Browse Source

Test and example for V2 (#912)

Signed-off-by: yhmo <yihua.mo@zilliz.com>
groot 1 year ago
parent
commit
1554910d89
31 changed files with 500 additions and 323 deletions
  1. 4 5
      .gitignore
  2. 1 1
      examples/main/java/io/milvus/v1/BinaryVectorExample.java
  3. 1 1
      examples/main/java/io/milvus/v1/BulkWriterExample.java
  4. 1 1
      examples/main/java/io/milvus/v1/CommonUtils.java
  5. 1 1
      examples/main/java/io/milvus/v1/Float16VectorExample.java
  6. 1 1
      examples/main/java/io/milvus/v1/GeneralExample.java
  7. 1 1
      examples/main/java/io/milvus/v1/HighLevelExample.java
  8. 1 1
      examples/main/java/io/milvus/v1/HybridSearchExample.java
  9. 1 1
      examples/main/java/io/milvus/v1/IteratorExample.java
  10. 1 1
      examples/main/java/io/milvus/v1/RBACExample.java
  11. 2 2
      examples/main/java/io/milvus/v1/ResourceGroupExample.java
  12. 1 1
      examples/main/java/io/milvus/v1/SimpleExample.java
  13. 1 1
      examples/main/java/io/milvus/v1/SparseVectorExample.java
  14. 14 7
      examples/main/java/io/milvus/v1/TLSExample.java
  15. 1 1
      examples/main/java/io/milvus/v1/resourcegroup/NodeInfo.java
  16. 1 1
      examples/main/java/io/milvus/v1/resourcegroup/ResourceGroupInfo.java
  17. 1 1
      examples/main/java/io/milvus/v1/resourcegroup/ResourceGroupManagement.java
  18. 90 0
      examples/main/java/io/milvus/v2/SimpleExample.java
  19. 0 0
      examples/main/resources/tls/gen.sh
  20. 0 0
      examples/main/resources/tls/openssl.cnf
  21. 0 115
      src/main/java/io/milvus/v2/examples/Simple.java
  22. 0 136
      src/main/java/io/milvus/v2/examples/Simple_Schema.java
  23. 7 2
      src/main/java/io/milvus/v2/service/collection/CollectionService.java
  24. 3 0
      src/main/java/io/milvus/v2/service/index/response/DescribeIndexResp.java
  25. 3 0
      src/main/java/io/milvus/v2/service/vector/request/data/BFloat16Vec.java
  26. 3 1
      src/main/java/io/milvus/v2/service/vector/request/data/BinaryVec.java
  27. 3 1
      src/main/java/io/milvus/v2/service/vector/request/data/Float16Vec.java
  28. 8 0
      src/main/java/io/milvus/v2/service/vector/request/data/FloatVec.java
  29. 5 1
      src/main/java/io/milvus/v2/utils/ConvertUtils.java
  30. 5 0
      src/main/java/io/milvus/v2/utils/SchemaUtils.java
  31. 339 39
      src/test/java/io/milvus/v2/client/MilvusClientV2DockerTest.java

+ 4 - 5
.gitignore

@@ -31,8 +31,7 @@ volumes/
 *.iml
 
 # Example files
-examples/main/java/io/milvus/tls/*
-!examples/main/java/io/milvus/tls/gen.sh
-!examples/main/java/io/milvus/tls/openssl.cnf
-/src/main/java/io/milvus/v2/examples/*
-/src/main/java/io/milvus/v2/examples/ManageCollectionDemo.java
+examples/main/resources/tls/*
+!examples/main/resources/tls/gen.sh
+!examples/main/resources/tls/openssl.cnf
+

+ 1 - 1
examples/main/java/io/milvus/BinaryVectorExample.java → examples/main/java/io/milvus/v1/BinaryVectorExample.java

@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.milvus;
+package io.milvus.v1;
 
 import com.google.gson.Gson;
 import com.google.gson.JsonObject;

+ 1 - 1
examples/main/java/io/milvus/BulkWriterExample.java → examples/main/java/io/milvus/v1/BulkWriterExample.java

@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.milvus;
+package io.milvus.v1;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.dataformat.csv.CsvMapper;

+ 1 - 1
examples/main/java/io/milvus/CommonUtils.java → examples/main/java/io/milvus/v1/CommonUtils.java

@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.milvus;
+package io.milvus.v1;
 
 import io.milvus.param.R;
 import org.tensorflow.ndarray.buffer.ByteDataBuffer;

+ 1 - 1
examples/main/java/io/milvus/Float16VectorExample.java → examples/main/java/io/milvus/v1/Float16VectorExample.java

@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.milvus;
+package io.milvus.v1;
 
 import com.google.gson.Gson;
 import com.google.gson.JsonObject;

+ 1 - 1
examples/main/java/io/milvus/GeneralExample.java → examples/main/java/io/milvus/v1/GeneralExample.java

@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.milvus;
+package io.milvus.v1;
 
 import com.google.gson.Gson;
 import com.google.gson.JsonObject;

+ 1 - 1
examples/main/java/io/milvus/HighLevelExample.java → examples/main/java/io/milvus/v1/HighLevelExample.java

@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.milvus;
+package io.milvus.v1;
 
 import com.google.gson.Gson;
 import com.google.gson.JsonObject;

+ 1 - 1
examples/main/java/io/milvus/HybridSearchExample.java → examples/main/java/io/milvus/v1/HybridSearchExample.java

@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.milvus;
+package io.milvus.v1;
 
 import com.google.gson.Gson;
 import com.google.gson.JsonObject;

+ 1 - 1
examples/main/java/io/milvus/IteratorExample.java → examples/main/java/io/milvus/v1/IteratorExample.java

@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package io.milvus;
+package io.milvus.v1;
 
 import com.google.common.collect.Lists;
 import io.milvus.client.MilvusClient;

+ 1 - 1
examples/main/java/io/milvus/RBACExample.java → examples/main/java/io/milvus/v1/RBACExample.java

@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.milvus;
+package io.milvus.v1;
 
 import io.milvus.client.MilvusServiceClient;
 import io.milvus.grpc.ListCredUsersResponse;

+ 2 - 2
examples/main/java/io/milvus/ResourceGroupExample.java → examples/main/java/io/milvus/v1/ResourceGroupExample.java

@@ -1,9 +1,9 @@
-package io.milvus;
+package io.milvus.v1;
 
 import com.google.gson.Gson;
 
 import io.milvus.client.MilvusServiceClient;
-import io.milvus.resourcegroup.ResourceGroupManagement;
+import io.milvus.v1.resourcegroup.ResourceGroupManagement;
 import io.milvus.param.ConnectParam;
 
 public class ResourceGroupExample {

+ 1 - 1
examples/main/java/io/milvus/SimpleExample.java → examples/main/java/io/milvus/v1/SimpleExample.java

@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.milvus;
+package io.milvus.v1;
 
 import com.google.gson.Gson;
 import com.google.gson.JsonObject;

+ 1 - 1
examples/main/java/io/milvus/SparseVectorExample.java → examples/main/java/io/milvus/v1/SparseVectorExample.java

@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.milvus;
+package io.milvus.v1;
 
 import com.google.gson.Gson;
 import com.google.gson.JsonObject;

+ 14 - 7
examples/main/java/io/milvus/TLSExample.java → examples/main/java/io/milvus/v1/TLSExample.java

@@ -16,13 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package io.milvus;
+package io.milvus.v1;
 
 import io.milvus.client.MilvusServiceClient;
 import io.milvus.grpc.CheckHealthResponse;
 import io.milvus.param.ConnectParam;
 import io.milvus.param.R;
 
+import java.io.File;
+import java.net.URL;
+
 
 // Note: read the following description before running this example
 // 1. cmd into the "tls" folder, generate certificate by the following commands.
@@ -49,12 +52,14 @@ import io.milvus.param.R;
 public class TLSExample {
 
     private static void oneWayAuth() {
-        String path = ClassLoader.getSystemResource("").getPath();
+        ClassLoader classLoader = BulkWriterExample.class.getClassLoader();
+        URL resourceUrl = classLoader.getResource("tls");
+        String path = new File(resourceUrl.getFile()).getAbsolutePath();
         ConnectParam connectParam = ConnectParam.newBuilder()
                 .withHost("localhost")
                 .withPort(19530)
                 .withServerName("localhost")
-                .withServerPemPath(path + "/tls/server.pem")
+                .withServerPemPath(path + "/server.pem")
                 .build();
         MilvusServiceClient milvusClient = new MilvusServiceClient(connectParam);
 
@@ -67,14 +72,16 @@ public class TLSExample {
     }
 
     private static void twoWayAuth() {
-        String path = ClassLoader.getSystemResource("").getPath();
+        ClassLoader classLoader = BulkWriterExample.class.getClassLoader();
+        URL resourceUrl = classLoader.getResource("tls");
+        String path = new File(resourceUrl.getFile()).getAbsolutePath();
         ConnectParam connectParam = ConnectParam.newBuilder()
                 .withHost("localhost")
                 .withPort(19530)
                 .withServerName("localhost")
-                .withCaPemPath(path + "/tls/ca.pem")
-                .withClientKeyPath(path + "/tls/client.key")
-                .withClientPemPath(path + "/tls/client.pem")
+                .withCaPemPath(path + "/ca.pem")
+                .withClientKeyPath(path + "/client.key")
+                .withClientPemPath(path + "/client.pem")
                 .build();
         MilvusServiceClient milvusClient = new MilvusServiceClient(connectParam);
 

+ 1 - 1
examples/main/java/io/milvus/resourcegroup/NodeInfo.java → examples/main/java/io/milvus/v1/resourcegroup/NodeInfo.java

@@ -1,4 +1,4 @@
-package io.milvus.resourcegroup;
+package io.milvus.v1.resourcegroup;
 
 import lombok.Getter;
 import lombok.NonNull;

+ 1 - 1
examples/main/java/io/milvus/resourcegroup/ResourceGroupInfo.java → examples/main/java/io/milvus/v1/resourcegroup/ResourceGroupInfo.java

@@ -1,4 +1,4 @@
-package io.milvus.resourcegroup;
+package io.milvus.v1.resourcegroup;
 
 import java.util.HashSet;
 import java.util.Set;

+ 1 - 1
examples/main/java/io/milvus/resourcegroup/ResourceGroupManagement.java → examples/main/java/io/milvus/v1/resourcegroup/ResourceGroupManagement.java

@@ -1,4 +1,4 @@
-package io.milvus.resourcegroup;
+package io.milvus.v1.resourcegroup;
 
 import java.util.Arrays;
 import java.util.HashMap;

+ 90 - 0
examples/main/java/io/milvus/v2/SimpleExample.java

@@ -0,0 +1,90 @@
+package io.milvus.v2;
+
+import com.google.gson.*;
+import io.milvus.v2.client.*;
+import io.milvus.v2.common.ConsistencyLevel;
+import io.milvus.v2.service.collection.request.CreateCollectionReq;
+import io.milvus.v2.service.collection.request.DropCollectionReq;
+import io.milvus.v2.service.collection.request.GetCollectionStatsReq;
+import io.milvus.v2.service.collection.response.GetCollectionStatsResp;
+import io.milvus.v2.service.vector.request.*;
+import io.milvus.v2.service.vector.request.data.FloatVec;
+import io.milvus.v2.service.vector.response.*;
+
+import java.util.*;
+
+public class SimpleExample {
+    public static void main(String[] args) {
+
+        ConnectConfig config = ConnectConfig.builder()
+                .uri("http://localhost:19530")
+                .build();
+        MilvusClientV2 client = new MilvusClientV2(config);
+
+        String collectionName = "simple_test";
+        // drop collection if exists
+        client.dropCollection(DropCollectionReq.builder()
+                .collectionName(collectionName)
+                .build());
+
+        // quickly create a collection with "id" field and "vector" field
+        client.createCollection(CreateCollectionReq.builder()
+                .collectionName(collectionName)
+                .dimension(4)
+                .build());
+        System.out.printf("Collection '%s' created\n", collectionName);
+
+        // insert some data
+        List<JsonObject> rows = new ArrayList<>();
+        Gson gson = new Gson();
+        for (int i = 0; i < 100; i++) {
+            JsonObject row = new JsonObject();
+            row.addProperty("id", i);
+            row.add("vector", gson.toJsonTree(new float[]{i, (float) i /2, (float) i /3, (float) i /4}));
+            row.addProperty(String.format("dynamic_%d", i), "this is dynamic value"); // this value is stored in dynamic field
+            rows.add(row);
+        }
+        InsertResp insertR = client.insert(InsertReq.builder()
+                .collectionName(collectionName)
+                .data(rows)
+                .build());
+        System.out.printf("%d rows inserted\n", insertR.getInsertCnt());
+
+        // get row count
+        QueryResp countR = client.query(QueryReq.builder()
+                .collectionName(collectionName)
+                .filter("")
+                .outputFields(Collections.singletonList("count(*)"))
+                .consistencyLevel(ConsistencyLevel.STRONG)
+                .build());
+        System.out.printf("%d rows persisted\n", (long)countR.getQueryResults().get(0).getEntity().get("count(*)"));
+
+        // retrieve
+        List<Object> ids = Arrays.asList(1L, 50L);
+        GetResp getR = client.get(GetReq.builder()
+                .collectionName(collectionName)
+                .ids(ids)
+                .outputFields(Collections.singletonList("*"))
+                .build());
+        System.out.println("\nRetrieve results:");
+        for (QueryResp.QueryResult result : getR.getGetResults()) {
+            System.out.println(result.getEntity());
+        }
+
+        // search
+        SearchResp searchR = client.search(SearchReq.builder()
+                .collectionName(collectionName)
+                .data(Collections.singletonList(new FloatVec(new float[]{1.0f, 1.0f, 1.0f, 1.0f})))
+                .filter("id < 100")
+                .topK(10)
+                .outputFields(Collections.singletonList("*"))
+                .build());
+        List<List<SearchResp.SearchResult>> searchResults = searchR.getSearchResults();
+        System.out.println("\nSearch results:");
+        for (List<SearchResp.SearchResult> results : searchResults) {
+            for (SearchResp.SearchResult result : results) {
+                System.out.printf("ID: %d, Distance: %f, %s\n", (long)result.getId(), result.getDistance(), result.getEntity().toString());
+            }
+        }
+    }
+}

+ 0 - 0
examples/main/java/io/milvus/tls/gen.sh → examples/main/resources/tls/gen.sh


+ 0 - 0
examples/main/java/io/milvus/tls/openssl.cnf → examples/main/resources/tls/openssl.cnf


+ 0 - 115
src/main/java/io/milvus/v2/examples/Simple.java

@@ -1,115 +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 io.milvus.v2.examples;
-
-import com.google.gson.*;
-import com.google.gson.reflect.TypeToken;
-import io.milvus.v2.client.ConnectConfig;
-import io.milvus.v2.client.MilvusClientV2;
-import io.milvus.v2.exception.MilvusClientException;
-import io.milvus.v2.service.collection.request.CreateCollectionReq;
-import io.milvus.v2.service.collection.request.DescribeCollectionReq;
-import io.milvus.v2.service.collection.request.DropCollectionReq;
-import io.milvus.v2.service.collection.request.HasCollectionReq;
-import io.milvus.v2.service.vector.request.InsertReq;
-import io.milvus.v2.service.vector.request.QueryReq;
-import io.milvus.v2.service.vector.request.SearchReq;
-import io.milvus.v2.service.vector.request.data.FloatVec;
-import io.milvus.v2.service.vector.response.QueryResp;
-import io.milvus.v2.service.vector.response.SearchResp;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Random;
-
-public class Simple {
-    Integer dim = 2;
-    String collectionName = "book";
-    static Logger logger = LoggerFactory.getLogger(Simple.class);
-    public static void main(String[] args) {
-        try {
-            new Simple().run();
-        } catch (MilvusClientException | InterruptedException e) {
-            logger.info(e.toString());
-        }
-    }
-
-    public void run() throws InterruptedException {
-        ConnectConfig connectConfig = ConnectConfig.builder()
-                .uri("https://in01-***.aws-us-west-2.vectordb.zillizcloud.com:19531")
-                .token("***")
-                .build();
-        MilvusClientV2 client = new MilvusClientV2(connectConfig);
-        // check collection exists
-        if (client.hasCollection(HasCollectionReq.builder().collectionName(collectionName).build())) {
-            logger.info("collection exists");
-            client.dropCollection(DropCollectionReq.builder().collectionName(collectionName).build());
-            logger.info("collection dropped");
-        }
-        // create collection
-        CreateCollectionReq createCollectionReq = CreateCollectionReq.builder()
-                .collectionName(collectionName)
-                .description("simple collection")
-                .dimension(dim)
-                .build();
-        client.createCollection(createCollectionReq);
-
-        logger.info(String.valueOf(client.listCollections()));
-        logger.info(String.valueOf(client.describeCollection(DescribeCollectionReq.builder().collectionName(collectionName).build())));
-        //insert data
-        List<JsonObject> insertData = new ArrayList<>();
-        Gson gson = new Gson();
-        for(int i = 0; i < 6; i++){
-            JsonObject jsonObject = new JsonObject();
-            List<Float> vectorList = new ArrayList<>();
-            for(int j = 0; j < dim; j++){
-                // generate random float vector
-                vectorList.add(new Random().nextFloat());
-            }
-            jsonObject.addProperty("id", (long) i);
-            jsonObject.add("vector", gson.toJsonTree(vectorList).getAsJsonArray());
-            insertData.add(jsonObject);
-        }
-        InsertReq insertReq = InsertReq.builder()
-                .collectionName(collectionName)
-                .data(insertData)
-                .build();
-        client.insert(insertReq);
-        //query data
-        QueryReq queryReq = QueryReq.builder()
-                .collectionName(collectionName)
-                .filter("id in [0]")
-                .build();
-        QueryResp queryResp = client.query(queryReq);
-        System.out.println(queryResp);
-        //search data
-        List<Float> vector = new Gson().fromJson(insertData.get(0).get("vector"), new TypeToken<List<Float>>() {}.getType());
-        SearchReq searchReq = SearchReq.builder()
-                .collectionName(collectionName)
-                .data(Collections.singletonList(new FloatVec(vector)))
-                .topK(10)
-                .build();
-        SearchResp searchResp = client.search(searchReq);
-        System.out.println(searchResp);
-    }
-}

+ 0 - 136
src/main/java/io/milvus/v2/examples/Simple_Schema.java

@@ -1,136 +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 io.milvus.v2.examples;
-
-import com.google.gson.*;
-import com.google.gson.reflect.TypeToken;
-import io.milvus.v2.client.ConnectConfig;
-import io.milvus.v2.client.MilvusClientV2;
-import io.milvus.v2.common.DataType;
-import io.milvus.v2.common.IndexParam;
-import io.milvus.v2.service.collection.request.*;
-import io.milvus.v2.service.index.request.CreateIndexReq;
-import io.milvus.v2.service.vector.request.InsertReq;
-import io.milvus.v2.service.vector.request.QueryReq;
-import io.milvus.v2.service.vector.request.SearchReq;
-import io.milvus.v2.service.vector.request.data.FloatVec;
-import io.milvus.v2.service.vector.response.QueryResp;
-import io.milvus.v2.service.vector.response.SearchResp;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
-
-public class Simple_Schema {
-    Integer dim = 2;
-    String collectionName = "book";
-    static Logger logger = LoggerFactory.getLogger(Simple_Schema.class);
-    public void run() throws InterruptedException {
-        ConnectConfig connectConfig = ConnectConfig.builder()
-                .uri("https://in01-***.aws-us-west-2.vectordb.zillizcloud.com:19531")
-                .token("***")
-                .build();
-        MilvusClientV2 client = new MilvusClientV2(connectConfig);
-        // check collection exists
-        if (client.hasCollection(HasCollectionReq.builder().collectionName(collectionName).build())) {
-            logger.info("collection exists");
-            client.dropCollection(DropCollectionReq.builder().collectionName(collectionName).build());
-        }
-        // create collection
-        CreateCollectionReq.CollectionSchema collectionSchema = client.createSchema();
-        collectionSchema.addField(AddFieldReq.builder().fieldName("id").dataType(DataType.Int64).isPrimaryKey(Boolean.TRUE).autoID(Boolean.FALSE).description("id").build());
-        collectionSchema.addField(AddFieldReq.builder().fieldName("vector").dataType(DataType.FloatVector).dimension(dim).build());
-        collectionSchema.addField(AddFieldReq.builder().fieldName("num").dataType(DataType.Int64).isPartitionKey(Boolean.TRUE).build());
-        collectionSchema.addField(AddFieldReq.builder().fieldName("array").dataType(DataType.Array).elementType(DataType.Int32).maxCapacity(10).description("array").build());
-
-        CreateCollectionReq createCollectionReq = CreateCollectionReq.builder()
-                .collectionName(collectionName)
-                .description("simple collection")
-                .collectionSchema(collectionSchema)
-                .enableDynamicField(Boolean.FALSE)
-                .build();
-        client.createCollection(createCollectionReq);
-        //create index
-        IndexParam indexParam = IndexParam.builder()
-                .fieldName("vector")
-                .metricType(IndexParam.MetricType.COSINE)
-                .build();
-        CreateIndexReq createIndexReq = CreateIndexReq.builder()
-                .collectionName(collectionName)
-                .indexParams(Collections.singletonList(indexParam))
-                .build();
-        client.createIndex(createIndexReq);
-        TimeUnit.SECONDS.sleep(1);
-        client.loadCollection(LoadCollectionReq.builder().collectionName(collectionName).build());
-        //insert data
-        List<JsonObject> insertData = new ArrayList<>();
-        Gson gson = new Gson();
-        for(int i = 0; i < 6; i++){
-            JsonObject jsonObject = new JsonObject();
-            List<Float> vectorList = new ArrayList<>();
-            for(int j = 0; j < dim; j++){
-                // generate random float vector
-                vectorList.add(new Random().nextFloat());
-            }
-            List<Integer> array = new ArrayList<>();
-            array.add(i);
-            jsonObject.addProperty("id", (long) i);
-            jsonObject.add("vector", gson.toJsonTree(vectorList).getAsJsonArray());
-            jsonObject.addProperty("num", (long) i);
-            jsonObject.add("array", gson.toJsonTree(array).getAsJsonArray());
-            insertData.add(jsonObject);
-        }
-
-        InsertReq insertReq = InsertReq.builder()
-                .collectionName(collectionName)
-                .data(insertData)
-                .build();
-        client.insert(insertReq);
-        //query data
-        QueryReq queryReq = QueryReq.builder()
-                .collectionName(collectionName)
-                .filter("id in [0]")
-                .build();
-        QueryResp queryResp = client.query(queryReq);
-        queryResp.getQueryResults().get(0).getEntity().get("vector");
-        System.out.println(queryResp);
-        //search data
-        List<Float> vector = new Gson().fromJson(insertData.get(0).get("vector"), new TypeToken<List<Float>>() {}.getType());
-        SearchReq searchReq = SearchReq.builder()
-                .collectionName(collectionName)
-                .data(Collections.singletonList(new FloatVec(vector)))
-                .outputFields(Collections.singletonList("vector"))
-                .topK(10)
-                .build();
-        SearchResp searchResp = client.search(searchReq);
-        System.out.println(searchResp);
-    }
-    public static void main(String[] args) {
-        try {
-            new Simple_Schema().run();
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-        }
-    }
-}

+ 7 - 2
src/main/java/io/milvus/v2/service/collection/CollectionService.java

@@ -43,6 +43,11 @@ public class CollectionService extends BaseService {
             createCollectionWithSchema(blockingStub, request);
             return;
         }
+
+        if (request.getDimension() == null) {
+            throw new MilvusClientException(ErrorCode.INVALID_PARAMS, "Dimension is undefined.");
+        }
+
         String title = String.format("CreateCollectionRequest collectionName:%s", request.getCollectionName());
         FieldSchema vectorSchema = FieldSchema.newBuilder()
                 .setName(request.getVectorFieldName())
@@ -172,12 +177,12 @@ public class CollectionService extends BaseService {
     }
 
     public DescribeCollectionResp describeCollection(MilvusServiceGrpc.MilvusServiceBlockingStub milvusServiceBlockingStub, DescribeCollectionReq request) {
-
+        String title = String.format("DescribeCollectionRequest collectionName:%s", request.getCollectionName());
         DescribeCollectionRequest describeCollectionRequest = DescribeCollectionRequest.newBuilder()
                 .setCollectionName(request.getCollectionName())
                 .build();
         DescribeCollectionResponse response = milvusServiceBlockingStub.describeCollection(describeCollectionRequest);
-
+        rpcUtils.handleResponse(title, response.getStatus());
         DescribeCollectionResp describeCollectionResp = DescribeCollectionResp.builder()
                 .collectionName(response.getCollectionName())
                 .description(response.getSchema().getDescription())

+ 3 - 0
src/main/java/io/milvus/v2/service/index/response/DescribeIndexResp.java

@@ -22,6 +22,8 @@ package io.milvus.v2.service.index.response;
 import lombok.Data;
 import lombok.experimental.SuperBuilder;
 
+import java.util.Map;
+
 @Data
 @SuperBuilder
 public class DescribeIndexResp {
@@ -29,4 +31,5 @@ public class DescribeIndexResp {
     private String indexType;
     private String metricType;
     private String fieldName;
+    private Map<String, Object> extraParams;
 }

+ 3 - 0
src/main/java/io/milvus/v2/service/vector/request/data/BFloat16Vec.java

@@ -29,6 +29,9 @@ public class BFloat16Vec implements BaseVector {
     public BFloat16Vec(ByteBuffer data) {
         this.data = data;
     }
+    public BFloat16Vec(byte[] data) {
+        this.data = ByteBuffer.wrap(data);
+    }
 
     @Override
     public PlaceholderType getPlaceholderType() {

+ 3 - 1
src/main/java/io/milvus/v2/service/vector/request/data/BinaryVec.java

@@ -29,7 +29,9 @@ public class BinaryVec implements BaseVector {
     public BinaryVec(ByteBuffer data) {
         this.data = data;
     }
-
+    public BinaryVec(byte[] data) {
+        this.data = ByteBuffer.wrap(data);
+    }
     @Override
     public PlaceholderType getPlaceholderType() {
         return PlaceholderType.BinaryVector;

+ 3 - 1
src/main/java/io/milvus/v2/service/vector/request/data/Float16Vec.java

@@ -29,7 +29,9 @@ public class Float16Vec implements BaseVector {
     public Float16Vec(ByteBuffer data) {
         this.data = data;
     }
-
+    public Float16Vec(byte[] data) {
+        this.data = ByteBuffer.wrap(data);
+    }
     @Override
     public PlaceholderType getPlaceholderType() {
         return PlaceholderType.Float16Vector;

+ 8 - 0
src/main/java/io/milvus/v2/service/vector/request/data/FloatVec.java

@@ -21,6 +21,8 @@ package io.milvus.v2.service.vector.request.data;
 
 
 import io.milvus.grpc.PlaceholderType;
+
+import java.util.ArrayList;
 import java.util.List;
 
 public class FloatVec implements BaseVector {
@@ -29,6 +31,12 @@ public class FloatVec implements BaseVector {
     public FloatVec(List<Float> data) {
         this.data = data;
     }
+    public FloatVec(float[] data) {
+        this.data = new ArrayList<>();
+        for (float f : data) {
+            this.data.add(f);
+        }
+    }
 
     @Override
     public PlaceholderType getPlaceholderType() {

+ 5 - 1
src/main/java/io/milvus/v2/utils/ConvertUtils.java

@@ -77,14 +77,18 @@ public class ConvertUtils {
                 .indexName(response.getIndexName())
                 .fieldName(response.getFieldName())
                 .build();
+        Map<String, Object> extraParams = new HashMap<>();
         List<KeyValuePair> params = response.getParamsList();
         for(KeyValuePair param : params) {
             if (param.getKey().equals("index_type")) {
                 describeIndexResp.setIndexType(param.getValue());
-            }else if (param.getKey().equals("metric_type")) {
+            } else if (param.getKey().equals("metric_type")) {
                 describeIndexResp.setMetricType(param.getValue());
+            } else {
+                extraParams.put(param.getKey(), param.getValue());
             }
         }
+        describeIndexResp.setExtraParams(extraParams);
         return describeIndexResp;
     }
 }

+ 5 - 0
src/main/java/io/milvus/v2/utils/SchemaUtils.java

@@ -74,10 +74,15 @@ public class SchemaUtils {
                 .dataType(io.milvus.v2.common.DataType.valueOf(fieldSchema.getDataType().name()))
                 .isPrimaryKey(fieldSchema.getIsPrimaryKey())
                 .autoID(fieldSchema.getAutoID())
+                .elementType(io.milvus.v2.common.DataType.valueOf(fieldSchema.getElementType().name()))
                 .build();
         for (KeyValuePair keyValuePair : fieldSchema.getTypeParamsList()) {
             if(keyValuePair.getKey().equals("dim")){
                 schema.setDimension(Integer.parseInt(keyValuePair.getValue()));
+            } else if(keyValuePair.getKey().equals("max_length")){
+                schema.setMaxLength(Integer.parseInt(keyValuePair.getValue()));
+            } else if(keyValuePair.getKey().equals("max_capacity")){
+                schema.setMaxCapacity(Integer.parseInt(keyValuePair.getValue()));
             }
         }
         return schema;

+ 339 - 39
src/test/java/io/milvus/v2/client/MilvusClientV2DockerTest.java

@@ -25,10 +25,17 @@ import com.google.gson.reflect.TypeToken;
 import io.milvus.v2.common.ConsistencyLevel;
 import io.milvus.v2.common.DataType;
 import io.milvus.v2.common.IndexParam;
-import io.milvus.v2.service.collection.request.AddFieldReq;
-import io.milvus.v2.service.collection.request.CreateCollectionReq;
-import io.milvus.v2.service.collection.request.DropCollectionReq;
-import io.milvus.v2.service.partition.request.CreatePartitionReq;
+import io.milvus.v2.exception.MilvusClientException;
+import io.milvus.v2.service.collection.request.*;
+import io.milvus.v2.service.collection.response.DescribeCollectionResp;
+import io.milvus.v2.service.index.request.CreateIndexReq;
+import io.milvus.v2.service.index.request.DescribeIndexReq;
+import io.milvus.v2.service.index.request.DropIndexReq;
+import io.milvus.v2.service.index.response.DescribeIndexResp;
+import io.milvus.v2.service.partition.request.*;
+import io.milvus.v2.service.utility.request.AlterAliasReq;
+import io.milvus.v2.service.utility.request.CreateAliasReq;
+import io.milvus.v2.service.utility.request.DropAliasReq;
 import io.milvus.v2.service.vector.request.*;
 import io.milvus.v2.service.vector.request.data.*;
 import io.milvus.v2.service.vector.request.ranker.*;
@@ -293,6 +300,7 @@ class MilvusClientV2DockerTest {
                     case JSON: {
                         JsonObject jsonObj = new JsonObject();
                         jsonObj.addProperty(String.format("JSON_%d", i), i);
+                        jsonObj.add("flags", GSON_INSTANCE.toJsonTree(new long[]{i, i+1, i + 2}));
                         row.add(field.getName(), jsonObj);
                         break;
                     }
@@ -357,6 +365,18 @@ class MilvusClientV2DockerTest {
         Assertions.assertEquals(arrStrOri, arrStr);
     }
 
+    private long getRowCount(String collectionName) {
+        QueryResp queryResp = client.query(QueryReq.builder()
+                .collectionName(collectionName)
+                .filter("")
+                .outputFields(Collections.singletonList("count(*)"))
+                .consistencyLevel(ConsistencyLevel.STRONG)
+                .build());
+        List<QueryResp.QueryResult> queryResults = queryResp.getQueryResults();
+        Assertions.assertEquals(1, queryResults.size());
+        return (long)queryResults.get(0).getEntity().get("count(*)");
+    }
+
 
     @Test
     void testFloatVectors() {
@@ -382,6 +402,7 @@ class MilvusClientV2DockerTest {
 
         CreateCollectionReq requestCreate = CreateCollectionReq.builder()
                 .collectionName(randomCollectionName)
+                .description("dummy")
                 .collectionSchema(collectionSchema)
                 .indexParams(Collections.singletonList(indexParam))
                 .build();
@@ -413,15 +434,41 @@ class MilvusClientV2DockerTest {
         Assertions.assertEquals(1, upsertResp.getUpsertCnt());
 
         // get row count
-        QueryResp queryResp = client.query(QueryReq.builder()
+        long rowCount = getRowCount(randomCollectionName);
+        Assertions.assertEquals(count + 1, rowCount);
+
+        // describe collection
+        DescribeCollectionResp descResp = client.describeCollection(DescribeCollectionReq.builder()
                 .collectionName(randomCollectionName)
-                .filter("")
-                .outputFields(Collections.singletonList("count(*)"))
-                .consistencyLevel(ConsistencyLevel.STRONG)
                 .build());
-        List<QueryResp.QueryResult> queryResults = queryResp.getQueryResults();
-        Assertions.assertEquals(1, queryResults.size());
-        Assertions.assertEquals(count + 1, queryResults.get(0).getEntity().get("count(*)"));
+        Assertions.assertEquals(randomCollectionName, descResp.getCollectionName());
+        Assertions.assertEquals("dummy", descResp.getDescription());
+        Assertions.assertEquals(2, descResp.getNumOfPartitions());
+        Assertions.assertEquals(1, descResp.getVectorFieldName().size());
+        Assertions.assertEquals("id", descResp.getPrimaryFieldName());
+        Assertions.assertTrue(descResp.getEnableDynamicField());
+        Assertions.assertFalse(descResp.getAutoID());
+
+        List<String> fieldNames = descResp.getFieldNames();
+        Assertions.assertEquals(collectionSchema.getFieldSchemaList().size(), fieldNames.size());
+        CreateCollectionReq.CollectionSchema schema = descResp.getCollectionSchema();
+        for (String name : fieldNames) {
+            CreateCollectionReq.FieldSchema f1 = collectionSchema.getField(name);
+            CreateCollectionReq.FieldSchema f2 = schema.getField(name);
+            Assertions.assertNotNull(f1);
+            Assertions.assertNotNull(f2);
+            Assertions.assertEquals(f1.getName(), f2.getName());
+            Assertions.assertEquals(f1.getDescription(), f2.getDescription());
+            Assertions.assertEquals(f1.getDataType(), f2.getDataType());
+            Assertions.assertEquals(f1.getDimension(), f2.getDimension());
+            Assertions.assertEquals(f1.getMaxLength(), f2.getMaxLength());
+            Assertions.assertEquals(f1.getIsPrimaryKey(), f2.getIsPrimaryKey());
+            Assertions.assertEquals(f1.getIsPartitionKey(), f2.getIsPartitionKey());
+            if (f1.getDataType() == io.milvus.v2.common.DataType.Array) {
+                Assertions.assertEquals(f1.getElementType(), f2.getElementType());
+                Assertions.assertEquals(f1.getMaxCapacity(), f2.getMaxCapacity());
+            }
+        }
 
         // search in partition
         SearchResp searchResp = client.search(SearchReq.builder()
@@ -491,6 +538,14 @@ class MilvusClientV2DockerTest {
             verifyOutput(row, entity);
         }
 
+        // query
+        QueryResp queryResp = client.query(QueryReq.builder()
+                .collectionName(randomCollectionName)
+                .filter("JSON_CONTAINS_ANY(json_field[\"flags\"], [4, 100])")
+                .build());
+        List<QueryResp.QueryResult> queryResults = queryResp.getQueryResults();
+        Assertions.assertEquals(6, queryResults.size());
+
         client.dropCollection(DropCollectionReq.builder().collectionName(randomCollectionName).build());
     }
 
@@ -532,15 +587,8 @@ class MilvusClientV2DockerTest {
         Assertions.assertEquals(count, insertResp.getInsertCnt());
 
         // get row count
-        QueryResp queryResp = client.query(QueryReq.builder()
-                .collectionName(randomCollectionName)
-                .filter("")
-                .outputFields(Collections.singletonList("count(*)"))
-                .consistencyLevel(ConsistencyLevel.STRONG)
-                .build());
-        List<QueryResp.QueryResult> queryResults = queryResp.getQueryResults();
-        Assertions.assertEquals(1, queryResults.size());
-        Assertions.assertEquals(count, queryResults.get(0).getEntity().get("count(*)"));
+        long rowCount = getRowCount(randomCollectionName);
+        Assertions.assertEquals(count, rowCount);
 
         // search in collection
         int nq = 5;
@@ -551,7 +599,7 @@ class MilvusClientV2DockerTest {
             JsonObject row = data.get(RANDOM.nextInt((int)count));
             targetIDs.add(row.get("id").getAsLong());
             byte[] vector = GSON_INSTANCE.fromJson(row.get(vectorFieldName), new TypeToken<byte[]>() {}.getType());
-            targetVectors.add(new BinaryVec(ByteBuffer.wrap(vector)));
+            targetVectors.add(new BinaryVec(vector));
         }
         SearchResp searchResp = client.search(SearchReq.builder()
                 .collectionName(randomCollectionName)
@@ -608,15 +656,8 @@ class MilvusClientV2DockerTest {
         Assertions.assertEquals(count, insertResp.getInsertCnt());
 
         // get row count
-        QueryResp queryResp = client.query(QueryReq.builder()
-                .collectionName(randomCollectionName)
-                .filter("")
-                .outputFields(Collections.singletonList("count(*)"))
-                .consistencyLevel(ConsistencyLevel.STRONG)
-                .build());
-        List<QueryResp.QueryResult> queryResults = queryResp.getQueryResults();
-        Assertions.assertEquals(1, queryResults.size());
-        Assertions.assertEquals(count, queryResults.get(0).getEntity().get("count(*)"));
+        long rowCount = getRowCount(randomCollectionName);
+        Assertions.assertEquals(count, rowCount);
 
         // search in collection
         int nq = 5;
@@ -702,15 +743,8 @@ class MilvusClientV2DockerTest {
         Assertions.assertEquals(count, insertResp.getInsertCnt());
 
         // get row count
-        QueryResp queryResp = client.query(QueryReq.builder()
-                .collectionName(randomCollectionName)
-                .filter("")
-                .outputFields(Collections.singletonList("count(*)"))
-                .consistencyLevel(ConsistencyLevel.STRONG)
-                .build());
-        List<QueryResp.QueryResult> queryResults = queryResp.getQueryResults();
-        Assertions.assertEquals(1, queryResults.size());
-        Assertions.assertEquals(count, queryResults.get(0).getEntity().get("count(*)"));
+        long rowCount = getRowCount(randomCollectionName);
+        Assertions.assertEquals(count, rowCount);
 
         // hybrid search in collection
         int nq = 5;
@@ -759,4 +793,270 @@ class MilvusClientV2DockerTest {
 
         client.dropCollection(DropCollectionReq.builder().collectionName(randomCollectionName).build());
     }
+
+    @Test
+    void testDeleteUpsert() {
+        String randomCollectionName = generator.generate(10);
+
+        CreateCollectionReq.CollectionSchema collectionSchema = CreateCollectionReq.CollectionSchema.builder()
+                .build();
+        collectionSchema.addField(AddFieldReq.builder()
+                .fieldName("pk")
+                .dataType(DataType.VarChar)
+                .isPrimaryKey(Boolean.TRUE)
+                .build());
+        collectionSchema.addField(AddFieldReq.builder()
+                .fieldName("float_vector")
+                .dataType(DataType.FloatVector)
+                .dimension(4)
+                .build());
+
+        List<IndexParam> indexParams = new ArrayList<>();
+        indexParams.add(IndexParam.builder()
+                .fieldName("float_vector")
+                .indexType(IndexParam.IndexType.IVF_FLAT)
+                .metricType(IndexParam.MetricType.L2)
+                .extraParams(new HashMap<String,Object>(){{put("nlist", 64);}})
+                .build());
+        CreateCollectionReq requestCreate = CreateCollectionReq.builder()
+                .collectionName(randomCollectionName)
+                .collectionSchema(collectionSchema)
+                .indexParams(indexParams)
+                .build();
+        client.createCollection(requestCreate);
+
+        // insert
+        List<JsonObject> data = new ArrayList<>();
+        Gson gson = new Gson();
+        for (int i = 0; i < 10; i++) {
+            JsonObject row = new JsonObject();
+            row.addProperty("pk", String.format("pk_%d", i));
+            row.add("float_vector", gson.toJsonTree(new float[]{(float)i, (float)(i + 1), (float)(i + 2), (float)(i + 3)}));
+            data.add(row);
+        }
+
+        InsertResp insertResp = client.insert(InsertReq.builder()
+                .collectionName(randomCollectionName)
+                .data(data)
+                .build());
+        Assertions.assertEquals(10, insertResp.getInsertCnt());
+
+        // delete
+        DeleteResp deleteResp = client.delete(DeleteReq.builder()
+                .collectionName(randomCollectionName)
+                .ids(Arrays.asList("pk_5", "pk_8"))
+                .build());
+        Assertions.assertEquals(2, deleteResp.getDeleteCnt());
+
+        // get row count
+        long rowCount = getRowCount(randomCollectionName);
+        Assertions.assertEquals(8L, rowCount);
+
+        // upsert
+        List<JsonObject> dataUpdate = new ArrayList<>();
+        JsonObject row1 = new JsonObject();
+        row1.addProperty("pk", "pk_5");
+        row1.add("float_vector", gson.toJsonTree(new float[]{5.0f, 5.0f, 5.0f, 5.0f}));
+        dataUpdate.add(row1);
+        JsonObject row2 = new JsonObject();
+        row2.addProperty("pk", "pk_2");
+        row2.add("float_vector", gson.toJsonTree(new float[]{2.0f, 2.0f, 2.0f, 2.0f}));
+        dataUpdate.add(row2);
+        UpsertResp upsertResp = client.upsert(UpsertReq.builder()
+                .collectionName(randomCollectionName)
+                .data(dataUpdate)
+                .build());
+        Assertions.assertEquals(2, upsertResp.getUpsertCnt());
+
+        // get row count
+        rowCount = getRowCount(randomCollectionName);
+        Assertions.assertEquals(9L, rowCount);
+
+        // verify
+        QueryResp queryResp = client.query(QueryReq.builder()
+                .collectionName(randomCollectionName)
+                .filter("pk == \"pk_2\" or pk == \"pk_5\"")
+                .outputFields(Collections.singletonList("*"))
+                .build());
+        List<QueryResp.QueryResult> queryResults = queryResp.getQueryResults();
+        Assertions.assertEquals(2, queryResults.size());
+
+        QueryResp.QueryResult result1 = queryResults.get(0);
+        Map<String, Object> entity1 = result1.getEntity();
+        Assertions.assertTrue(entity1.containsKey("pk"));
+        Assertions.assertEquals("pk_2", entity1.get("pk"));
+        Assertions.assertTrue(entity1.containsKey("float_vector"));
+        Assertions.assertTrue(entity1.get("float_vector") instanceof List);
+        List<Float> vector1 = (List<Float>) entity1.get("float_vector");
+        for (Float f : vector1) {
+            Assertions.assertEquals(2.0f, f);
+        }
+
+        QueryResp.QueryResult result2 = queryResults.get(1);
+        Map<String, Object> entity2 = result2.getEntity();
+        Assertions.assertTrue(entity2.containsKey("pk"));
+        Assertions.assertEquals("pk_5", entity2.get("pk"));
+        Assertions.assertTrue(entity2.containsKey("float_vector"));
+        Assertions.assertTrue(entity2.get("float_vector") instanceof List);
+        List<Float> vector2 = (List<Float>) entity2.get("float_vector");
+        for (Float f : vector2) {
+            Assertions.assertEquals(5.0f, f);
+        }
+
+        client.dropCollection(DropCollectionReq.builder().collectionName(randomCollectionName).build());
+    }
+
+    @Test
+    void testAlias() {
+        client.createCollection(CreateCollectionReq.builder()
+                .collectionName("AAA")
+                .description("desc_A")
+                .dimension(100)
+                .build());
+
+        client.createCollection(CreateCollectionReq.builder()
+                .collectionName("BBB")
+                .description("desc_B")
+                .dimension(50)
+                .build());
+
+        client.createAlias(CreateAliasReq.builder()
+                .collectionName("BBB")
+                .alias("CCC")
+                .build());
+
+        DescribeCollectionResp descResp = client.describeCollection(DescribeCollectionReq.builder()
+                .collectionName("CCC")
+                .build());
+        Assertions.assertEquals("desc_B", descResp.getDescription());
+
+        client.dropCollection(DropCollectionReq.builder()
+                .collectionName("BBB")
+                .build());
+
+        Assertions.assertThrows(MilvusClientException.class, ()->client.describeCollection(DescribeCollectionReq.builder()
+                .collectionName("CCC")
+                .build()));
+
+        client.alterAlias(AlterAliasReq.builder()
+                .collectionName("AAA")
+                .alias("CCC")
+                .build());
+
+        descResp = client.describeCollection(DescribeCollectionReq.builder()
+                .collectionName("CCC")
+                .build());
+        Assertions.assertEquals("desc_A", descResp.getDescription());
+
+        client.dropAlias(DropAliasReq.builder()
+                .alias("CCC")
+                .build());
+
+        Assertions.assertThrows(MilvusClientException.class, ()->client.describeCollection(DescribeCollectionReq.builder()
+                .collectionName("CCC")
+                .build()));
+    }
+
+    @Test
+    void testPartition() {
+        String randomCollectionName = generator.generate(10);
+        client.createCollection(CreateCollectionReq.builder()
+                .collectionName(randomCollectionName)
+                .dimension(4)
+                .build());
+
+        client.createPartition(CreatePartitionReq.builder()
+                .collectionName(randomCollectionName)
+                .partitionName("P1")
+                .build());
+
+        client.createPartition(CreatePartitionReq.builder()
+                .collectionName(randomCollectionName)
+                .partitionName("P2")
+                .build());
+
+        List<String> partitions = client.listPartitions(ListPartitionsReq.builder()
+                .collectionName(randomCollectionName)
+                .build());
+        Assertions.assertEquals(3, partitions.size());
+        Assertions.assertTrue(partitions.contains("P1"));
+        Assertions.assertTrue(partitions.contains("P2"));
+        Assertions.assertTrue(partitions.contains("_default"));
+
+        Boolean has = client.hasPartition(HasPartitionReq.builder()
+                .collectionName(randomCollectionName)
+                .partitionName("P1")
+                .build());
+        Assertions.assertTrue(has);
+
+        client.releasePartitions(ReleasePartitionsReq.builder()
+                .collectionName(randomCollectionName)
+                .partitionNames(Collections.singletonList("P1"))
+                .build());
+
+        client.dropPartition(DropPartitionReq.builder()
+                .collectionName(randomCollectionName)
+                .partitionName("P1")
+                .build());
+
+        has = client.hasPartition(HasPartitionReq.builder()
+                .collectionName(randomCollectionName)
+                .partitionName("P1")
+                .build());
+        Assertions.assertFalse(has);
+
+        partitions = client.listPartitions(ListPartitionsReq.builder()
+                .collectionName(randomCollectionName)
+                .build());
+        Assertions.assertEquals(2, partitions.size());
+        Assertions.assertFalse(partitions.contains("P1"));
+    }
+
+    @Test
+    void testIndex() {
+        String randomCollectionName = generator.generate(10);
+        client.createCollection(CreateCollectionReq.builder()
+                .collectionName(randomCollectionName)
+                .dimension(dimension)
+                .build());
+
+        client.releaseCollection(ReleaseCollectionReq.builder()
+                .collectionName(randomCollectionName)
+                .build());
+
+        DescribeIndexResp descResp = client.describeIndex(DescribeIndexReq.builder()
+                .collectionName(randomCollectionName)
+                .fieldName("vector")
+                .build());
+        Assertions.assertEquals(IndexParam.IndexType.AUTOINDEX.name(), descResp.getIndexType());
+
+        client.dropIndex(DropIndexReq.builder()
+                .collectionName(randomCollectionName)
+                .fieldName("vector")
+                .build());
+
+        IndexParam param = IndexParam.builder()
+                .fieldName("vector")
+                .indexName("XXX")
+                .indexType(IndexParam.IndexType.IVF_FLAT)
+                .metricType(IndexParam.MetricType.COSINE)
+                .extraParams(new HashMap<String,Object>(){{put("nlist", 64);}})
+                .build();
+
+        client.createIndex(CreateIndexReq.builder()
+                .collectionName(randomCollectionName)
+                .indexParams(Collections.singletonList(param))
+                .build());
+
+        descResp = client.describeIndex(DescribeIndexReq.builder()
+                .collectionName(randomCollectionName)
+                .fieldName("vector")
+                .build());
+        Assertions.assertEquals("XXX", descResp.getIndexName());
+        Assertions.assertEquals(IndexParam.IndexType.IVF_FLAT.name(), descResp.getIndexType());
+        Assertions.assertEquals(IndexParam.MetricType.COSINE.name(), descResp.getMetricType());
+        Map<String, Object> extraParams = descResp.getExtraParams();
+        Assertions.assertTrue(extraParams.containsKey("nlist"));
+        Assertions.assertEquals("64", extraParams.get("nlist"));
+    }
 }