diff --git a/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/rag/RAGCreateCollection.java b/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/rag/RAGCreateCollection.java new file mode 100644 index 0000000000000..d2e6221e1a00a --- /dev/null +++ b/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/rag/RAGCreateCollection.java @@ -0,0 +1,163 @@ +/* + * 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.component.milvus.rag; + +import io.milvus.grpc.DataType; +import io.milvus.param.collection.CreateCollectionParam; +import io.milvus.param.collection.FieldType; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.component.milvus.MilvusAction; +import org.apache.camel.component.milvus.MilvusHeaders; + +public class RAGCreateCollection implements Processor { + + private String collectionName = "rag_collection"; + private String collectionDescription = "RAG collection"; + private String idFieldName = "id"; + private String dimension = "768"; + private String textFieldName = "content"; + private String textFieldDataType = "VarChar"; + private String vectorFieldName = "embedding"; + private String textFieldMaxLength = "2048"; + private String additionalTextFields; + + @Override + public void process(Exchange exchange) throws Exception { + int vectorDim = Integer.parseInt(dimension); + int maxLength = Integer.parseInt(textFieldMaxLength); + DataType textDataType = DataType.valueOf(textFieldDataType); + + FieldType idField = FieldType.newBuilder() + .withName(idFieldName) + .withDataType(DataType.Int64) + .withPrimaryKey(true) + .withAutoID(true) + .build(); + + FieldType.Builder textFieldBuilder = FieldType.newBuilder() + .withName(textFieldName) + .withDataType(textDataType); + if (textDataType == DataType.VarChar) { + textFieldBuilder.withMaxLength(maxLength); + } + FieldType textField = textFieldBuilder.build(); + + FieldType vectorField = FieldType.newBuilder() + .withName(vectorFieldName) + .withDataType(DataType.FloatVector) + .withDimension(vectorDim) + .build(); + + CreateCollectionParam.Builder builder = CreateCollectionParam.newBuilder() + .withCollectionName(collectionName) + .withDescription(collectionDescription) + .addFieldType(idField) + .addFieldType(textField); + + if (additionalTextFields != null && !additionalTextFields.isBlank()) { + for (String fieldName : additionalTextFields.split(",")) { + String trimmed = fieldName.trim(); + if (!trimmed.isEmpty()) { + FieldType extraField = FieldType.newBuilder() + .withName(trimmed) + .withDataType(DataType.VarChar) + .withMaxLength(maxLength) + .build(); + builder.addFieldType(extraField); + } + } + } + + builder.addFieldType(vectorField); + + exchange.getIn().setBody(builder.build()); + exchange.getIn().setHeader(MilvusHeaders.ACTION, MilvusAction.CREATE_COLLECTION); + } + + public String getCollectionName() { + return collectionName; + } + + public void setCollectionName(String collectionName) { + this.collectionName = collectionName; + } + + public String getCollectionDescription() { + return collectionDescription; + } + + public void setCollectionDescription(String collectionDescription) { + this.collectionDescription = collectionDescription; + } + + public String getIdFieldName() { + return idFieldName; + } + + public void setIdFieldName(String idFieldName) { + this.idFieldName = idFieldName; + } + + public String getDimension() { + return dimension; + } + + public void setDimension(String dimension) { + this.dimension = dimension; + } + + public String getTextFieldName() { + return textFieldName; + } + + public void setTextFieldName(String textFieldName) { + this.textFieldName = textFieldName; + } + + public String getTextFieldDataType() { + return textFieldDataType; + } + + public void setTextFieldDataType(String textFieldDataType) { + this.textFieldDataType = textFieldDataType; + } + + public String getVectorFieldName() { + return vectorFieldName; + } + + public void setVectorFieldName(String vectorFieldName) { + this.vectorFieldName = vectorFieldName; + } + + public String getTextFieldMaxLength() { + return textFieldMaxLength; + } + + public void setTextFieldMaxLength(String textFieldMaxLength) { + this.textFieldMaxLength = textFieldMaxLength; + } + + public String getAdditionalTextFields() { + return additionalTextFields; + } + + public void setAdditionalTextFields(String additionalTextFields) { + this.additionalTextFields = additionalTextFields; + } +} diff --git a/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/rag/RAGCreateIndex.java b/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/rag/RAGCreateIndex.java new file mode 100644 index 0000000000000..0430462b42f8d --- /dev/null +++ b/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/rag/RAGCreateIndex.java @@ -0,0 +1,92 @@ +/* + * 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.component.milvus.rag; + +import io.milvus.param.IndexType; +import io.milvus.param.MetricType; +import io.milvus.param.index.CreateIndexParam; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.component.milvus.MilvusAction; +import org.apache.camel.component.milvus.MilvusHeaders; + +public class RAGCreateIndex implements Processor { + + private String collectionName = "rag_collection"; + private String vectorFieldName = "embedding"; + private String indexType = "IVF_FLAT"; + private String metricType = "COSINE"; + private String extraParam = "{\"nlist\": 128}"; + + @Override + public void process(Exchange exchange) throws Exception { + IndexType idxType = IndexType.valueOf(indexType); + MetricType metric = MetricType.valueOf(metricType); + + CreateIndexParam param = CreateIndexParam.newBuilder() + .withCollectionName(collectionName) + .withFieldName(vectorFieldName) + .withIndexType(idxType) + .withMetricType(metric) + .withExtraParam(extraParam) + .withSyncMode(Boolean.TRUE) + .build(); + + exchange.getIn().setBody(param); + exchange.getIn().setHeader(MilvusHeaders.ACTION, MilvusAction.CREATE_INDEX); + } + + public String getCollectionName() { + return collectionName; + } + + public void setCollectionName(String collectionName) { + this.collectionName = collectionName; + } + + public String getVectorFieldName() { + return vectorFieldName; + } + + public void setVectorFieldName(String vectorFieldName) { + this.vectorFieldName = vectorFieldName; + } + + public String getIndexType() { + return indexType; + } + + public void setIndexType(String indexType) { + this.indexType = indexType; + } + + public String getMetricType() { + return metricType; + } + + public void setMetricType(String metricType) { + this.metricType = metricType; + } + + public String getExtraParam() { + return extraParam; + } + + public void setExtraParam(String extraParam) { + this.extraParam = extraParam; + } +} diff --git a/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/rag/RAGDelete.java b/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/rag/RAGDelete.java new file mode 100644 index 0000000000000..7c6292026ac57 --- /dev/null +++ b/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/rag/RAGDelete.java @@ -0,0 +1,58 @@ +/* + * 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.component.milvus.rag; + +import io.milvus.param.dml.DeleteParam; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.component.milvus.MilvusAction; +import org.apache.camel.component.milvus.MilvusHeaders; + +public class RAGDelete implements Processor { + + private String collectionName = "rag_collection"; + private String filter; + + @Override + public void process(Exchange exchange) throws Exception { + DeleteParam.Builder builder = DeleteParam.newBuilder() + .withCollectionName(collectionName); + + if (filter != null && !filter.isEmpty()) { + builder.withExpr(filter); + } + + exchange.getIn().setBody(builder.build()); + exchange.getIn().setHeader(MilvusHeaders.ACTION, MilvusAction.DELETE); + } + + public String getCollectionName() { + return collectionName; + } + + public void setCollectionName(String collectionName) { + this.collectionName = collectionName; + } + + public String getFilter() { + return filter; + } + + public void setFilter(String filter) { + this.filter = filter; + } +} diff --git a/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/rag/RAGInsert.java b/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/rag/RAGInsert.java new file mode 100644 index 0000000000000..fd983731ab5f4 --- /dev/null +++ b/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/rag/RAGInsert.java @@ -0,0 +1,84 @@ +/* + * 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.component.milvus.rag; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import io.milvus.param.dml.InsertParam; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.component.milvus.MilvusAction; +import org.apache.camel.component.milvus.MilvusHeaders; + +public class RAGInsert implements Processor { + + private String collectionName = "rag_collection"; + private String vectorFieldName = "embedding"; + private String textFieldMappings = "content=text"; + + @SuppressWarnings("unchecked") + @Override + public void process(Exchange exchange) throws Exception { + List vector = exchange.getIn().getBody(List.class); + + List fields = new ArrayList<>(); + + for (String mapping : textFieldMappings.split(",")) { + String[] pair = mapping.trim().split("="); + String fieldName = pair[0].trim(); + String variableName = pair[1].trim(); + String value = exchange.getVariable(variableName, String.class); + fields.add(new InsertParam.Field(fieldName, Collections.singletonList(value))); + } + + fields.add(new InsertParam.Field(vectorFieldName, Collections.singletonList(vector))); + + InsertParam param = InsertParam.newBuilder() + .withCollectionName(collectionName) + .withFields(fields) + .build(); + + exchange.getIn().setBody(param); + exchange.getIn().setHeader(MilvusHeaders.ACTION, MilvusAction.INSERT); + } + + public String getCollectionName() { + return collectionName; + } + + public void setCollectionName(String collectionName) { + this.collectionName = collectionName; + } + + public String getVectorFieldName() { + return vectorFieldName; + } + + public void setVectorFieldName(String vectorFieldName) { + this.vectorFieldName = vectorFieldName; + } + + public String getTextFieldMappings() { + return textFieldMappings; + } + + public void setTextFieldMappings(String textFieldMappings) { + this.textFieldMappings = textFieldMappings; + } +} diff --git a/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/rag/RAGResultExtractor.java b/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/rag/RAGResultExtractor.java new file mode 100644 index 0000000000000..701ef2e8a526a --- /dev/null +++ b/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/rag/RAGResultExtractor.java @@ -0,0 +1,66 @@ +/* + * 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.component.milvus.rag; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import io.milvus.param.highlevel.dml.response.SearchResponse; +import io.milvus.response.QueryResultsWrapper; +import org.apache.camel.Exchange; + +public class RAGResultExtractor { + + private String outputFields = "content"; + + public List> extract(Exchange exchange) { + SearchResponse response = exchange.getIn().getBody(SearchResponse.class); + List> extracted = new ArrayList<>(); + + String[] fields = outputFields.split(","); + + if (response != null) { + List records = response.getRowRecords(0); + int rank = 1; + for (QueryResultsWrapper.RowRecord record : records) { + Map item = new LinkedHashMap<>(); + item.put("rank", rank++); + for (String field : fields) { + String trimmed = field.trim(); + if (!trimmed.isEmpty()) { + Object value = record.get(trimmed); + if (value != null) { + item.put(trimmed, value); + } + } + } + extracted.add(item); + } + } + return extracted; + } + + public String getOutputFields() { + return outputFields; + } + + public void setOutputFields(String outputFields) { + this.outputFields = outputFields; + } +} diff --git a/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/rag/RAGSearch.java b/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/rag/RAGSearch.java new file mode 100644 index 0000000000000..6cb473a1d13ba --- /dev/null +++ b/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/rag/RAGSearch.java @@ -0,0 +1,98 @@ +/* + * 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.component.milvus.rag; + +import java.util.ArrayList; +import java.util.List; + +import io.milvus.common.clientenum.ConsistencyLevelEnum; +import io.milvus.param.highlevel.dml.SearchSimpleParam; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.component.milvus.MilvusAction; +import org.apache.camel.component.milvus.MilvusHeaders; + +public class RAGSearch implements Processor { + + private String collectionName = "rag_collection"; + private String outputFields = "content"; + private String limit = "10"; + private String filter; + + @SuppressWarnings("unchecked") + @Override + public void process(Exchange exchange) throws Exception { + List queryEmbedding = exchange.getIn().getBody(List.class); + long searchLimit = Long.parseLong(limit); + + List fields = new ArrayList<>(); + for (String field : outputFields.split(",")) { + String trimmed = field.trim(); + if (!trimmed.isEmpty()) { + fields.add(trimmed); + } + } + + SearchSimpleParam.Builder builder = SearchSimpleParam.newBuilder() + .withCollectionName(collectionName) + .withVectors(queryEmbedding) + .withLimit(searchLimit) + .withOutputFields(fields) + .withConsistencyLevel(ConsistencyLevelEnum.STRONG); + + if (filter != null && !filter.isEmpty()) { + builder.withFilter(filter); + } + + SearchSimpleParam param = builder.build(); + + exchange.getIn().setBody(param); + exchange.getIn().setHeader(MilvusHeaders.ACTION, MilvusAction.SEARCH); + } + + public String getCollectionName() { + return collectionName; + } + + public void setCollectionName(String collectionName) { + this.collectionName = collectionName; + } + + public String getOutputFields() { + return outputFields; + } + + public void setOutputFields(String outputFields) { + this.outputFields = outputFields; + } + + public String getLimit() { + return limit; + } + + public void setLimit(String limit) { + this.limit = limit; + } + + public String getFilter() { + return filter; + } + + public void setFilter(String filter) { + this.filter = filter; + } +} diff --git a/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/rag/RAGUpsert.java b/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/rag/RAGUpsert.java new file mode 100644 index 0000000000000..f975fd717be9b --- /dev/null +++ b/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/rag/RAGUpsert.java @@ -0,0 +1,84 @@ +/* + * 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.component.milvus.rag; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import io.milvus.param.dml.UpsertParam; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.component.milvus.MilvusAction; +import org.apache.camel.component.milvus.MilvusHeaders; + +public class RAGUpsert implements Processor { + + private String collectionName = "rag_collection"; + private String vectorFieldName = "embedding"; + private String textFieldMappings = "content=text"; + + @SuppressWarnings("unchecked") + @Override + public void process(Exchange exchange) throws Exception { + List vector = exchange.getIn().getBody(List.class); + + List fields = new ArrayList<>(); + + for (String mapping : textFieldMappings.split(",")) { + String[] pair = mapping.trim().split("="); + String fieldName = pair[0].trim(); + String variableName = pair[1].trim(); + String value = exchange.getVariable(variableName, String.class); + fields.add(new UpsertParam.Field(fieldName, Collections.singletonList(value))); + } + + fields.add(new UpsertParam.Field(vectorFieldName, Collections.singletonList(vector))); + + UpsertParam param = UpsertParam.newBuilder() + .withCollectionName(collectionName) + .withFields(fields) + .build(); + + exchange.getIn().setBody(param); + exchange.getIn().setHeader(MilvusHeaders.ACTION, MilvusAction.UPSERT); + } + + public String getCollectionName() { + return collectionName; + } + + public void setCollectionName(String collectionName) { + this.collectionName = collectionName; + } + + public String getVectorFieldName() { + return vectorFieldName; + } + + public void setVectorFieldName(String vectorFieldName) { + this.vectorFieldName = vectorFieldName; + } + + public String getTextFieldMappings() { + return textFieldMappings; + } + + public void setTextFieldMappings(String textFieldMappings) { + this.textFieldMappings = textFieldMappings; + } +} diff --git a/components/camel-ai/camel-milvus/src/test/java/org/apache/camel/component/milvus/MilvusCreateCollectionTest.java b/components/camel-ai/camel-milvus/src/test/java/org/apache/camel/component/milvus/MilvusCreateCollectionTest.java index a75119addc330..281e6244fa44e 100644 --- a/components/camel-ai/camel-milvus/src/test/java/org/apache/camel/component/milvus/MilvusCreateCollectionTest.java +++ b/components/camel-ai/camel-milvus/src/test/java/org/apache/camel/component/milvus/MilvusCreateCollectionTest.java @@ -17,12 +17,10 @@ package org.apache.camel.component.milvus; -import io.milvus.grpc.DataType; -import io.milvus.param.collection.CollectionSchemaParam; -import io.milvus.param.collection.CreateCollectionParam; -import io.milvus.param.collection.FieldType; import org.apache.camel.Exchange; import org.apache.camel.NoSuchHeaderException; +import org.apache.camel.component.milvus.rag.RAGCreateCollection; +import org.apache.camel.support.DefaultExchange; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -32,43 +30,22 @@ public class MilvusCreateCollectionTest extends MilvusTestSupport { @DisplayName("Tests that trying to create a collection without passing the action name triggers a failure") @Test - public void createCollectionWithoutRequiredParameters() { - FieldType fieldType1 = FieldType.newBuilder() - .withName("userID") - .withDescription("user identification") - .withDataType(DataType.Int64) - .withPrimaryKey(true) - .withAutoID(true) - .build(); - - FieldType fieldType2 = FieldType.newBuilder() - .withName("userFace") - .withDescription("face embedding") - .withDataType(DataType.FloatVector) - .withDimension(64) - .build(); - - FieldType fieldType3 = FieldType.newBuilder() - .withName("userAge") - .withDescription("user age") - .withDataType(DataType.Int8) - .build(); - - CreateCollectionParam createCollectionReq = CreateCollectionParam.newBuilder() - .withCollectionName("test") - .withDescription("customer info") - .withShardsNum(2) - .withSchema(CollectionSchemaParam.newBuilder() - .withEnableDynamicField(false) - .addFieldType(fieldType1) - .addFieldType(fieldType2) - .addFieldType(fieldType3) - .build()) - .build(); - + public void createCollectionWithoutRequiredParameters() throws Exception { + RAGCreateCollection ragCreateCollection = new RAGCreateCollection(); + ragCreateCollection.setCollectionName("test"); + ragCreateCollection.setCollectionDescription("customer info"); + ragCreateCollection.setIdFieldName("userID"); + ragCreateCollection.setVectorFieldName("userFace"); + ragCreateCollection.setTextFieldName("userAge"); + ragCreateCollection.setTextFieldDataType("Int8"); + ragCreateCollection.setDimension("64"); + + Exchange tempExchange = new DefaultExchange(context); + ragCreateCollection.process(tempExchange); + + // Send body without the action header to trigger failure Exchange result = fluentTemplate.to("milvus:createCollection") - .withBody( - createCollectionReq) + .withBody(tempExchange.getIn().getBody()) .request(Exchange.class); assertThat(result).isNotNull(); diff --git a/components/camel-ai/camel-milvus/src/test/java/org/apache/camel/component/milvus/it/MilvusComponentIT.java b/components/camel-ai/camel-milvus/src/test/java/org/apache/camel/component/milvus/it/MilvusComponentIT.java index cab3064b08520..3fcfe23e4b96b 100644 --- a/components/camel-ai/camel-milvus/src/test/java/org/apache/camel/component/milvus/it/MilvusComponentIT.java +++ b/components/camel-ai/camel-milvus/src/test/java/org/apache/camel/component/milvus/it/MilvusComponentIT.java @@ -21,24 +21,22 @@ import java.util.Random; import io.milvus.common.clientenum.ConsistencyLevelEnum; -import io.milvus.grpc.DataType; import io.milvus.grpc.QueryResults; 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.dml.QueryParam; import io.milvus.param.dml.UpsertParam; -import io.milvus.param.highlevel.dml.SearchSimpleParam; import io.milvus.param.highlevel.dml.response.SearchResponse; import io.milvus.param.index.CreateIndexParam; import org.apache.camel.Exchange; import org.apache.camel.component.milvus.MilvusAction; import org.apache.camel.component.milvus.MilvusHeaders; import org.apache.camel.component.milvus.MilvusTestSupport; +import org.apache.camel.component.milvus.rag.RAGCreateCollection; +import org.apache.camel.component.milvus.rag.RAGCreateIndex; +import org.apache.camel.component.milvus.rag.RAGDelete; +import org.apache.camel.component.milvus.rag.RAGSearch; +import org.apache.camel.support.DefaultExchange; import org.assertj.core.util.Lists; import org.junit.jupiter.api.*; @@ -48,43 +46,22 @@ public class MilvusComponentIT extends MilvusTestSupport { @Test @Order(1) - public void createCollection() { - FieldType fieldType1 = FieldType.newBuilder() - .withName("userID") - .withDescription("user identification") - .withDataType(DataType.Int64) - .withPrimaryKey(true) - .withAutoID(true) - .build(); - - FieldType fieldType2 = FieldType.newBuilder() - .withName("userFace") - .withDescription("face embedding") - .withDataType(DataType.FloatVector) - .withDimension(64) - .build(); - - FieldType fieldType3 = FieldType.newBuilder() - .withName("userAge") - .withDescription("user age") - .withDataType(DataType.Int8) - .build(); - - CreateCollectionParam createCollectionReq = CreateCollectionParam.newBuilder() - .withCollectionName("test") - .withDescription("customer info") - .withShardsNum(2) - .withSchema(CollectionSchemaParam.newBuilder() - .withEnableDynamicField(false) - .addFieldType(fieldType1) - .addFieldType(fieldType2) - .addFieldType(fieldType3).build()) - .build(); + public void createCollection() throws Exception { + RAGCreateCollection ragCreateCollection = new RAGCreateCollection(); + ragCreateCollection.setCollectionName("test"); + ragCreateCollection.setCollectionDescription("customer info"); + ragCreateCollection.setIdFieldName("userID"); + ragCreateCollection.setVectorFieldName("userFace"); + ragCreateCollection.setTextFieldName("userAge"); + ragCreateCollection.setTextFieldDataType("Int8"); + ragCreateCollection.setDimension("64"); + + Exchange tempExchange = new DefaultExchange(context); + ragCreateCollection.process(tempExchange); Exchange result = fluentTemplate.to("milvus:test") - .withHeader(MilvusHeaders.ACTION, MilvusAction.CREATE_COLLECTION) - .withBody( - createCollectionReq) + .withHeader(MilvusHeaders.ACTION, tempExchange.getIn().getHeader(MilvusHeaders.ACTION)) + .withBody(tempExchange.getIn().getBody()) .request(Exchange.class); assertThat(result).isNotNull(); @@ -93,7 +70,7 @@ public void createCollection() { @Test @Order(2) - public void createIndex() { + public void createIndex() throws Exception { CreateIndexParam createAgeIndexParam = CreateIndexParam.newBuilder() .withCollectionName("test") .withFieldName("userAge") @@ -110,20 +87,19 @@ public void createIndex() { assertThat(result).isNotNull(); assertThat(result.getException()).isNull(); - CreateIndexParam createVectorIndexParam = CreateIndexParam.newBuilder() - .withCollectionName("test") - .withFieldName("userFace") - .withIndexName("userFaceIndex") - .withIndexType(IndexType.IVF_FLAT) - .withMetricType(MetricType.L2) - .withExtraParam("{\"nlist\":128}") - .withSyncMode(Boolean.TRUE) - .build(); + RAGCreateIndex ragCreateIndex = new RAGCreateIndex(); + ragCreateIndex.setCollectionName("test"); + ragCreateIndex.setVectorFieldName("userFace"); + ragCreateIndex.setIndexType("IVF_FLAT"); + ragCreateIndex.setMetricType("L2"); + ragCreateIndex.setExtraParam("{\"nlist\":128}"); + + Exchange tempExchange = new DefaultExchange(context); + ragCreateIndex.process(tempExchange); result = fluentTemplate.to("milvus:test") - .withHeader(MilvusHeaders.ACTION, MilvusAction.CREATE_INDEX) - .withBody( - createVectorIndexParam) + .withHeader(MilvusHeaders.ACTION, tempExchange.getIn().getHeader(MilvusHeaders.ACTION)) + .withBody(tempExchange.getIn().getBody()) .request(Exchange.class); assertThat(result).isNotNull(); @@ -187,21 +163,20 @@ public void upsert() { @Test @Order(5) - public void search() { - SearchSimpleParam searchSimpleParam = SearchSimpleParam.newBuilder() - .withCollectionName("test") - .withVectors(generateFloatVector()) - .withFilter("userAge>0") - .withLimit(100L) - .withOffset(0L) - .withOutputFields(Lists.newArrayList("userAge")) - .withConsistencyLevel(ConsistencyLevelEnum.STRONG) - .build(); + public void search() throws Exception { + RAGSearch ragSearch = new RAGSearch(); + ragSearch.setCollectionName("test"); + ragSearch.setOutputFields("userAge"); + ragSearch.setFilter("userAge>0"); + ragSearch.setLimit("100"); + + Exchange tempExchange = new DefaultExchange(context); + tempExchange.getIn().setBody(generateFloatVector()); + ragSearch.process(tempExchange); Exchange result = fluentTemplate.to("milvus:test") - .withHeader(MilvusHeaders.ACTION, MilvusAction.SEARCH) - .withBody( - searchSimpleParam) + .withHeader(MilvusHeaders.ACTION, tempExchange.getIn().getHeader(MilvusHeaders.ACTION)) + .withBody(tempExchange.getIn().getBody()) .request(Exchange.class); assertThat(result).isNotNull(); @@ -232,35 +207,35 @@ public void query() { @Test @Order(7) - public void delete() { - DeleteParam delete = DeleteParam.newBuilder() - .withCollectionName("test") - .withExpr("userAge>0") - .build(); + public void delete() throws Exception { + RAGDelete ragDelete = new RAGDelete(); + ragDelete.setCollectionName("test"); + ragDelete.setFilter("userAge>0"); + + Exchange tempExchange = new DefaultExchange(context); + ragDelete.process(tempExchange); Exchange result = fluentTemplate.to("milvus:test") - .withHeader(MilvusHeaders.ACTION, MilvusAction.DELETE) - .withBody( - delete) + .withHeader(MilvusHeaders.ACTION, tempExchange.getIn().getHeader(MilvusHeaders.ACTION)) + .withBody(tempExchange.getIn().getBody()) .request(Exchange.class); assertThat(result).isNotNull(); assertThat(result.getException()).isNull(); - SearchSimpleParam searchSimpleParam = SearchSimpleParam.newBuilder() - .withCollectionName("test") - .withVectors(generateFloatVector()) - .withFilter("userAge>0") - .withLimit(100L) - .withOffset(0L) - .withOutputFields(Lists.newArrayList("userAge")) - .withConsistencyLevel(ConsistencyLevelEnum.STRONG) - .build(); + RAGSearch ragSearch = new RAGSearch(); + ragSearch.setCollectionName("test"); + ragSearch.setOutputFields("userAge"); + ragSearch.setFilter("userAge>0"); + ragSearch.setLimit("100"); + + tempExchange = new DefaultExchange(context); + tempExchange.getIn().setBody(generateFloatVector()); + ragSearch.process(tempExchange); result = fluentTemplate.to("milvus:test") - .withHeader(MilvusHeaders.ACTION, MilvusAction.SEARCH) - .withBody( - searchSimpleParam) + .withHeader(MilvusHeaders.ACTION, tempExchange.getIn().getHeader(MilvusHeaders.ACTION)) + .withBody(tempExchange.getIn().getBody()) .request(Exchange.class); assertThat(result).isNotNull();