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

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

commit 4ff854b0c062faefbbb242f28bf0a2fbae6453bc
Author: Jiri Ondrusek <[email protected]>
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 <[email protected]>
---
 extensions/weaviate/deployment/pom.xml             |  4 ++
 .../weaviate/deployment/WeaviateProcessor.java     | 49 +++++++++++++++----
 extensions/weaviate/runtime/pom.xml                |  4 ++
 .../component/weaviate/it/WeaviateResource.java    | 55 +++++++++++++---------
 .../component/weaviate/it/WeaviateRoutes.java      | 15 +++++-
 .../component/weaviate/it/WeaviateTest.java        | 39 +++++----------
 .../weaviate/it/WeaviateTestResource.java          |  7 ++-
 7 files changed, 112 insertions(+), 61 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 b31e40ab1a..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
@@ -19,11 +19,11 @@ package org.apache.camel.quarkus.component.weaviate.it;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.stream.Collectors;
 
-import io.weaviate.client.base.Result;
-import io.weaviate.client.v1.data.model.WeaviateObject;
-import io.weaviate.client.v1.graphql.model.GraphQLResponse;
+import io.weaviate.client6.v1.api.collections.WeaviateObject;
+import io.weaviate.client6.v1.api.collections.query.QueryResponse;
 import jakarta.enterprise.context.ApplicationScoped;
 import jakarta.inject.Inject;
 import jakarta.ws.rs.POST;
@@ -40,6 +40,8 @@ import org.jboss.logging.Logger;
 public class WeaviateResource {
 
     public static final String WEAVIATE_CONTAINER_ADDRESS = 
"cq.weaviate.container.address";
+    public static final String WEAVIATE_CONTAINER_GRPC_HOST = 
"cq.weaviate.container.grpc.host";
+    public static final String WEAVIATE_CONTAINER_GRPC_PORT = 
"cq.weaviate.container.grpc.port";
     public static final String WEAVIATE_API_KEY_ENV = "WEAVIATE_API_KEY";
     public static final String WEAVIATE_HOST_ENV = "WEAVIATE_HOST";
 
@@ -48,6 +50,7 @@ public class WeaviateResource {
     @Inject
     CamelContext context;
 
+    @SuppressWarnings("unchecked")
     @Path("/request")
     @POST
     @Produces(MediaType.APPLICATION_JSON)
@@ -57,7 +60,6 @@ public class WeaviateResource {
         Object body = headers.get("body");
         headers.remove("body");
 
-        //convert Double to Float in body list (for create)
         if (body instanceof List) {
             body = ((List<?>) body).stream().map(o -> o instanceof Double ? 
((Double) o).floatValue() : o)
                     .collect(Collectors.toList());
@@ -69,25 +71,36 @@ public class WeaviateResource {
                 .withHeaders(headers)
                 .request(Exchange.class);
 
-        Result<?> result = response.getIn().getBody(Result.class);
-        LOG.debugf("Response for collections with headers (%s) is: \"%s\".", 
headers, result);
+        if (response.getException() != null) {
+            HashMap<String, Object> errorMap = new HashMap<>();
+            errorMap.put("error", response.getException().getMessage());
+            return Response.ok(errorMap).build();
+        }
+
+        Object result = response.getIn().getBody();
+        LOG.debugf("Response for request with headers (%s) is: \"%s\".", 
headers, result);
 
         if (result != null) {
-            HashMap<String, Object> map = new HashMap();
-            map.put("error", result.getError() == null ? "" : 
result.getError());
-
-            if (result.getResult() instanceof Boolean) {
-                map.put("result", result.getResult());
-            } else if (result.getResult() instanceof WeaviateObject) {
-                map.put("result", ((WeaviateObject) 
result.getResult()).getId());
-                map.put("resultProperties", ((WeaviateObject) 
result.getResult()).getProperties());
-            } else if (result.getResult() instanceof List) {
-                @SuppressWarnings("unchecked")
-                List<WeaviateObject> objects = (List<WeaviateObject>) 
result.getResult();
-                map.put("result",
-                        
objects.stream().collect(Collectors.toMap(WeaviateObject::getId, 
WeaviateObject::getProperties)));
-            } else if (result.getResult() instanceof GraphQLResponse) {
-                map.put("result", result.getResult());
+            HashMap<String, Object> map = new HashMap<>();
+
+            if (result instanceof Boolean) {
+                map.put("result", result);
+            } else if (result instanceof WeaviateObject) {
+                WeaviateObject<Map<String, Object>> wo = 
(WeaviateObject<Map<String, Object>>) result;
+                map.put("result", wo.uuid());
+                map.put("resultProperties", wo.properties());
+            } else if (result instanceof Optional) {
+                Optional<WeaviateObject<Map<String, Object>>> opt = 
(Optional<WeaviateObject<Map<String, Object>>>) result;
+                if (opt.isPresent()) {
+                    WeaviateObject<Map<String, Object>> wo = opt.get();
+                    map.put("result", Map.of(wo.uuid(), wo.properties()));
+                }
+            } else if (result instanceof QueryResponse) {
+                QueryResponse<Map<String, Object>> qr = 
(QueryResponse<Map<String, Object>>) result;
+                List<Map<String, Object>> objects = qr.objects().stream()
+                        .map(WeaviateObject::properties)
+                        .collect(Collectors.toList());
+                map.put("result", objects);
             }
 
             return Response.ok(map).build();
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 65b66180d1..04e6e14f6c 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));
     }
 
@@ -246,10 +235,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"

Reply via email to