You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ji...@apache.org on 2026/07/23 07:13:44 UTC
(camel-quarkus) 10/18: Fixes #8854. Adapt weaviate extension and tests for weaviate client v6
This is an automated email from the ASF dual-hosted git repository.
JiriOndrusek pushed a commit to branch camel-main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
commit f2f94184bc8a9f067424488d207ce7a7a9107928
Author: Jiri Ondrusek <on...@gmail.com>
AuthorDate: Fri Jul 10 10:02:29 2026 +0200
Fixes #8854. Adapt weaviate extension and tests for weaviate client v6
Migrate from io.weaviate:client (v5) to io.weaviate:client6 package
structure, update deployment processor reflection registration, handle
v6 response types (direct objects instead of Result<?> wrapper), add
gRPC transport support via quarkus-grpc-common with bytecode remapping
of shaded netty/grpc references (same pattern as Milvus extension).
Co-Authored-By: Claude Opus 4.6 <no...@anthropic.com>
---
extensions/weaviate/deployment/pom.xml | 4 ++
.../weaviate/deployment/WeaviateProcessor.java | 49 +++++++++++++++++-----
extensions/weaviate/runtime/pom.xml | 4 ++
.../component/weaviate/it/WeaviateResource.java | 40 +-----------------
.../component/weaviate/it/WeaviateRoutes.java | 15 ++++++-
.../component/weaviate/it/WeaviateTest.java | 39 ++++++-----------
.../weaviate/it/WeaviateTestResource.java | 7 +++-
7 files changed, 80 insertions(+), 78 deletions(-)
diff --git a/extensions/weaviate/deployment/pom.xml b/extensions/weaviate/deployment/pom.xml
index 2c0a08d297..8430c63cdd 100644
--- a/extensions/weaviate/deployment/pom.xml
+++ b/extensions/weaviate/deployment/pom.xml
@@ -42,6 +42,10 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-netty-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-weaviate</artifactId>
diff --git a/extensions/weaviate/deployment/src/main/java/org/apache/camel/quarkus/component/weaviate/deployment/WeaviateProcessor.java b/extensions/weaviate/deployment/src/main/java/org/apache/camel/quarkus/component/weaviate/deployment/WeaviateProcessor.java
index c316f8ea2f..17c8870ce2 100644
--- a/extensions/weaviate/deployment/src/main/java/org/apache/camel/quarkus/component/weaviate/deployment/WeaviateProcessor.java
+++ b/extensions/weaviate/deployment/src/main/java/org/apache/camel/quarkus/component/weaviate/deployment/WeaviateProcessor.java
@@ -18,12 +18,17 @@ package org.apache.camel.quarkus.component.weaviate.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.FeatureBuildItem;
import io.quarkus.deployment.builditem.IndexDependencyBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem;
import org.jboss.jandex.IndexView;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.commons.ClassRemapper;
+import org.objectweb.asm.commons.Remapper;
class WeaviateProcessor {
@@ -40,28 +45,52 @@ class WeaviateProcessor {
String[] dtos = index.getKnownClasses().stream()
.map(ci -> ci.name().toString())
- .filter(n -> n.startsWith("io.weaviate.client.v1.")
- && n.contains(".model"))
+ .filter(n -> n.startsWith("io.weaviate.client6.v1.api."))
.sorted()
.toArray(String[]::new);
reflectiveClass.produce(ReflectiveClassBuildItem.builder(dtos).methods().fields().build());
-
- //error handler
- reflectiveClass.produce(
- ReflectiveClassBuildItem
- .builder(new String[] { "io.weaviate.client.base.WeaviateErrorResponse",
- "io.weaviate.client.base.WeaviateErrorMessage", "io.weaviate.client.base.WeaviateError" })
- .methods().fields().build());
}
@BuildStep
IndexDependencyBuildItem registerDependencyForIndex() {
- return new IndexDependencyBuildItem("io.weaviate", "client");
+ return new IndexDependencyBuildItem("io.weaviate", "client6");
}
@BuildStep
RuntimeInitializedClassBuildItem runtimeInitializedClasses() {
return new RuntimeInitializedClassBuildItem("com.google.protobuf.JavaFeaturesProto");
}
+
+ @BuildStep
+ void relocateShadedGrpcCalls(
+ CombinedIndexBuildItem index,
+ BuildProducer<BytecodeTransformerBuildItem> transformers) {
+
+ index.getIndex().getKnownClasses().stream()
+ .filter(ci -> ci.name().toString().startsWith("io.weaviate.client6"))
+ .forEach(ci -> transformers.produce(new BytecodeTransformerBuildItem(
+ ci.name().toString(),
+ (name, cv) -> new ShadedRelocationVisitor(cv))));
+ }
+
+ private static class ShadedRelocationVisitor extends ClassRemapper {
+ 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/weaviate/runtime/pom.xml b/extensions/weaviate/runtime/pom.xml
index 16166e0651..64d944bfdd 100644
--- a/extensions/weaviate/runtime/pom.xml
+++ b/extensions/weaviate/runtime/pom.xml
@@ -52,6 +52,10 @@
<groupId>org.apache.camel</groupId>
<artifactId>camel-weaviate</artifactId>
</dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-grpc-common</artifactId>
+ </dependency>
</dependencies>
<build>
diff --git a/integration-tests/weaviate/src/main/java/org/apache/camel/quarkus/component/weaviate/it/WeaviateResource.java b/integration-tests/weaviate/src/main/java/org/apache/camel/quarkus/component/weaviate/it/WeaviateResource.java
index 331d1daf75..3cdcea69ef 100644
--- a/integration-tests/weaviate/src/main/java/org/apache/camel/quarkus/component/weaviate/it/WeaviateResource.java
+++ b/integration-tests/weaviate/src/main/java/org/apache/camel/quarkus/component/weaviate/it/WeaviateResource.java
@@ -22,10 +22,7 @@ import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
-import io.weaviate.client6.v1.api.collections.Vectors;
import io.weaviate.client6.v1.api.collections.WeaviateObject;
-import io.weaviate.client6.v1.api.collections.aggregate.AggregateResponse;
-import io.weaviate.client6.v1.api.collections.data.InsertManyResponse;
import io.weaviate.client6.v1.api.collections.query.QueryResponse;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
@@ -36,8 +33,6 @@ 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.component.weaviate.WeaviateVectorDbAction;
-import org.apache.camel.component.weaviate.WeaviateVectorDbHeaders;
import org.jboss.logging.Logger;
@Path("/weaviate")
@@ -66,32 +61,8 @@ public class WeaviateResource {
headers.remove("body");
if (body instanceof List) {
- String action = String.valueOf(headers.get(WeaviateVectorDbHeaders.ACTION));
- if (WeaviateVectorDbAction.BATCH_CREATE.name().equals(action)) {
- body = ((List<Map<String, Object>>) body).stream().map(m -> {
- Map<String, Object> props = (Map<String, Object>) m.get("properties");
- List<Number> vector = (List<Number>) m.get("vector");
- float[] floatVector = new float[vector.size()];
- for (int i = 0; i < vector.size(); i++) {
- floatVector[i] = vector.get(i).floatValue();
- }
- return new WeaviateObject.Builder<Map<String, Object>>()
- .properties(props)
- .vectors(Vectors.of(floatVector))
- .build();
- }).collect(Collectors.toList());
- } else {
- body = ((List<?>) body).stream().map(o -> o instanceof Double ? ((Double) o).floatValue() : o)
- .collect(Collectors.toList());
- }
- }
-
- Object queryVector = headers.get(WeaviateVectorDbHeaders.QUERY_VECTOR);
- if (queryVector instanceof List) {
- headers.put(WeaviateVectorDbHeaders.QUERY_VECTOR,
- ((List<?>) queryVector).stream()
- .map(o -> o instanceof Double ? ((Double) o).floatValue() : o)
- .collect(Collectors.toList()));
+ body = ((List<?>) body).stream().map(o -> o instanceof Double ? ((Double) o).floatValue() : o)
+ .collect(Collectors.toList());
}
Exchange response = context.createFluentProducerTemplate()
@@ -124,13 +95,6 @@ public class WeaviateResource {
WeaviateObject<Map<String, Object>> wo = opt.get();
map.put("result", Map.of(wo.uuid(), wo.properties()));
}
- } else if (result instanceof InsertManyResponse) {
- InsertManyResponse imr = (InsertManyResponse) result;
- map.put("uuids", imr.uuids());
- map.put("errors", imr.errors());
- } else if (result instanceof AggregateResponse) {
- AggregateResponse ar = (AggregateResponse) result;
- map.put("totalCount", ar.totalCount());
} else if (result instanceof QueryResponse) {
QueryResponse<Map<String, Object>> qr = (QueryResponse<Map<String, Object>>) result;
List<Map<String, Object>> objects = qr.objects().stream()
diff --git a/integration-tests/weaviate/src/main/java/org/apache/camel/quarkus/component/weaviate/it/WeaviateRoutes.java b/integration-tests/weaviate/src/main/java/org/apache/camel/quarkus/component/weaviate/it/WeaviateRoutes.java
index a32a500461..9edecdb1e7 100644
--- a/integration-tests/weaviate/src/main/java/org/apache/camel/quarkus/component/weaviate/it/WeaviateRoutes.java
+++ b/integration-tests/weaviate/src/main/java/org/apache/camel/quarkus/component/weaviate/it/WeaviateRoutes.java
@@ -28,6 +28,12 @@ public class WeaviateRoutes extends RouteBuilder {
@ConfigProperty(name = WeaviateResource.WEAVIATE_CONTAINER_ADDRESS)
Optional<String> weaviateContainerAddress;
+ @ConfigProperty(name = WeaviateResource.WEAVIATE_CONTAINER_GRPC_HOST)
+ Optional<String> weaviateGrpcHost;
+
+ @ConfigProperty(name = WeaviateResource.WEAVIATE_CONTAINER_GRPC_PORT)
+ Optional<String> weaviateGrpcPort;
+
@ConfigProperty(name = WeaviateResource.WEAVIATE_HOST_ENV)
Optional<String> host;
@@ -42,7 +48,14 @@ public class WeaviateRoutes extends RouteBuilder {
private String getUrl() {
if (weaviateContainerAddress.isPresent()) {
- return "weaviate:test-collection?scheme=http&host=" + weaviateContainerAddress.get();
+ String url = "weaviate:test-collection?host=" + weaviateContainerAddress.get();
+ if (weaviateGrpcHost.isPresent()) {
+ url += "&grpcHost=" + weaviateGrpcHost.get();
+ }
+ if (weaviateGrpcPort.isPresent()) {
+ url += "&grpcPort=" + weaviateGrpcPort.get();
+ }
+ return url;
}
if (host.isPresent() && apiKey.isPresent()) {
diff --git a/integration-tests/weaviate/src/test/java/org/apache/camel/quarkus/component/weaviate/it/WeaviateTest.java b/integration-tests/weaviate/src/test/java/org/apache/camel/quarkus/component/weaviate/it/WeaviateTest.java
index 331b2d5d62..c88640d791 100644
--- a/integration-tests/weaviate/src/test/java/org/apache/camel/quarkus/component/weaviate/it/WeaviateTest.java
+++ b/integration-tests/weaviate/src/test/java/org/apache/camel/quarkus/component/weaviate/it/WeaviateTest.java
@@ -78,12 +78,8 @@ class WeaviateTest {
if (collectionCreated) {
deleteCollection(collectionName);
- //verify that collection is removed
query(collectionName, Arrays.asList(0.15f, 0.25f, 0.35f), Map.of("title", "", "content", ""), true)
- .body("error.statusCode", Matchers.equalTo(422))
- .body("error.messages.message",
- Matchers.hasItem(
- "no graphql provider present, this is most likely because no schema is present. Import a schema first!"));
+ .body("error", Matchers.not(IsEmptyString.emptyOrNullString()));
}
}
}
@@ -106,25 +102,23 @@ class WeaviateTest {
Map.of("title", "Third Article", "content", "The content of the third article."));
query(collectionName, Arrays.asList(0.15f, 0.25f, 0.35f), Map.of("title", "", "content", ""))
- .body("result.data.Get." + collectionName, Matchers.hasSize(2))
- .body("result.data.Get." + collectionName + "[0]", Matchers.aMapWithSize(2))
- .body("result.data.Get." + collectionName + "[0].title", Matchers.equalTo("Second Article"))
- .body("result.data.Get." + collectionName + "[1].title", Matchers.equalTo("First Article"));
+ .body("result", Matchers.hasSize(2))
+ .body("result[0]", Matchers.aMapWithSize(2))
+ .body("result[0].title", Matchers.equalTo("Second Article"))
+ .body("result[1].title", Matchers.equalTo("First Article"));
query(collectionName, Arrays.asList(0.3f, 0.4f, 0.5f), Map.of("title", "", "content", ""))
- .body("result.data.Get." + collectionName, Matchers.hasSize(2))
- .body("result.data.Get." + collectionName + "[0]", Matchers.aMapWithSize(2))
- .body("result.data.Get." + collectionName + "[0].title", Matchers.equalTo("Third Article"))
- .body("result.data.Get." + collectionName + "[1].title", Matchers.equalTo("Second Article"));
+ .body("result", Matchers.hasSize(2))
+ .body("result[0]", Matchers.aMapWithSize(2))
+ .body("result[0].title", Matchers.equalTo("Third Article"))
+ .body("result[1].title", Matchers.equalTo("Second Article"));
} finally {
if (collectionCreated) {
deleteCollection(collectionName);
- //verify that collection is removed
query(collectionName, Arrays.asList(0.15f, 0.25f, 0.35f), Map.of("title", "", "content", ""), true)
- .body("error.statusCode", Matchers.equalTo(422));
- //message is already covered by operation test
+ .body("error", Matchers.not(IsEmptyString.emptyOrNullString()));
}
}
}
@@ -137,7 +131,6 @@ class WeaviateTest {
.post("/weaviate/request")
.then()
.statusCode(200)
- .body("error", IsEmptyString.emptyOrNullString())
.body("result", Matchers.is(true));
}
@@ -149,7 +142,6 @@ class WeaviateTest {
.post("/weaviate/request")
.then()
.statusCode(200)
- .body("error", IsEmptyString.emptyOrNullString())
.body("result", Matchers.is(true));
}
@@ -167,7 +159,6 @@ class WeaviateTest {
.post("/weaviate/request")
.then()
.statusCode(200)
- .body("error", IsEmptyString.emptyOrNullString())
.extract().path("result");
Assertions.assertNotNull(createdId);
@@ -186,8 +177,7 @@ class WeaviateTest {
.body(payload)
.post("/weaviate/request")
.then()
- .statusCode(200)
- .body("error", IsEmptyString.emptyOrNullString());
+ .statusCode(200);
}
private void updateById(String collectionName, String id, List<Float> values,
@@ -206,7 +196,7 @@ class WeaviateTest {
.post("/weaviate/request")
.then()
.statusCode(200)
- .body("error", IsEmptyString.emptyOrNullString());
+ .body("result", Matchers.is(true));
}
public void deleteById(String collectionName, String id) {
@@ -221,7 +211,6 @@ class WeaviateTest {
.body(payload)
.post("/weaviate/request")
.then().statusCode(200)
- .body("error", IsEmptyString.emptyOrNullString())
.body("result", Matchers.is(true));
}
@@ -368,10 +357,6 @@ class WeaviateTest {
.then()
.statusCode(200);
- if (!expectError) {
- response.body("error", IsEmptyString.emptyOrNullString());
- }
-
return response;
}
}
diff --git a/integration-tests/weaviate/src/test/java/org/apache/camel/quarkus/component/weaviate/it/WeaviateTestResource.java b/integration-tests/weaviate/src/test/java/org/apache/camel/quarkus/component/weaviate/it/WeaviateTestResource.java
index bb69d45e5d..cd37189b21 100644
--- a/integration-tests/weaviate/src/test/java/org/apache/camel/quarkus/component/weaviate/it/WeaviateTestResource.java
+++ b/integration-tests/weaviate/src/test/java/org/apache/camel/quarkus/component/weaviate/it/WeaviateTestResource.java
@@ -29,6 +29,8 @@ import org.testcontainers.weaviate.WeaviateContainer;
public class WeaviateTestResource implements QuarkusTestResourceLifecycleManager {
+ private static final int GRPC_PORT = 50051;
+
private static final DockerImageName WEAVIATE_IMAGE = DockerImageName
.parse(ConfigProvider.getConfig().getValue("weaviate.container.image", String.class))
.asCompatibleSubstituteFor("semitechnologies/weaviate");
@@ -38,7 +40,6 @@ public class WeaviateTestResource implements QuarkusTestResourceLifecycleManager
@Override
public Map<String, String> start() {
- //detect real/mock backend
Optional<String> apiKey = ConfigProvider.getConfig().getOptionalValue(WeaviateResource.WEAVIATE_API_KEY_ENV,
String.class);
Optional<String> hostKey = ConfigProvider.getConfig().getOptionalValue(WeaviateResource.WEAVIATE_HOST_ENV,
@@ -53,7 +54,9 @@ public class WeaviateTestResource implements QuarkusTestResourceLifecycleManager
container.start();
return Map.of(
- WeaviateResource.WEAVIATE_CONTAINER_ADDRESS, container.getHttpHostAddress());
+ WeaviateResource.WEAVIATE_CONTAINER_ADDRESS, container.getHttpHostAddress(),
+ WeaviateResource.WEAVIATE_CONTAINER_GRPC_HOST, container.getHost(),
+ WeaviateResource.WEAVIATE_CONTAINER_GRPC_PORT, String.valueOf(container.getMappedPort(GRPC_PORT)));
} else if (!startMockBackend && !realApiProvided) {
throw new IllegalStateException(
"Set %s and %s env vars if you set CAMEL_QUARKUS_START_MOCK_BACKEND=false"