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 e0721f2955 Add tests and native support for milvus extension
e0721f2955 is described below
commit e0721f29558286be4766b0e051b1627dce621e88
Author: souvik ghosh <[email protected]>
AuthorDate: Thu Mar 5 20:42:49 2026 +0530
Add tests and native support for milvus extension
Fixes #6025
* Add tests and native support for milvus extension
* Move to quarkus-grpc-common to remove unnecessary stuff
---------
Co-authored-by: Souvik Ghosh <[email protected]>
---
docs/modules/ROOT/examples/components/milvus.yml | 6 +-
.../ROOT/pages/reference/extensions/milvus.adoc | 14 +-
.../milvus/deployment/MilvusProcessor.java | 30 ---
extensions-jvm/pom.xml | 1 -
.../milvus/deployment/pom.xml | 4 +
.../milvus/deployment/MilvusProcessor.java | 86 ++++++++
{extensions-jvm => extensions}/milvus/pom.xml | 2 +-
.../milvus/runtime/pom.xml | 5 +
.../main/resources/META-INF/quarkus-extension.yaml | 1 -
extensions/pom.xml | 1 +
.../component/milvus/it/MilvusResource.java | 50 -----
integration-tests-jvm/pom.xml | 1 -
.../milvus/pom.xml | 37 ++++
.../component/milvus/it/MilvusResource.java | 229 +++++++++++++++++++++
.../quarkus/component/milvus/it/MilvusRoutes.java | 21 +-
.../quarkus/component/milvus/it/MilvusIT.java | 0
.../quarkus/component/milvus/it/MilvusTest.java | 97 +++++++++
.../component/milvus/it/MilvusTestResource.java | 59 ++++++
integration-tests/pom.xml | 1 +
pom.xml | 1 +
tooling/scripts/test-categories.yaml | 2 +
21 files changed, 544 insertions(+), 104 deletions(-)
diff --git a/docs/modules/ROOT/examples/components/milvus.yml
b/docs/modules/ROOT/examples/components/milvus.yml
index bd1e122c7b..ed4593cde2 100644
--- a/docs/modules/ROOT/examples/components/milvus.yml
+++ b/docs/modules/ROOT/examples/components/milvus.yml
@@ -2,11 +2,11 @@
# This file was generated by
camel-quarkus-maven-plugin:update-extension-doc-page
cqArtifactId: camel-quarkus-milvus
cqArtifactIdBase: milvus
-cqNativeSupported: false
-cqStatus: Preview
+cqNativeSupported: true
+cqStatus: Stable
cqDeprecated: false
cqJvmSince: 3.10.0
-cqNativeSince: n/a
+cqNativeSince: 3.33.0
cqCamelPartName: milvus
cqCamelPartTitle: Milvus
cqCamelPartDescription: Perform operations on the Milvus Vector Database.
diff --git a/docs/modules/ROOT/pages/reference/extensions/milvus.adoc
b/docs/modules/ROOT/pages/reference/extensions/milvus.adoc
index 0518929a86..c4d3ed4037 100644
--- a/docs/modules/ROOT/pages/reference/extensions/milvus.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/milvus.adoc
@@ -4,17 +4,17 @@
= Milvus
:linkattrs:
:cq-artifact-id: camel-quarkus-milvus
-:cq-native-supported: false
-:cq-status: Preview
-:cq-status-deprecation: Preview
+:cq-native-supported: true
+:cq-status: Stable
+:cq-status-deprecation: Stable
:cq-description: Perform operations on the Milvus Vector Database.
:cq-deprecated: false
:cq-jvm-since: 3.10.0
-:cq-native-since: n/a
+:cq-native-since: 3.33.0
ifeval::[{doc-show-badges} == true]
[.badges]
-[.badge-key]##JVM since##[.badge-supported]##3.10.0##
[.badge-key]##Native##[.badge-unsupported]##unsupported##
+[.badge-key]##JVM since##[.badge-supported]##3.10.0## [.badge-key]##Native
since##[.badge-supported]##3.33.0##
endif::[]
Perform operations on the Milvus Vector Database.
@@ -29,6 +29,10 @@ Please refer to the above link for usage and configuration
details.
[id="extensions-milvus-maven-coordinates"]
== Maven coordinates
+https://{link-quarkus-code-generator}/?extension-search=camel-quarkus-milvus[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/milvus/deployment/src/main/java/org/apache/camel/quarkus/component/milvus/deployment/MilvusProcessor.java
b/extensions-jvm/milvus/deployment/src/main/java/org/apache/camel/quarkus/component/milvus/deployment/MilvusProcessor.java
deleted file mode 100644
index ead9a83461..0000000000
---
a/extensions-jvm/milvus/deployment/src/main/java/org/apache/camel/quarkus/component/milvus/deployment/MilvusProcessor.java
+++ /dev/null
@@ -1,30 +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.milvus.deployment;
-
-import io.quarkus.deployment.annotations.BuildStep;
-import io.quarkus.deployment.builditem.FeatureBuildItem;
-
-class MilvusProcessor {
-
- private static final String FEATURE = "camel-milvus";
-
- @BuildStep
- FeatureBuildItem feature() {
- return new FeatureBuildItem(FEATURE);
- }
-}
diff --git a/extensions-jvm/pom.xml b/extensions-jvm/pom.xml
index 46c7236e4a..c57002cfa9 100644
--- a/extensions-jvm/pom.xml
+++ b/extensions-jvm/pom.xml
@@ -78,7 +78,6 @@
<module>jsonapi</module>
<module>ldif</module>
<module>lucene</module>
- <module>milvus</module>
<module>mina-sftp</module>
<module>mvel</module>
<module>opensearch</module>
diff --git a/extensions-jvm/milvus/deployment/pom.xml
b/extensions/milvus/deployment/pom.xml
similarity index 94%
rename from extensions-jvm/milvus/deployment/pom.xml
rename to extensions/milvus/deployment/pom.xml
index b52dd20b7d..d0093a69c4 100644
--- a/extensions-jvm/milvus/deployment/pom.xml
+++ b/extensions/milvus/deployment/pom.xml
@@ -34,6 +34,10 @@
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-core-deployment</artifactId>
</dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-grpc-common-deployment</artifactId>
+ </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-milvus</artifactId>
diff --git
a/extensions/milvus/deployment/src/main/java/org/apache/camel/quarkus/component/milvus/deployment/MilvusProcessor.java
b/extensions/milvus/deployment/src/main/java/org/apache/camel/quarkus/component/milvus/deployment/MilvusProcessor.java
new file mode 100644
index 0000000000..5357ff425f
--- /dev/null
+++
b/extensions/milvus/deployment/src/main/java/org/apache/camel/quarkus/component/milvus/deployment/MilvusProcessor.java
@@ -0,0 +1,86 @@
+/*
+ * 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.milvus.deployment;
+
+import io.quarkus.deployment.annotations.BuildProducer;
+import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.builditem.BytecodeTransformerBuildItem;
+import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
+import io.quarkus.deployment.builditem.IndexDependencyBuildItem;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.commons.ClassRemapper;
+import org.objectweb.asm.commons.Remapper;
+
+class MilvusProcessor {
+
+ /**
+ * Intercepts all Milvus SDK classes during the Quarkus build process to
perform
+ * bytecode transformation. This ensures the SDK points to the correct
+ * gRPC/Netty implementations, avoiding 'Class Not Found'
+ */
+
+ @BuildStep
+ void relocateAllShadedCalls(
+ CombinedIndexBuildItem index,
+ BuildProducer<BytecodeTransformerBuildItem> transformers) {
+
+ index.getIndex().getKnownClasses().stream()
+ .filter(ci -> {
+ String name = ci.name().toString();
+ return name.startsWith("io.milvus");
+ })
+ .forEach(ci -> {
+ transformers.produce(new BytecodeTransformerBuildItem(
+ ci.name().toString(),
+ (name, cv) -> new ShadedRelocationVisitor(cv)));
+ });
+ }
+
+ //This build step ensures that the Milvus Java SDK is indexed by Jandex.
+
+ @BuildStep
+ IndexDependencyBuildItem indexDependencie() {
+ return new IndexDependencyBuildItem("io.milvus", "milvus-sdk-java");
+ }
+
+ /**
+ * Custom ClassRemapper used during the Quarkus build step to intercept and
+ * redirect shaded Netty/gRPC calls within the Milvus SDK.
+ */
+
+ private static class ShadedRelocationVisitor extends ClassRemapper {
+ public ShadedRelocationVisitor(ClassVisitor cv) {
+ super(Opcodes.ASM9, cv, new Remapper(Opcodes.ASM9) {
+ @Override
+ public String map(String internalName) {
+ if (internalName == null)
+ return null;
+
+ if
(internalName.startsWith("io/grpc/netty/shaded/io/grpc")) {
+ return
internalName.replace("io/grpc/netty/shaded/io/grpc", "io/grpc");
+ }
+ if
(internalName.startsWith("io/grpc/netty/shaded/io/netty")) {
+ return
internalName.replace("io/grpc/netty/shaded/io/netty", "io/netty");
+ }
+ return super.map(internalName);
+ }
+ });
+ }
+ }
+
+}
diff --git a/extensions-jvm/milvus/pom.xml b/extensions/milvus/pom.xml
similarity index 96%
rename from extensions-jvm/milvus/pom.xml
rename to extensions/milvus/pom.xml
index 90e89e4209..0a4054708b 100644
--- a/extensions-jvm/milvus/pom.xml
+++ b/extensions/milvus/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.33.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
diff --git a/extensions-jvm/milvus/runtime/pom.xml
b/extensions/milvus/runtime/pom.xml
similarity index 92%
rename from extensions-jvm/milvus/runtime/pom.xml
rename to extensions/milvus/runtime/pom.xml
index dd395337af..7de727ce66 100644
--- a/extensions-jvm/milvus/runtime/pom.xml
+++ b/extensions/milvus/runtime/pom.xml
@@ -32,6 +32,7 @@
<properties>
<camel.quarkus.jvmSince>3.10.0</camel.quarkus.jvmSince>
+ <camel.quarkus.nativeSince>3.33.0</camel.quarkus.nativeSince>
</properties>
<dependencies>
@@ -39,6 +40,10 @@
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-core</artifactId>
</dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-grpc-common</artifactId>
+ </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-milvus</artifactId>
diff --git
a/extensions-jvm/milvus/runtime/src/main/resources/META-INF/quarkus-extension.yaml
b/extensions/milvus/runtime/src/main/resources/META-INF/quarkus-extension.yaml
similarity index 98%
rename from
extensions-jvm/milvus/runtime/src/main/resources/META-INF/quarkus-extension.yaml
rename to
extensions/milvus/runtime/src/main/resources/META-INF/quarkus-extension.yaml
index a67a8d0684..800261188b 100644
---
a/extensions-jvm/milvus/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++
b/extensions/milvus/runtime/src/main/resources/META-INF/quarkus-extension.yaml
@@ -26,7 +26,6 @@ description: "Perform operations on the Milvus Vector
Database"
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/milvus.html"
categories:
- "integration"
diff --git a/extensions/pom.xml b/extensions/pom.xml
index 4d9f8d1abb..f3cbaa1c50 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -203,6 +203,7 @@
<module>microprofile-fault-tolerance</module>
<module>microprofile-health</module>
<module>milo</module>
+ <module>milvus</module>
<module>minio</module>
<module>mllp</module>
<module>mock</module>
diff --git
a/integration-tests-jvm/milvus/src/main/java/org/apache/camel/quarkus/component/milvus/it/MilvusResource.java
b/integration-tests-jvm/milvus/src/main/java/org/apache/camel/quarkus/component/milvus/it/MilvusResource.java
deleted file mode 100644
index 1fa0d1526d..0000000000
---
a/integration-tests-jvm/milvus/src/main/java/org/apache/camel/quarkus/component/milvus/it/MilvusResource.java
+++ /dev/null
@@ -1,50 +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.milvus.it;
-
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.inject.Inject;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Response;
-import org.apache.camel.CamelContext;
-import org.jboss.logging.Logger;
-
-@Path("/milvus")
-@ApplicationScoped
-public class MilvusResource {
-
- private static final Logger LOG = Logger.getLogger(MilvusResource.class);
-
- private static final String COMPONENT_MILVUS = "milvus";
- @Inject
- CamelContext context;
-
- @Path("/load/component/milvus")
- @GET
- @Produces(MediaType.TEXT_PLAIN)
- public Response loadComponentMilvus() throws Exception {
- /* This is an autogenerated test */
- if (context.getComponent(COMPONENT_MILVUS) != null) {
- return Response.ok().build();
- }
- LOG.warnf("Could not load [%s] from the Camel context",
COMPONENT_MILVUS);
- return Response.status(500, COMPONENT_MILVUS + " could not be loaded
from the Camel context").build();
- }
-}
diff --git a/integration-tests-jvm/pom.xml b/integration-tests-jvm/pom.xml
index 7d05bd84ba..29bc8fba07 100644
--- a/integration-tests-jvm/pom.xml
+++ b/integration-tests-jvm/pom.xml
@@ -79,7 +79,6 @@
<module>ldif</module>
<module>lucene</module>
<module>main-devmode</module>
- <module>milvus</module>
<module>mina-sftp</module>
<module>mvel</module>
<module>opensearch</module>
diff --git a/integration-tests-jvm/milvus/pom.xml
b/integration-tests/milvus/pom.xml
similarity index 75%
rename from integration-tests-jvm/milvus/pom.xml
rename to integration-tests/milvus/pom.xml
index 7ccb2847f8..b840ad5386 100644
--- a/integration-tests-jvm/milvus/pom.xml
+++ b/integration-tests/milvus/pom.xml
@@ -31,6 +31,10 @@
<description>Integration tests for Camel Quarkus Milvus
extension</description>
<dependencies>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-direct</artifactId>
+ </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-milvus</artifactId>
@@ -39,8 +43,17 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-resteasy-jackson</artifactId>
+ </dependency>
<!-- test dependencies -->
+ <dependency>
+ <groupId>org.testcontainers</groupId>
+ <artifactId>testcontainers-milvus</artifactId>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit</artifactId>
@@ -90,6 +103,19 @@
</activation>
<dependencies>
<!-- 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>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-direct-deployment</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-milvus-deployment</artifactId>
@@ -105,6 +131,17 @@
</dependency>
</dependencies>
</profile>
+ <profile>
+ <id>skip-testcontainers-tests</id>
+ <activation>
+ <property>
+ <name>skip-testcontainers-tests</name>
+ </property>
+ </activation>
+ <properties>
+ <skipTests>true</skipTests>
+ </properties>
+ </profile>
</profiles>
</project>
diff --git
a/integration-tests/milvus/src/main/java/org/apache/camel/quarkus/component/milvus/it/MilvusResource.java
b/integration-tests/milvus/src/main/java/org/apache/camel/quarkus/component/milvus/it/MilvusResource.java
new file mode 100644
index 0000000000..fad4844f99
--- /dev/null
+++
b/integration-tests/milvus/src/main/java/org/apache/camel/quarkus/component/milvus/it/MilvusResource.java
@@ -0,0 +1,229 @@
+/*
+ * 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.milvus.it;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import io.milvus.common.clientenum.ConsistencyLevelEnum;
+import io.milvus.grpc.DataType;
+import io.milvus.param.IndexType;
+import io.milvus.param.MetricType;
+import io.milvus.param.collection.CollectionSchemaParam;
+import io.milvus.param.collection.CreateCollectionParam;
+import io.milvus.param.collection.FieldType;
+import io.milvus.param.dml.DeleteParam;
+import io.milvus.param.dml.InsertParam;
+import io.milvus.param.highlevel.dml.SearchSimpleParam;
+import io.milvus.param.index.CreateIndexParam;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.FluentProducerTemplate;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.component.milvus.MilvusAction;
+import org.apache.camel.component.milvus.MilvusHeaders;
+import org.jboss.logging.Logger;
+
+@Path("/milvus")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+@ApplicationScoped
+public class MilvusResource {
+
+ private static final Logger LOG = Logger.getLogger(MilvusResource.class);
+
+ private static final String COMPONENT_MILVUS = "milvus";
+
+ @Inject
+ CamelContext context;
+
+ @Inject
+ FluentProducerTemplate fluentTemplate;
+
+ @Inject
+ ProducerTemplate producerTemplate;
+
+ @POST
+ @Path("/create/{collectionName}")
+ public Response createCollection(@PathParam("collectionName") String
collectionName,
+ Map<String, Object> payload) {
+
+ int dimension =
Integer.parseInt(String.valueOf(payload.get("dimension")));
+ String vectorField = String.valueOf(payload.get("vector_field"));
+ Boolean autoId =
Boolean.valueOf(String.valueOf(payload.get("autoID")));
+
+ FieldType field1 = FieldType.newBuilder()
+ .withName("id")
+ .withDataType(DataType.Int64)
+ .withPrimaryKey(true)
+ .withAutoID(autoId)
+ .build();
+
+ FieldType field2 = FieldType.newBuilder()
+ .withName(vectorField)
+ .withDataType(DataType.FloatVector)
+ .withDimension(dimension)
+ .build();
+
+ CollectionSchemaParam schemaParam = CollectionSchemaParam.newBuilder()
+ .addFieldType(field1)
+ .addFieldType(field2)
+ .withEnableDynamicField(true)
+ .build();
+
+ CreateCollectionParam createParam = CreateCollectionParam.newBuilder()
+ .withCollectionName(collectionName)
+ .withSchema(schemaParam)
+ .build();
+
+ Exchange response = fluentTemplate.to("direct:in")
+ .withHeader(MilvusHeaders.ACTION,
MilvusAction.CREATE_COLLECTION)
+ .withHeader(MilvusHeaders.COLLECTION_NAME, collectionName)
+ .withBody(createParam)
+ .request(Exchange.class);
+
+ if (response.isFailed()) {
+ Exception ex = response.getException();
+ return Response.status(400).entity(ex.getMessage()).build();
+ }
+ return
Response.ok(response.getMessage().getBody(String.class)).build();
+
+ }
+
+ @POST
+ @Path("/index/{collectionName}")
+ public Response index(@PathParam("collectionName") String collectionName,
Map<String, Object> payload) {
+ String vectorField = String.valueOf(payload.get("vector_field"));
+ String extraParam = String.valueOf(payload.get("params"));
+
+ CreateIndexParam indexParam = CreateIndexParam.newBuilder()
+ .withCollectionName(collectionName)
+ .withFieldName(vectorField)
+ .withIndexType(IndexType.IVF_FLAT)
+ .withMetricType(MetricType.L2)
+ .withExtraParam(extraParam)
+ .withSyncMode(Boolean.TRUE)
+ .build();
+ Exchange response = fluentTemplate.to("direct:in")
+ .withHeader(MilvusHeaders.ACTION, MilvusAction.CREATE_INDEX)
+ .withHeader(MilvusHeaders.COLLECTION_NAME, collectionName)
+ .withBody(indexParam)
+ .request(Exchange.class);
+
+ if (response.isFailed()) {
+ Exception ex = response.getException();
+ return Response.status(400).entity(ex.getMessage()).build();
+ }
+ return
Response.ok(response.getMessage().getBody(String.class)).build();
+
+ }
+
+ @POST
+ @Path("/insert/{collectionName}")
+ public Response insertData(@PathParam("collectionName") String
collectionName, List<Map<String, Object>> data) {
+ Gson gson = new Gson();
+ List<JsonObject> rows = new ArrayList<>();
+
+ for (Map<String, Object> map : data) {
+ JsonObject row = gson.toJsonTree(map).getAsJsonObject();
+ rows.add(row);
+ }
+
+ InsertParam insertParam = InsertParam.newBuilder()
+ .withCollectionName(collectionName)
+ .withRows(rows)
+ .build();
+ Exchange response = fluentTemplate.to("direct:in")
+ .withHeader(MilvusHeaders.ACTION, MilvusAction.INSERT)
+ .withHeader(MilvusHeaders.COLLECTION_NAME, collectionName)
+ .withBody(insertParam).request(Exchange.class);
+ if (response.isFailed() && response.getException() != null) {
+ Exception exception = response.getException();
+ return Response.status(500)
+ .entity("Milvus Exception: " + exception.getMessage())
+ .build();
+ }
+ return Response.ok().build();
+
+ }
+
+ @POST
+ @Path("/search/{collectionName}")
+ public Response search(@PathParam("collectionName") String collectionName,
List<Float> payload) {
+
+ SearchSimpleParam searchParam = SearchSimpleParam.newBuilder()
+ .withCollectionName(collectionName)
+ .withVectors(payload)
+ .withLimit(100L)
+ .withOffset(0L)
+ .withConsistencyLevel(ConsistencyLevelEnum.STRONG)
+ .build();
+
+ Exchange response = fluentTemplate.to("direct:in")
+ .withHeader(MilvusHeaders.ACTION, MilvusAction.SEARCH)
+ .withHeader(MilvusHeaders.COLLECTION_NAME, collectionName)
+ .withBody(searchParam)
+ .request(Exchange.class);
+ if (response.isFailed()) {
+ Exception ex = response.getException();
+ return Response.status(400).entity(ex.getMessage()).build();
+ }
+ return
Response.ok(response.getMessage().getBody(String.class)).build();
+
+ }
+
+ @POST
+ @Path("/delete/{collectionName}")
+ public Response delete(@PathParam("collectionName") String collectionName,
List<Long> ids) {
+
+ String expr = "id in [" + ids.stream()
+ .map(String::valueOf)
+ .collect(Collectors.joining(",")) + "]";
+
+ DeleteParam deleteParam = DeleteParam.newBuilder()
+ .withCollectionName(collectionName)
+ .withExpr(expr)
+ .build();
+
+ Exchange response = fluentTemplate.to("direct:in")
+ .withHeader(MilvusHeaders.ACTION, MilvusAction.DELETE)
+ .withHeader(MilvusHeaders.COLLECTION_NAME, collectionName)
+ .withBody(deleteParam)
+ .request(Exchange.class);
+
+ if (response.isFailed()) {
+ Exception ex = response.getException();
+ return Response.status(400).entity(ex.getMessage()).build();
+ }
+ return
Response.ok(response.getMessage().getBody(String.class)).build();
+
+ }
+
+}
diff --git
a/integration-tests-jvm/milvus/src/test/java/org/apache/camel/quarkus/component/milvus/it/MilvusTest.java
b/integration-tests/milvus/src/main/java/org/apache/camel/quarkus/component/milvus/it/MilvusRoutes.java
similarity index 68%
rename from
integration-tests-jvm/milvus/src/test/java/org/apache/camel/quarkus/component/milvus/it/MilvusTest.java
rename to
integration-tests/milvus/src/main/java/org/apache/camel/quarkus/component/milvus/it/MilvusRoutes.java
index b692db6a8a..6e0a445c9a 100644
---
a/integration-tests-jvm/milvus/src/test/java/org/apache/camel/quarkus/component/milvus/it/MilvusTest.java
+++
b/integration-tests/milvus/src/main/java/org/apache/camel/quarkus/component/milvus/it/MilvusRoutes.java
@@ -16,19 +16,16 @@
*/
package org.apache.camel.quarkus.component.milvus.it;
-import io.quarkus.test.junit.QuarkusTest;
-import io.restassured.RestAssured;
-import org.junit.jupiter.api.Test;
+import org.apache.camel.builder.RouteBuilder;
-@QuarkusTest
-class MilvusTest {
+public class MilvusRoutes extends RouteBuilder {
- @Test
- public void loadComponentMilvus() {
- /* A simple autogenerated test */
- RestAssured.get("/milvus/load/component/milvus")
- .then()
- .statusCode(200);
- }
+ @Override
+ public void configure() throws Exception {
+ from("direct:in")
+ .log("Received body : ${body}")
+ .log("DEBUG: Target Collection Header is:
${header.CamelMilvusCollectionName}")
+ .toD("milvus:${header.CamelMilvusCollectionName}");
+ }
}
diff --git
a/integration-tests-jvm/milvus/src/test/java/org/apache/camel/quarkus/component/milvus/it/MilvusIT.java
b/integration-tests/milvus/src/test/java/org/apache/camel/quarkus/component/milvus/it/MilvusIT.java
similarity index 100%
rename from
integration-tests-jvm/milvus/src/test/java/org/apache/camel/quarkus/component/milvus/it/MilvusIT.java
rename to
integration-tests/milvus/src/test/java/org/apache/camel/quarkus/component/milvus/it/MilvusIT.java
diff --git
a/integration-tests/milvus/src/test/java/org/apache/camel/quarkus/component/milvus/it/MilvusTest.java
b/integration-tests/milvus/src/test/java/org/apache/camel/quarkus/component/milvus/it/MilvusTest.java
new file mode 100644
index 0000000000..07f6a9d87b
--- /dev/null
+++
b/integration-tests/milvus/src/test/java/org/apache/camel/quarkus/component/milvus/it/MilvusTest.java
@@ -0,0 +1,97 @@
+/*
+ * 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.milvus.it;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Stream;
+
+import io.quarkus.test.common.QuarkusTestResource;
+import io.quarkus.test.junit.QuarkusTest;
+import io.restassured.http.ContentType;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import static io.restassured.RestAssured.*;
+import static org.hamcrest.Matchers.containsStringIgnoringCase;
+
+@QuarkusTest
+@QuarkusTestResource(MilvusTestResource.class)
+class MilvusTest {
+
+ @ParameterizedTest
+ @MethodSource("provideScenarios")
+ public void testMilvusOperations(String operation, Map<String, Object>
config, Object data,
+ int status,
+ String error) {
+ String collectionName = (String) config.get("name");
+ var response = given()
+ .contentType(ContentType.JSON)
+ .body(data == null ? config : data)
+ .post("/milvus/" + operation + "/" + collectionName);
+
+ response.then().statusCode(status);
+
+ if (error != null) {
+ response.then().body(containsStringIgnoringCase(error));
+ }
+ }
+
+ private static Stream<Arguments> provideScenarios() {
+
+ Map<String, Object> config3d = Map.of(
+ "name", "col_3d",
+ "dimension", 3,
+ "vector_field", "vector",
+ "autoID", false);
+
+ Map<String, Object> ghostConfig = Map.of("name",
"non_existent_collection");
+
+ return Stream.of(
+ // 1. Create Collection
+ Arguments.of("create", config3d, null, 200, "Success"),
+
+ // 2. Insert Data
+ Arguments.of("insert", config3d,
+ List.of(Map.of("id", 1L, "vector", List.of(0.1f, 0.2f,
0.3f))), 200, null),
+ Arguments.of("insert", config3d,
+ List.of(Map.of("id", 2L, "vector", List.of(0.4f, 0.6f,
0.8f))), 200, null),
+ // 3. Index Data
+ Arguments.of("index", config3d, Map.of(
+ "vector_field", "vector", "params", "{\"nlist\":
1024}"), 200, "Success"),
+ // 4. Search
+ Arguments.of("search", config3d, List.of(0.1f, 0.2f, 0.3f),
200, null),
+
+ // 5. Delete
+ Arguments.of("delete", config3d, List.of(1L), 200,
"delete_cnt: 1"),
+
+ // Negative Use Case
+
+ // 1. Invalid insert
+ Arguments.of("insert", config3d,
+ List.of(Map.of("id", 4L, "vector", List.of(0.1f,
0.2f))), 500, "Milvus Exception"),
+ // 2. Invalid Search
+ Arguments.of("search", config3d, List.of(0.1f, 0.2f), 400,
"dimension mismatch"),
+
+ Arguments.of("search", ghostConfig, List.of(0.1f, 0.2f), 400,
"collection not found"),
+ // 3. Invalid delete
+ Arguments.of("delete", ghostConfig, List.of(1L), 400,
"collection not found"));
+
+ }
+
+}
diff --git
a/integration-tests/milvus/src/test/java/org/apache/camel/quarkus/component/milvus/it/MilvusTestResource.java
b/integration-tests/milvus/src/test/java/org/apache/camel/quarkus/component/milvus/it/MilvusTestResource.java
new file mode 100644
index 0000000000..a1ffa94219
--- /dev/null
+++
b/integration-tests/milvus/src/test/java/org/apache/camel/quarkus/component/milvus/it/MilvusTestResource.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.milvus.it;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
+import org.eclipse.microprofile.config.ConfigProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testcontainers.milvus.MilvusContainer;
+
+public class MilvusTestResource implements QuarkusTestResourceLifecycleManager
{
+
+ private static final Logger LOGGER =
LoggerFactory.getLogger(MilvusTestResource.class);
+ private static final String MILVUS_IMAGE =
ConfigProvider.getConfig().getValue("milvus.container.image",
+ String.class);
+ private MilvusContainer milvus;
+
+ @Override
+ public Map<String, String> start() {
+ Map<String, String> properties = new HashMap<>();
+ milvus = new MilvusContainer(MILVUS_IMAGE);
+ milvus.start();
+ properties.put("camel.component.milvus.host", milvus.getHost());
+ properties.put("camel.component.milvus.port",
String.valueOf(milvus.getMappedPort(19530)));
+ LOGGER.info("Properties: {}", properties);
+ return properties;
+
+ }
+
+ @Override
+ public void stop() {
+ try {
+ if (milvus != null) {
+ milvus.stop();
+ }
+ } catch (Exception e) {
+ LOGGER.error("An error occurred while stopping Milvus container",
e);
+ }
+
+ }
+}
diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
index 01e8f41d77..c4d86c0d13 100644
--- a/integration-tests/pom.xml
+++ b/integration-tests/pom.xml
@@ -177,6 +177,7 @@
<module>microprofile-fault-tolerance</module>
<module>microprofile-health</module>
<module>milo</module>
+ <module>milvus</module>
<module>minio</module>
<module>mllp</module>
<module>mongodb-grouped</module>
diff --git a/pom.xml b/pom.xml
index 324f3a0ae8..2a6ba75c03 100644
--- a/pom.xml
+++ b/pom.xml
@@ -268,6 +268,7 @@
<mysql.container.image>mirror.gcr.io/mysql:9.5</mysql.container.image>
<mariadb.container.image>mirror.gcr.io/mariadb:12.1</mariadb.container.image>
<mongodb.container.image>mirror.gcr.io/mongo:7.0</mongodb.container.image>
+ <milvus.container.image>milvusdb/milvus:v2.3.9</milvus.container.image>
<nats.container.image>mirror.gcr.io/nats:2.11.6</nats.container.image>
<opensearch.container.image>mirror.gcr.io/opensearchproject/opensearch:3.1.0</opensearch.container.image>
<openssh-server.container.image>mirror.gcr.io/linuxserver/openssh-server:version-9.7_p1-r4</openssh-server.container.image>
diff --git a/tooling/scripts/test-categories.yaml
b/tooling/scripts/test-categories.yaml
index 0203c20f52..64dd9fb7e6 100644
--- a/tooling/scripts/test-categories.yaml
+++ b/tooling/scripts/test-categories.yaml
@@ -243,6 +243,7 @@ group-13:
- jdbc-grouped
- kubernetes
- langchain4j-embeddingstore
+ - milvus
- salesforce
- sap-netweaver
- servicenow
@@ -250,3 +251,4 @@ group-13:
- nitrite
- twilio
- pgevent
+