You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ja...@apache.org on 2021/01/13 12:42:40 UTC

[camel-quarkus] branch master updated: Minio native support #2040

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

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


The following commit(s) were added to refs/heads/master by this push:
     new d17bf28  Minio native support #2040
d17bf28 is described below

commit d17bf28ceac30d2262d2178122677ac22fbfd84d
Author: JiriOndrusek <on...@gmail.com>
AuthorDate: Mon Jan 4 09:29:55 2021 +0100

    Minio native support #2040
---
 .../ROOT/pages/reference/extensions/minio.adoc     |  19 +-
 .../ROOT/partials/reference/components/minio.adoc  |   6 +-
 .../quarkus/component/minio/it/MinioResource.java  |  51 ------
 extensions-jvm/pom.xml                             |   1 -
 .../minio/deployment/pom.xml                       |   4 +
 .../component/minio/deployment/MinioProcessor.java |  16 --
 {extensions-jvm => extensions}/minio/pom.xml       |   1 -
 .../minio/runtime/pom.xml                          |  11 ++
 .../minio/runtime/src/main/doc/limitations.adoc    |   7 +
 .../main/resources/META-INF/quarkus-extension.yaml |   3 +-
 extensions/pom.xml                                 |   1 +
 .../minio}/pom.xml                                 |  49 ++++-
 .../component/minio/it/MinioConfigProvider.java    |  61 +++++++
 .../quarkus/component/minio/it/MinioResource.java  | 198 +++++++++++++++++++++
 ...se.microprofile.config.spi.ConfigSourceProvider |   1 +
 .../camel/quarkus/component/minio/it/MinioIT.java  |  16 +-
 .../quarkus/component/minio/it/MinioTest.java      | 175 ++++++++++++++++++
 .../component/minio/it/MinioTestResource.java      |  59 ++++++
 integration-tests/pom.xml                          |   1 +
 pom.xml                                            |   1 +
 poms/bom/pom.xml                                   |  10 ++
 tooling/scripts/test-categories.yaml               |   1 +
 22 files changed, 597 insertions(+), 95 deletions(-)

diff --git a/docs/modules/ROOT/pages/reference/extensions/minio.adoc b/docs/modules/ROOT/pages/reference/extensions/minio.adoc
index 15cc317..f49f0cc 100644
--- a/docs/modules/ROOT/pages/reference/extensions/minio.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/minio.adoc
@@ -2,15 +2,15 @@
 // This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
 = Minio
 :cq-artifact-id: camel-quarkus-minio
-:cq-native-supported: false
-:cq-status: Preview
+:cq-native-supported: true
+:cq-status: Stable
 :cq-description: Store and retrieve objects from Minio Storage Service using Minio SDK.
 :cq-deprecated: false
 :cq-jvm-since: 1.5.0
-:cq-native-since: n/a
+:cq-native-since: 1.6.0
 
 [.badges]
-[.badge-key]##JVM since##[.badge-supported]##1.5.0## [.badge-key]##Native##[.badge-unsupported]##unsupported##
+[.badge-key]##JVM since##[.badge-supported]##1.5.0## [.badge-key]##Native since##[.badge-supported]##1.6.0##
 
 Store and retrieve objects from Minio Storage Service using Minio SDK.
 
@@ -31,3 +31,14 @@ Please refer to the above link for usage and configuration details.
 ----
 
 Check the xref:user-guide/index.adoc[User guide] for more information about writing Camel Quarkus applications.
+
+== Camel Quarkus limitations
+
+This extension leverages the Quarkiverse Minio. Standard application.properties mechanism is used to define connection (see http://github.com/quarkiverse/quarkiverse-minio#configuration-reference[documentation]).
+
+It is mandatory to configure the Minio client in properties and Camel will autowire client into the Minio component.
+Configuration via application.properties allows definition of only one minio client, therefore it isn't possible to define several different minio endpoints, which run together.
+
+Please upvote https://github.com/quarkiverse/quarkiverse-minio/issues/22[this issue]
+if you do not like the present state.
+
diff --git a/docs/modules/ROOT/partials/reference/components/minio.adoc b/docs/modules/ROOT/partials/reference/components/minio.adoc
index ea8932b..159f4a1 100644
--- a/docs/modules/ROOT/partials/reference/components/minio.adoc
+++ b/docs/modules/ROOT/partials/reference/components/minio.adoc
@@ -2,11 +2,11 @@
 // This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
 :cq-artifact-id: camel-quarkus-minio
 :cq-artifact-id-base: minio
-:cq-native-supported: false
-:cq-status: Preview
+:cq-native-supported: true
+:cq-status: Stable
 :cq-deprecated: false
 :cq-jvm-since: 1.5.0
-:cq-native-since: n/a
+:cq-native-since: 1.6.0
 :cq-camel-part-name: minio
 :cq-camel-part-title: Minio
 :cq-camel-part-description: Store and retrieve objects from Minio Storage Service using Minio SDK.
diff --git a/extensions-jvm/minio/integration-test/src/main/java/org/apache/camel/quarkus/component/minio/it/MinioResource.java b/extensions-jvm/minio/integration-test/src/main/java/org/apache/camel/quarkus/component/minio/it/MinioResource.java
deleted file mode 100644
index ac98d5c..0000000
--- a/extensions-jvm/minio/integration-test/src/main/java/org/apache/camel/quarkus/component/minio/it/MinioResource.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.minio.it;
-
-import javax.enterprise.context.ApplicationScoped;
-import javax.inject.Inject;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.apache.camel.CamelContext;
-import org.jboss.logging.Logger;
-
-@Path("/minio")
-@ApplicationScoped
-public class MinioResource {
-
-    private static final Logger LOG = Logger.getLogger(MinioResource.class);
-
-    private static final String COMPONENT_MINIO = "minio";
-    @Inject
-    CamelContext context;
-
-    @Path("/load/component/minio")
-    @GET
-    @Produces(MediaType.TEXT_PLAIN)
-    public Response loadComponentMinio() throws Exception {
-        /* This is an autogenerated test */
-        if (context.getComponent(COMPONENT_MINIO) != null) {
-            return Response.ok().build();
-        }
-        LOG.warnf("Could not load [%s] from the Camel context", COMPONENT_MINIO);
-        return Response.status(500, COMPONENT_MINIO + " could not be loaded from the Camel context").build();
-    }
-}
diff --git a/extensions-jvm/pom.xml b/extensions-jvm/pom.xml
index bb4ec67..6057028 100644
--- a/extensions-jvm/pom.xml
+++ b/extensions-jvm/pom.xml
@@ -98,7 +98,6 @@
         <module>lucene</module>
         <module>management</module>
         <module>milo</module>
-        <module>minio</module>
         <module>mllp</module>
         <module>mvel</module>
         <module>mybatis</module>
diff --git a/extensions-jvm/minio/deployment/pom.xml b/extensions/minio/deployment/pom.xml
similarity index 94%
rename from extensions-jvm/minio/deployment/pom.xml
rename to extensions/minio/deployment/pom.xml
index f33961b..8d8b75f 100644
--- a/extensions-jvm/minio/deployment/pom.xml
+++ b/extensions/minio/deployment/pom.xml
@@ -40,6 +40,10 @@
             <groupId>org.apache.camel.quarkus</groupId>
             <artifactId>camel-quarkus-minio</artifactId>
         </dependency>
+        <dependency>
+            <groupId>io.quarkiverse.minio</groupId>
+            <artifactId>minio-client-deployment</artifactId>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/extensions-jvm/minio/deployment/src/main/java/org/apache/camel/quarkus/component/minio/deployment/MinioProcessor.java b/extensions/minio/deployment/src/main/java/org/apache/camel/quarkus/component/minio/deployment/MinioProcessor.java
similarity index 62%
rename from extensions-jvm/minio/deployment/src/main/java/org/apache/camel/quarkus/component/minio/deployment/MinioProcessor.java
rename to extensions/minio/deployment/src/main/java/org/apache/camel/quarkus/component/minio/deployment/MinioProcessor.java
index 4a05914..bf85ed8 100644
--- a/extensions-jvm/minio/deployment/src/main/java/org/apache/camel/quarkus/component/minio/deployment/MinioProcessor.java
+++ b/extensions/minio/deployment/src/main/java/org/apache/camel/quarkus/component/minio/deployment/MinioProcessor.java
@@ -17,30 +17,14 @@
 package org.apache.camel.quarkus.component.minio.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.NativeBuild;
-import org.apache.camel.quarkus.core.JvmOnlyRecorder;
-import org.jboss.logging.Logger;
 
 class MinioProcessor {
 
-    private static final Logger LOG = Logger.getLogger(MinioProcessor.class);
     private static final String FEATURE = "camel-minio";
 
     @BuildStep
     FeatureBuildItem feature() {
         return new FeatureBuildItem(FEATURE);
     }
-
-    /**
-     * Remove this once this extension starts supporting the native mode.
-     */
-    @BuildStep(onlyIf = NativeBuild.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/minio/pom.xml b/extensions/minio/pom.xml
similarity index 97%
rename from extensions-jvm/minio/pom.xml
rename to extensions/minio/pom.xml
index 46afd9d..4a06790 100644
--- a/extensions-jvm/minio/pom.xml
+++ b/extensions/minio/pom.xml
@@ -35,6 +35,5 @@
     <modules>
         <module>deployment</module>
         <module>runtime</module>
-        <module>integration-test</module>
     </modules>
 </project>
diff --git a/extensions-jvm/minio/runtime/pom.xml b/extensions/minio/runtime/pom.xml
similarity index 90%
rename from extensions-jvm/minio/runtime/pom.xml
rename to extensions/minio/runtime/pom.xml
index 98a6184..d21ae2b 100644
--- a/extensions-jvm/minio/runtime/pom.xml
+++ b/extensions/minio/runtime/pom.xml
@@ -34,6 +34,7 @@
 
     <properties>
         <camel.quarkus.jvmSince>1.5.0</camel.quarkus.jvmSince>
+        <camel.quarkus.nativeSince>1.6.0</camel.quarkus.nativeSince>
     </properties>
 
     <dependencyManagement>
@@ -57,6 +58,16 @@
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-minio</artifactId>
         </dependency>
+        <dependency>
+            <groupId>io.quarkiverse.minio</groupId>
+            <artifactId>minio-client</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>minio</artifactId>
+                    <groupId>io.minio</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/extensions/minio/runtime/src/main/doc/limitations.adoc b/extensions/minio/runtime/src/main/doc/limitations.adoc
new file mode 100644
index 0000000..bb494ad
--- /dev/null
+++ b/extensions/minio/runtime/src/main/doc/limitations.adoc
@@ -0,0 +1,7 @@
+This extension leverages the Quarkiverse Minio. Standard application.properties mechanism is used to define connection (see http://github.com/quarkiverse/quarkiverse-minio#configuration-reference[documentation]).
+
+It is mandatory to configure the Minio client in properties and Camel will autowire client into the Minio component.
+Configuration via application.properties allows definition of only one minio client, therefore it isn't possible to define several different minio endpoints, which run together.
+
+Please upvote https://github.com/quarkiverse/quarkiverse-minio/issues/22[this issue]
+if you do not like the present state.
\ No newline at end of file
diff --git a/extensions-jvm/minio/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/minio/runtime/src/main/resources/META-INF/quarkus-extension.yaml
similarity index 97%
rename from extensions-jvm/minio/runtime/src/main/resources/META-INF/quarkus-extension.yaml
rename to extensions/minio/runtime/src/main/resources/META-INF/quarkus-extension.yaml
index ac281da..6e51473 100644
--- a/extensions-jvm/minio/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ b/extensions/minio/runtime/src/main/resources/META-INF/quarkus-extension.yaml
@@ -24,9 +24,8 @@
 name: "Camel Minio"
 description: "Store and retrieve objects from Minio Storage Service using Minio SDK"
 metadata:
-  unlisted: true
   guide: "https://camel.apache.org/camel-quarkus/latest/reference/extensions/minio.html"
   categories:
   - "integration"
   status:
-  - "preview"
+  - "stable"
diff --git a/extensions/pom.xml b/extensions/pom.xml
index 728fcf0..e59472c 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -159,6 +159,7 @@
         <module>microprofile-fault-tolerance</module>
         <module>microprofile-health</module>
         <module>microprofile-metrics</module>
+        <module>minio</module>
         <module>mock</module>
         <module>mongodb</module>
         <module>mongodb-gridfs</module>
diff --git a/extensions-jvm/minio/integration-test/pom.xml b/integration-tests/minio/pom.xml
similarity index 65%
rename from extensions-jvm/minio/integration-test/pom.xml
rename to integration-tests/minio/pom.xml
index 758cc0f..237e522 100644
--- a/extensions-jvm/minio/integration-test/pom.xml
+++ b/integration-tests/minio/pom.xml
@@ -23,13 +23,13 @@
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.apache.camel.quarkus</groupId>
-        <artifactId>camel-quarkus-build-parent-it</artifactId>
+        <artifactId>camel-quarkus-integration-tests</artifactId>
         <version>1.6.0-SNAPSHOT</version>
-        <relativePath>../../../poms/build-parent-it/pom.xml</relativePath>
+        <relativePath>../pom.xml</relativePath>
     </parent>
 
-    <artifactId>camel-quarkus-minio-integration-test</artifactId>
-    <name>Camel Quarkus :: Minio :: Integration Test</name>
+    <artifactId>camel-quarkus-integration-test-minio</artifactId>
+    <name>Camel Quarkus :: Integration Tests :: Minio</name>
     <description>Integration tests for Camel Quarkus Minio extension</description>
 
     <dependencyManagement>
@@ -65,6 +65,16 @@
             <artifactId>rest-assured</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-integration-testcontainers-support</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.awaitility</groupId>
+            <artifactId>awaitility</artifactId>
+            <scope>test</scope>
+        </dependency>
 
         <!-- The following dependencies guarantee that this module is built after them. You can update them by running `mvn process-resources -Pformat -N` from the source tree root directory -->
         <dependency>
@@ -81,4 +91,35 @@
             </exclusions>
         </dependency>
     </dependencies>
+
+    <profiles>
+        <profile>
+            <id>native</id>
+            <activation>
+                <property>
+                    <name>native</name>
+                </property>
+            </activation>
+            <properties>
+                <quarkus.package.type>native</quarkus.package.type>
+            </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>
+    </profiles>
+
 </project>
diff --git a/integration-tests/minio/src/main/java/org/apache/camel/quarkus/component/minio/it/MinioConfigProvider.java b/integration-tests/minio/src/main/java/org/apache/camel/quarkus/component/minio/it/MinioConfigProvider.java
new file mode 100644
index 0000000..809a7d4
--- /dev/null
+++ b/integration-tests/minio/src/main/java/org/apache/camel/quarkus/component/minio/it/MinioConfigProvider.java
@@ -0,0 +1,61 @@
+/*
+ * 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.minio.it;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.microprofile.config.spi.ConfigSource;
+import org.eclipse.microprofile.config.spi.ConfigSourceProvider;
+
+public class MinioConfigProvider implements ConfigSourceProvider {
+
+    private final MinioConfig minioConfig = new MinioConfig();
+
+    @Override
+    public Iterable<ConfigSource> getConfigSources(ClassLoader forClassLoader) {
+        return Collections.singletonList(minioConfig);
+    }
+
+    private static final class MinioConfig implements ConfigSource {
+
+        private final Map<String, String> values = new HashMap<String, String>() {
+            {
+                put("quarkus.minio.url", String.format("http://%s:%s", System.getProperty(MinioResource.PARAM_SERVER_HOST),
+                        System.getProperty(MinioResource.PARAM_SERVER_PORT)));
+                put("quarkus.minio.access-key", MinioResource.SERVER_ACCESS_KEY);
+                put("quarkus.minio.secret-key", MinioResource.SERVER_SECRET_KEY);
+            }
+        };
+
+        @Override
+        public Map<String, String> getProperties() {
+            return values;
+        }
+
+        @Override
+        public String getValue(String propertyName) {
+            return values.get(propertyName);
+        }
+
+        @Override
+        public String getName() {
+            return MinioConfig.class.getName();
+        }
+    }
+}
diff --git a/integration-tests/minio/src/main/java/org/apache/camel/quarkus/component/minio/it/MinioResource.java b/integration-tests/minio/src/main/java/org/apache/camel/quarkus/component/minio/it/MinioResource.java
new file mode 100644
index 0000000..7fb7d5c
--- /dev/null
+++ b/integration-tests/minio/src/main/java/org/apache/camel/quarkus/component/minio/it/MinioResource.java
@@ -0,0 +1,198 @@
+/*
+ * 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.minio.it;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.GeneralSecurityException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+
+import io.minio.BucketExistsArgs;
+import io.minio.GetObjectArgs;
+import io.minio.MakeBucketArgs;
+import io.minio.MinioClient;
+import io.minio.PutObjectArgs;
+import io.minio.Result;
+import io.minio.errors.MinioException;
+import io.minio.messages.Bucket;
+import io.minio.messages.Item;
+import org.apache.camel.ConsumerTemplate;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.component.minio.MinioConstants;
+import org.apache.camel.component.minio.MinioOperations;
+
+@Path("/minio")
+@ApplicationScoped
+public class MinioResource {
+    private static final long PART_SIZE = 50 * 1024 * 1024;
+
+    public static final String SERVER_ACCESS_KEY = "testAccessKey";
+    public static final String SERVER_SECRET_KEY = "testSecretKey";
+    public static final String PARAM_SERVER_HOST = MinioResource.class.getSimpleName() + "_serverHost";
+    public static final String PARAM_SERVER_PORT = MinioResource.class.getSimpleName() + "_serverPort";
+
+    @Inject
+    ProducerTemplate producerTemplate;
+
+    @Inject
+    ConsumerTemplate consumerTemplate;
+
+    @Inject
+    MinioClient minioClient;
+
+    @Path("/consumer")
+    @GET
+    @Produces(MediaType.TEXT_PLAIN)
+    public String consumer() {
+
+        String serverUrl = "http://" + System.getProperty(PARAM_SERVER_HOST) + ":" + System.getProperty(PARAM_SERVER_PORT);
+
+        final String message = consumerTemplate.receiveBody(
+                "minio://mycamel?moveAfterRead=true&destinationBucketName=camel-kafka-connector&autoCreateBucket=true"
+                        + "&accessKey=" + SERVER_ACCESS_KEY
+                        + "&secretKey=RAW(" + SERVER_SECRET_KEY + ")"
+                        + "&endpoint=" + serverUrl
+                        + "&secure=true",
+                5000, String.class);
+        return message;
+    }
+
+    @Path("/operation")
+    @POST
+    @Produces(MediaType.TEXT_PLAIN)
+    @Consumes(MediaType.TEXT_PLAIN)
+    public String operation(String body,
+            @QueryParam(MinioConstants.MINIO_OPERATION) String operation,
+            @QueryParam(MinioConstants.OBJECT_NAME) String objectName,
+            @QueryParam(MinioConstants.DESTINATION_OBJECT_NAME) String destinationObjectName,
+            @QueryParam(MinioConstants.DESTINATION_BUCKET_NAME) String destinationBucketName) {
+
+        String serverUrl = "http://" + System.getProperty(PARAM_SERVER_HOST) + ":" + System.getProperty(PARAM_SERVER_PORT);
+        String endpoint = "minio:mycamel?accessKey=" + SERVER_ACCESS_KEY
+                + "&secretKey=RAW(" + SERVER_SECRET_KEY + ")"
+                + "&endpoint=" + serverUrl;
+
+        MinioOperations op = (operation != "" && !"".equals(operation) ? MinioOperations.valueOf(operation) : null);
+
+        Map<String, Object> headers = new HashMap<>();
+        if (op != null) {
+            headers.put(MinioConstants.MINIO_OPERATION, op);
+        }
+        if (objectName != null) {
+            headers.put(MinioConstants.OBJECT_NAME, objectName);
+        }
+        if (destinationObjectName != null) {
+            headers.put(MinioConstants.DESTINATION_OBJECT_NAME, destinationObjectName);
+        }
+        if (destinationBucketName != null) {
+            headers.put(MinioConstants.DESTINATION_BUCKET_NAME, destinationBucketName);
+        }
+
+        if (op == MinioOperations.getObject) {
+            return producerTemplate.requestBodyAndHeaders(endpoint, body, headers, String.class);
+        }
+
+        final Iterable objectList = producerTemplate.requestBodyAndHeaders(endpoint, body, headers, Iterable.class);
+        StringBuilder sb = new StringBuilder();
+        StringBuilder errorSB = new StringBuilder();
+        objectList.forEach(r -> {
+            try {
+                if (r instanceof Result) {
+                    Object o = ((Result) r).get();
+                    if (o instanceof Item) {
+                        sb.append("item: ").append(((Item) o).objectName());
+                    } else {
+                        sb.append(o);
+                    }
+                }
+                if (r instanceof Bucket) {
+                    sb.append("bucket: ").append(((Bucket) r).name());
+                } else {
+                    sb.append(r);
+                }
+                sb.append(", ");
+            } catch (Exception e) {
+                errorSB.append(e.toString());
+            }
+        });
+        return errorSB.length() > 0 ? errorSB.toString() : sb.toString();
+    }
+
+    @Path("/getUsingPojo")
+    @POST
+    @Produces(MediaType.TEXT_PLAIN)
+    @Consumes(MediaType.TEXT_PLAIN)
+    public String getUsingPojo(String bucket,
+            @QueryParam(MinioConstants.OBJECT_NAME) String objectName) {
+
+        String serverUrl = "http://" + System.getProperty(PARAM_SERVER_HOST) + ":" + System.getProperty(PARAM_SERVER_PORT);
+        String endpoint = "minio:mycamel?accessKey=" + SERVER_ACCESS_KEY
+                + "&secretKey=RAW(" + SERVER_SECRET_KEY + ")"
+                + "&endpoint=" + serverUrl
+                + "&pojoRequest=true";
+
+        GetObjectArgs.Builder body = GetObjectArgs.builder()
+                .bucket(bucket)
+                .object(objectName);
+
+        Map<String, Object> headers = Collections.singletonMap(MinioConstants.MINIO_OPERATION, MinioOperations.getObject);
+
+        return producerTemplate.requestBodyAndHeaders(endpoint, body, headers, String.class);
+
+    }
+
+    @Path("/initBucket")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    public void initBucket(String bucketName) throws Exception {
+        if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
+            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
+        }
+    }
+
+    @Path("/putObject")
+    @POST
+    @Produces(MediaType.TEXT_PLAIN)
+    public void putObject(String content,
+            @QueryParam(MinioConstants.OBJECT_NAME) String objectName,
+            @QueryParam(MinioConstants.BUCKET_NAME) String bucketName) throws Exception {
+        try (InputStream is = new ByteArrayInputStream((content.getBytes()))) {
+            minioClient.putObject(
+                    PutObjectArgs.builder()
+                            .bucket(bucketName)
+                            .object(objectName)
+                            .contentType("text/xml")
+                            .stream(is, -1, PART_SIZE)
+                            .build());
+        } catch (MinioException | GeneralSecurityException | IOException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+}
diff --git a/integration-tests/minio/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSourceProvider b/integration-tests/minio/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSourceProvider
new file mode 100644
index 0000000..e961080
--- /dev/null
+++ b/integration-tests/minio/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSourceProvider
@@ -0,0 +1 @@
+org.apache.camel.quarkus.component.minio.it.MinioConfigProvider
\ No newline at end of file
diff --git a/extensions-jvm/minio/integration-test/src/test/java/org/apache/camel/quarkus/component/minio/it/MinioTest.java b/integration-tests/minio/src/test/java/org/apache/camel/quarkus/component/minio/it/MinioIT.java
similarity index 70%
rename from extensions-jvm/minio/integration-test/src/test/java/org/apache/camel/quarkus/component/minio/it/MinioTest.java
rename to integration-tests/minio/src/test/java/org/apache/camel/quarkus/component/minio/it/MinioIT.java
index 720a83d..f5d78ca 100644
--- a/extensions-jvm/minio/integration-test/src/test/java/org/apache/camel/quarkus/component/minio/it/MinioTest.java
+++ b/integration-tests/minio/src/test/java/org/apache/camel/quarkus/component/minio/it/MinioIT.java
@@ -16,19 +16,9 @@
  */
 package org.apache.camel.quarkus.component.minio.it;
 
-import io.quarkus.test.junit.QuarkusTest;
-import io.restassured.RestAssured;
-import org.junit.jupiter.api.Test;
+import io.quarkus.test.junit.NativeImageTest;
 
-@QuarkusTest
-class MinioTest {
-
-    @Test
-    public void loadComponentMinio() {
-        /* A simple autogenerated test */
-        RestAssured.get("/minio/load/component/minio")
-                .then()
-                .statusCode(200);
-    }
+@NativeImageTest
+class MinioIT extends MinioTest {
 
 }
diff --git a/integration-tests/minio/src/test/java/org/apache/camel/quarkus/component/minio/it/MinioTest.java b/integration-tests/minio/src/test/java/org/apache/camel/quarkus/component/minio/it/MinioTest.java
new file mode 100644
index 0000000..3b53bb0
--- /dev/null
+++ b/integration-tests/minio/src/test/java/org/apache/camel/quarkus/component/minio/it/MinioTest.java
@@ -0,0 +1,175 @@
+/*
+ * 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.minio.it;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import io.quarkus.test.common.QuarkusTestResource;
+import io.quarkus.test.junit.QuarkusTest;
+import io.restassured.RestAssured;
+import io.restassured.http.ContentType;
+import io.restassured.response.ValidatableResponse;
+import io.restassured.specification.RequestSpecification;
+import org.apache.camel.component.minio.MinioConstants;
+import org.apache.camel.component.minio.MinioOperations;
+import org.apache.camel.util.CollectionHelper;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import static org.awaitility.Awaitility.await;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
+
+@QuarkusTest
+@QuarkusTestResource(MinioTestResource.class)
+class MinioTest {
+
+    private final String BUCKET_NAME = "mycamel";
+
+    @Test
+    public void testConsumer() throws Exception {
+        initClient();
+
+        sendViaClient("Dummy content", "consumerObject");
+
+        //wait for the result from the server
+        await().atMost(10L, TimeUnit.SECONDS).untilAsserted(() -> {
+            String result = RestAssured.get("/minio/consumer")
+                    .then()
+                    .extract().asString();
+            Assertions.assertEquals("Dummy content", result);
+        });
+    }
+
+    @Test
+    public void testDeleteObject() throws Exception {
+        initClient();
+
+        sendViaClient("Dummy content", "testDeleteObject");
+
+        producerRequest(MinioOperations.listObjects, null, Collections.emptyMap())
+                .statusCode(200)
+                .body(containsString("item: testDeleteObject"));
+
+        producerRequest(MinioOperations.deleteObject, null,
+                Collections.singletonMap(MinioConstants.OBJECT_NAME, "testDeleteObject"))
+                        .statusCode(200)
+                        .body(containsString("true"));
+
+        producerRequest(MinioOperations.listObjects, null, Collections.emptyMap())
+                .statusCode(200)
+                .body(equalTo(""));
+    }
+
+    @Test
+    public void testDeleteBucket() throws Exception {
+        initClient();
+
+        producerRequest(MinioOperations.listBuckets, null, Collections.emptyMap())
+                .statusCode(200)
+                .body(containsString("bucket: " + BUCKET_NAME));
+
+        producerRequest(MinioOperations.deleteBucket, null, Collections.emptyMap())
+                .statusCode(200);
+
+        producerRequest(MinioOperations.listBuckets, null, Collections.emptyMap())
+                .statusCode(200)
+                .body(equalTo(""));
+    }
+
+    @Test
+    public void testBasicOperations() throws Exception {
+        initClient();
+
+        producerRequest(null, "Hi Sheldon.", Collections.singletonMap(MinioConstants.OBJECT_NAME, "putName"))
+                .statusCode(200)
+                .body(containsString("Hi Sheldon"));
+
+        producerRequest(MinioOperations.copyObject, null, CollectionHelper.mapOf(MinioConstants.OBJECT_NAME, "putName",
+                MinioConstants.DESTINATION_OBJECT_NAME, "copyName",
+                MinioConstants.DESTINATION_BUCKET_NAME, BUCKET_NAME))
+                        .statusCode(200);
+
+        producerRequest(MinioOperations.getObject, null, Collections.singletonMap(MinioConstants.OBJECT_NAME, "copyName"))
+                .statusCode(200)
+                .body(containsString("Hi Sheldon"));
+    }
+
+    @Test
+    public void testGetViaPojo() throws Exception {
+        initClient();
+        initClient(BUCKET_NAME + "2");
+
+        producerRequest(null, "Hi Sheldon.", Collections.singletonMap(MinioConstants.OBJECT_NAME, "putViaPojoName"))
+                .statusCode(200)
+                .body(containsString("Hi Sheldon"));
+
+        producerRequest(MinioOperations.copyObject, null, CollectionHelper.mapOf(MinioConstants.OBJECT_NAME, "putViaPojoName",
+                MinioConstants.DESTINATION_OBJECT_NAME, "copyViaPojoName",
+                MinioConstants.DESTINATION_BUCKET_NAME, BUCKET_NAME + "2"))
+                        .statusCode(200);
+
+        producerRequest(MinioOperations.getObject, BUCKET_NAME + "2",
+                Collections.singletonMap(MinioConstants.OBJECT_NAME, "copyViaPojoName"),
+                "/minio/getUsingPojo")
+                        .statusCode(200)
+                        .body(containsString("Hi Sheldon"));
+    }
+
+    private ValidatableResponse producerRequest(MinioOperations operation, String body, Map<String, String> params) {
+        return producerRequest(operation, body, params, "/minio/operation");
+    }
+
+    private ValidatableResponse producerRequest(MinioOperations operation, String body, Map<String, String> params,
+            String path) {
+        RequestSpecification request = RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .queryParam(MinioConstants.MINIO_OPERATION, operation != null ? operation.name() : null);
+
+        params.forEach((k, v) -> request.queryParam(k, v));
+
+        return request.body(body == null ? "" : body)
+                .post(path)
+                .then();
+    }
+
+    private void initClient() throws Exception {
+        initClient(BUCKET_NAME);
+    }
+
+    private void initClient(String bucketName) throws Exception {
+        RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .body(bucketName)
+                .post("/minio/initBucket")
+                .then()
+                .statusCode(204);
+    }
+
+    private void sendViaClient(String content, String objectName) {
+        RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .queryParam(MinioConstants.OBJECT_NAME, objectName)
+                .queryParam(MinioConstants.BUCKET_NAME, BUCKET_NAME)
+                .body(content)
+                .post("/minio/putObject")
+                .then()
+                .statusCode(204);
+    }
+}
diff --git a/integration-tests/minio/src/test/java/org/apache/camel/quarkus/component/minio/it/MinioTestResource.java b/integration-tests/minio/src/test/java/org/apache/camel/quarkus/component/minio/it/MinioTestResource.java
new file mode 100644
index 0000000..e5fd6a7
--- /dev/null
+++ b/integration-tests/minio/src/test/java/org/apache/camel/quarkus/component/minio/it/MinioTestResource.java
@@ -0,0 +1,59 @@
+/*
+ * 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.minio.it;
+
+import java.time.Duration;
+import java.util.Map;
+
+import org.apache.camel.quarkus.testcontainers.ContainerResourceLifecycleManager;
+import org.apache.camel.util.CollectionHelper;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.wait.strategy.HttpWaitStrategy;
+
+public class MinioTestResource implements ContainerResourceLifecycleManager {
+
+    public static final String CONTAINER_ACCESS_KEY = "MINIO_ACCESS_KEY";
+    public static final String CONTAINER_SECRET_KEY = "MINIO_SECRET_KEY";
+    private final String CONTAINER_IMAGE = "minio/minio:RELEASE.2020-12-03T05-49-24Z";
+    private final int BROKER_PORT = 9000;
+
+    private GenericContainer minioServer = new GenericContainer(CONTAINER_IMAGE)
+            .withEnv(CONTAINER_ACCESS_KEY, MinioResource.SERVER_ACCESS_KEY)
+            .withEnv(CONTAINER_SECRET_KEY, MinioResource.SERVER_SECRET_KEY)
+            .withCommand("server /data")
+            .withExposedPorts(BROKER_PORT)
+            .waitingFor(new HttpWaitStrategy()
+                    .forPath("/minio/health/ready")
+                    .forPort(BROKER_PORT)
+                    .withStartupTimeout(Duration.ofSeconds(10)));
+
+    @Override
+    public Map<String, String> start() {
+        minioServer.start();
+
+        return CollectionHelper.mapOf(
+                MinioResource.PARAM_SERVER_PORT, minioServer.getMappedPort(BROKER_PORT) + "",
+                MinioResource.PARAM_SERVER_HOST, minioServer.getHost());
+    }
+
+    @Override
+    public void stop() {
+        if (minioServer.isRunning()) {
+            minioServer.stop();
+        }
+    }
+}
diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
index f838567..b9bc7ce 100644
--- a/integration-tests/pom.xml
+++ b/integration-tests/pom.xml
@@ -134,6 +134,7 @@
         <module>messaging</module>
         <module>micrometer</module>
         <module>microprofile</module>
+        <module>minio</module>
         <module>mongodb</module>
         <module>msv</module>
         <module>mustache</module>
diff --git a/pom.xml b/pom.xml
index 1f33bbc..d060f1b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -91,6 +91,7 @@
         <okhttp.version>${squareup-okhttp-version}</okhttp.version><!-- keep in sync with okio -->
         <okio.version>${squareup-okio-version}</okio.version><!-- keep in sync with okhttp -->
         <optaplanner.version>7.46.0.Final</optaplanner.version>
+        <quarkiverse-minio.version>0.2.0</quarkiverse-minio.version>
         <quarkus.version>1.11.0.CR1</quarkus.version>
         <quarkus-google-cloud.version>0.3.0</quarkus-google-cloud.version>
         <quarkus-hazelcast-client.version>1.1.1</quarkus-hazelcast-client.version>
diff --git a/poms/bom/pom.xml b/poms/bom/pom.xml
index b1059a5..29a275f 100644
--- a/poms/bom/pom.xml
+++ b/poms/bom/pom.xml
@@ -5644,6 +5644,16 @@
                 <version>${quarkus-google-cloud.version}</version>
             </dependency>
             <dependency>
+                <groupId>io.quarkiverse.minio</groupId>
+                <artifactId>minio-client</artifactId>
+                <version>${quarkiverse-minio.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>io.quarkiverse.minio</groupId>
+                <artifactId>minio-client-deployment</artifactId>
+                <version>${quarkiverse-minio.version}</version>
+            </dependency>
+            <dependency>
                 <groupId>io.smallrye.reactive</groupId>
                 <artifactId>smallrye-reactive-messaging-camel</artifactId>
                 <version>${smallrye.reactive.messaging.camel.version}</version>
diff --git a/tooling/scripts/test-categories.yaml b/tooling/scripts/test-categories.yaml
index e71637d..9863dc9 100644
--- a/tooling/scripts/test-categories.yaml
+++ b/tooling/scripts/test-categories.yaml
@@ -60,6 +60,7 @@ database:
   - jpa
   - kudu
   - leveldb
+  - minio
   - mongodb
   - pgevent
   - pg-replication-slot