Browse Source

Change master branch to Milvus 2.0, bring in protos (#190)

Xiaofan 3 years ago
parent
commit
d3c6402652
32 changed files with 737 additions and 5080 deletions
  1. 0 213
      examples/src/main/java/MilvusClientExample.java
  2. 11 35
      pom.xml
  3. 0 108
      src/main/java/io/milvus/client/CollectionMapping.java
  4. 0 28
      src/main/java/io/milvus/client/ConnectFailedException.java
  5. 0 204
      src/main/java/io/milvus/client/ConnectParam.java
  6. 0 54
      src/main/java/io/milvus/client/CountEntitiesResponse.java
  7. 0 64
      src/main/java/io/milvus/client/GetCollectionInfoResponse.java
  8. 0 41
      src/main/java/io/milvus/client/GetEntityByIDResponse.java
  9. 0 61
      src/main/java/io/milvus/client/GetIndexInfoResponse.java
  10. 0 53
      src/main/java/io/milvus/client/HasCollectionResponse.java
  11. 0 53
      src/main/java/io/milvus/client/HasPartitionResponse.java
  12. 0 118
      src/main/java/io/milvus/client/Index.java
  13. 0 58
      src/main/java/io/milvus/client/IndexType.java
  14. 0 132
      src/main/java/io/milvus/client/InsertParam.java
  15. 0 54
      src/main/java/io/milvus/client/InsertResponse.java
  16. 0 57
      src/main/java/io/milvus/client/ListCollectionsResponse.java
  17. 0 30
      src/main/java/io/milvus/client/ListIDInSegmentResponse.java
  18. 0 51
      src/main/java/io/milvus/client/ListPartitionsResponse.java
  19. 0 64
      src/main/java/io/milvus/client/MetricType.java
  20. 0 487
      src/main/java/io/milvus/client/MilvusClient.java
  21. 0 1400
      src/main/java/io/milvus/client/MilvusGrpcClient.java
  22. 0 115
      src/main/java/io/milvus/client/Response.java
  23. 0 170
      src/main/java/io/milvus/client/SearchParam.java
  24. 0 137
      src/main/java/io/milvus/client/SearchResponse.java
  25. 0 16
      src/main/java/io/milvus/client/exception/InitializationException.java
  26. 0 24
      src/main/java/io/milvus/client/exception/MilvusException.java
  27. 0 22
      src/main/java/io/milvus/client/exception/UnsupportedServerVersion.java
  28. 161 0
      src/main/proto/common.proto
  29. 437 405
      src/main/proto/milvus.proto
  30. 128 0
      src/main/proto/schema.proto
  31. 0 39
      src/main/proto/status.proto
  32. 0 787
      src/test/java/io/milvus/client/MilvusGrpcClientTest.java

+ 0 - 213
examples/src/main/java/MilvusClientExample.java

@@ -1,213 +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.
- */
-
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.gson.JsonObject;
-import io.milvus.client.*;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.SplittableRandom;
-import java.util.concurrent.ExecutionException;
-import java.util.stream.Collectors;
-import java.util.stream.DoubleStream;
-
-// This is a simple example demonstrating how to use Milvus Java SDK.
-// For detailed API document, please refer to
-// https://milvus-io.github.io/milvus-sdk-java/javadoc/io/milvus/client/package-summary.html
-// You can also find more information on https://milvus.io/
-public class MilvusClientExample {
-
-  // Helper function that generates random vectors
-  static List<List<Float>> generateVectors(int vectorCount, int dimension) {
-    SplittableRandom splitcollectionRandom = new SplittableRandom();
-    List<List<Float>> vectors = new ArrayList<>(vectorCount);
-    for (int i = 0; i < vectorCount; ++i) {
-      splitcollectionRandom = splitcollectionRandom.split();
-      DoubleStream doubleStream = splitcollectionRandom.doubles(dimension);
-      List<Float> vector =
-          doubleStream.boxed().map(Double::floatValue).collect(Collectors.toList());
-      vectors.add(vector);
-    }
-    return vectors;
-  }
-
-  // Helper function that normalizes a vector if you are using IP (Inner Product) as your metric
-  // type
-  static List<Float> normalizeVector(List<Float> vector) {
-    float squareSum = vector.stream().map(x -> x * x).reduce((float) 0, Float::sum);
-    final float norm = (float) Math.sqrt(squareSum);
-    vector = vector.stream().map(x -> x / norm).collect(Collectors.toList());
-    return vector;
-  }
-
-  public static void main(String[] args) throws InterruptedException {
-
-    // You may need to change the following to the host and port of your Milvus server
-    String host = "localhost";
-    int port = 19530;
-    if (args.length >= 2) {
-      host = args[0];
-      port = Integer.parseInt(args[1]);
-    }
-
-    ConnectParam connectParam = new ConnectParam.Builder().withHost(host).withPort(port).build();
-    MilvusClient client = new MilvusGrpcClient(connectParam);
-
-    // Create a collection with the following collection mapping
-    final String collectionName = "example"; // collection name
-    final int dimension = 128; // dimension of each vector
-    final int indexFileSize = 1024; // maximum size (in MB) of each index file
-    final MetricType metricType = MetricType.IP; // we choose IP (Inner Product) as our metric type
-    CollectionMapping collectionMapping =
-        new CollectionMapping.Builder(collectionName, dimension)
-            .withIndexFileSize(indexFileSize)
-            .withMetricType(metricType)
-            .build();
-    Response createCollectionResponse = client.createCollection(collectionMapping);
-
-    // Check whether the collection exists
-    HasCollectionResponse hasCollectionResponse = client.hasCollection(collectionName);
-
-    // Get collection info
-    GetCollectionInfoResponse getCollectionInfoResponse = client.getCollectionInfo(collectionName);
-
-    // Insert randomly generated vectors to collection
-    final int vectorCount = 100000;
-    List<List<Float>> vectors = generateVectors(vectorCount, dimension);
-    vectors =
-        vectors.stream().map(MilvusClientExample::normalizeVector).collect(Collectors.toList());
-    InsertParam insertParam =
-        new InsertParam.Builder(collectionName).withFloatVectors(vectors).build();
-    InsertResponse insertResponse = client.insert(insertParam);
-    // Insert returns a list of vector ids that you will be using (if you did not supply them
-    // yourself) to reference the vectors you just inserted
-    List<Long> vectorIds = insertResponse.getVectorIds();
-
-    // Flush data in collection
-    Response flushResponse = client.flush(collectionName);
-
-    // Get current entity count of collection
-    CountEntitiesResponse ountEntitiesResponse = client.countEntities(collectionName);
-
-    // Create index for the collection
-    // We choose IVF_SQ8 as our index type here. Refer to IndexType javadoc for a
-    // complete explanation of different index types
-    final IndexType indexType = IndexType.IVF_SQ8;
-    // Each index type has its optional parameters you can set. Refer to the Milvus documentation
-    // for how to set the optimal parameters based on your needs.
-    JsonObject indexParamsJson = new JsonObject();
-    indexParamsJson.addProperty("nlist", 16384);
-    Index index =
-        new Index.Builder(collectionName, indexType)
-            .withParamsInJson(indexParamsJson.toString())
-            .build();
-    Response createIndexResponse = client.createIndex(index);
-
-    // Get index info for your collection
-    GetIndexInfoResponse getIndexInfoResponse = client.getIndexInfo(collectionName);
-    System.out.format("Index Info: %s\n", getIndexInfoResponse.getIndex().get().toString());
-
-    // Get collection info
-    Response getCollectionStatsResponse = client.getCollectionStats(collectionName);
-    if (getCollectionStatsResponse.ok()) {
-      // Collection info is sent back with JSON type string
-      String jsonString = getCollectionStatsResponse.getMessage();
-      System.out.format("Collection Stats: %s\n", jsonString);
-    }
-
-    // Check whether a partition exists in collection
-    // Obviously we do not have partition "tag" now
-    HasPartitionResponse testHasPartition = client.hasPartition(collectionName, "tag");
-    if (testHasPartition.ok() && testHasPartition.hasPartition()) {
-      throw new AssertionError("Wrong results!");
-    }
-
-    // Search vectors
-    // Searching the first 5 vectors of the vectors we just inserted
-    final int searchBatchSize = 5;
-    List<List<Float>> vectorsToSearch = vectors.subList(0, searchBatchSize);
-    final long topK = 10;
-    // Based on the index you created, the available search parameters will be different. Refer to
-    // the Milvus documentation for how to set the optimal parameters based on your needs.
-    JsonObject searchParamsJson = new JsonObject();
-    searchParamsJson.addProperty("nprobe", 20);
-    SearchParam searchParam =
-        new SearchParam.Builder(collectionName)
-            .withFloatVectors(vectorsToSearch)
-            .withTopK(topK)
-            .withParamsInJson(searchParamsJson.toString())
-            .build();
-    SearchResponse searchResponse = client.search(searchParam);
-    if (searchResponse.ok()) {
-      List<List<SearchResponse.QueryResult>> queryResultsList =
-          searchResponse.getQueryResultsList();
-      final double epsilon = 0.001;
-      for (int i = 0; i < searchBatchSize; i++) {
-        // Since we are searching for vector that is already present in the collection,
-        // the first result vector should be itself and the distance (inner product) should be
-        // very close to 1 (some precision is lost during the process)
-        SearchResponse.QueryResult firstQueryResult = queryResultsList.get(i).get(0);
-        if (firstQueryResult.getVectorId() != vectorIds.get(i)
-            || Math.abs(1 - firstQueryResult.getDistance()) > epsilon) {
-          throw new AssertionError("Wrong results!");
-        }
-      }
-    }
-    // You can also get result ids and distances separately
-    List<List<Long>> resultIds = searchResponse.getResultIdsList();
-    List<List<Float>> resultDistances = searchResponse.getResultDistancesList();
-
-    // You can send search request asynchronously, which returns a ListenableFuture object
-    ListenableFuture<SearchResponse> searchResponseFuture = client.searchAsync(searchParam);
-    try {
-      // Get search response immediately. Obviously you will want to do more complicated stuff with
-      // ListenableFuture
-      searchResponseFuture.get();
-    } catch (ExecutionException e) {
-      e.printStackTrace();
-    }
-
-    // Delete the first 5 vectors you just searched
-    Response deleteByIdsResponse =
-        client.deleteEntityByID(collectionName, vectorIds.subList(0, searchBatchSize));
-    flushResponse = client.flush(collectionName);
-
-    // Try to get the corresponding vector of the first id you just deleted.
-    GetEntityByIDResponse getEntityByIDResponse =
-        client.getEntityByID(collectionName, vectorIds.subList(0, searchBatchSize));
-    // Obviously you won't get anything
-    if (!getEntityByIDResponse.getFloatVectors().get(0).isEmpty()) {
-      throw new AssertionError("This can never happen!");
-    }
-
-    // Compact the collection, erase deleted data from disk and rebuild index in background (if
-    // the data size after compaction is still larger than indexFileSize). Data was only
-    // soft-deleted until you call compact.
-    Response compactResponse = client.compact(collectionName);
-
-    // Drop index for the collection
-    Response dropIndexResponse = client.dropIndex(collectionName);
-
-    // Drop collection
-    Response dropCollectionResponse = client.dropCollection(collectionName);
-
-    // Disconnect from Milvus server
-    client.close();
-  }
-}

+ 11 - 35
pom.xml

@@ -25,7 +25,7 @@
 
     <groupId>io.milvus</groupId>
     <artifactId>milvus-sdk-java</artifactId>
-    <version>1.0.0</version>
+    <version>2.0.0</version>
     <packaging>jar</packaging>
 
     <name>io.milvus:milvus-sdk-java</name>
@@ -42,14 +42,8 @@
 
     <developers>
         <developer>
-            <name>Xiaohai Xu</name>
-            <email>xiaohai.xu@zilliz.com</email>
-            <organization>Milvus</organization>
-            <organizationUrl>http://www.milvus.io</organizationUrl>
-        </developer>
-        <developer>
-            <name>Zhiru Zhu</name>
-            <email>zhiru.zhu@zilliz.com</email>
+            <name>Xiaofan Luan</name>
+            <email>xiaofan.luan@zilliz.com</email>
             <organization>Milvus</organization>
             <organizationUrl>http://www.milvus.io</organizationUrl>
         </developer>
@@ -70,9 +64,9 @@
 
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <grpc.version>1.30.2</grpc.version>
-        <protobuf.version>3.11.0</protobuf.version>
-        <protoc.version>3.11.0</protoc.version>
+        <grpc.version>1.38.0</grpc.version>
+        <protobuf.version>3.12.0</protobuf.version>
+        <protoc.version>3.12.0</protoc.version>
         <maven.compiler.source>1.8</maven.compiler.source>
         <maven.compiler.target>1.8</maven.compiler.target>
     </properties>
@@ -98,18 +92,18 @@
         <dependency>
             <groupId>io.grpc</groupId>
             <artifactId>grpc-netty-shaded</artifactId>
-            <version>1.30.2</version>
+            <version>${grpc.version}</version>
             <scope>runtime</scope>
         </dependency>
         <dependency>
             <groupId>io.grpc</groupId>
             <artifactId>grpc-protobuf</artifactId>
-            <version>1.30.2</version>
+            <version>${grpc.version}</version>
         </dependency>
         <dependency>
             <groupId>io.grpc</groupId>
             <artifactId>grpc-stub</artifactId>
-            <version>1.30.2</version>
+            <version>${grpc.version}</version>
         </dependency>
         <dependency>
             <groupId>javax.annotation</groupId>
@@ -127,27 +121,11 @@
             <artifactId>protobuf-java-util</artifactId>
             <version>${protobuf.version}</version>
         </dependency>
-        <dependency>
-            <groupId>com.google.errorprone</groupId>
-            <artifactId>error_prone_annotations</artifactId>
-            <version>2.3.4</version> <!-- prefer to use 2.3.3 or later -->
-        </dependency>
-        <dependency>
-            <groupId>org.junit.jupiter</groupId>
-            <artifactId>junit-jupiter</artifactId>
-            <version>5.6.2</version>
-            <scope>test</scope>
-        </dependency>
         <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-text</artifactId>
             <version>1.6</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-collections4</artifactId>
-            <version>4.4</version>
-        </dependency>
         <dependency>
             <groupId>org.json</groupId>
             <artifactId>json</artifactId>
@@ -272,11 +250,9 @@
                 <artifactId>protobuf-maven-plugin</artifactId>
                 <version>0.6.1</version>
                 <configuration>
-                    <protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}
-                    </protocArtifact>
+                    <protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}</protocArtifact>
                     <pluginId>grpc-java</pluginId>
-                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
-                    </pluginArtifact>
+                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
                 </configuration>
                 <executions>
                     <execution>

+ 0 - 108
src/main/java/io/milvus/client/CollectionMapping.java

@@ -1,108 +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.client;
-
-import javax.annotation.Nonnull;
-
-/** Represents a collection mapping */
-// Builder Pattern
-public class CollectionMapping {
-  private final String collectionName;
-  private final long dimension;
-  private final long indexFileSize;
-  private final MetricType metricType;
-
-  private CollectionMapping(@Nonnull Builder builder) {
-    collectionName = builder.collectionName;
-    dimension = builder.dimension;
-    indexFileSize = builder.indexFileSize;
-    metricType = builder.metricType;
-  }
-
-  public String getCollectionName() {
-    return collectionName;
-  }
-
-  public long getDimension() {
-    return dimension;
-  }
-
-  public long getIndexFileSize() {
-    return indexFileSize;
-  }
-
-  public MetricType getMetricType() {
-    return metricType;
-  }
-
-  @Override
-  public String toString() {
-    return String.format(
-        "CollectionMapping = {collectionName = %s, dimension = %d, indexFileSize = %d, metricType = %s}",
-        collectionName, dimension, indexFileSize, metricType.name());
-  }
-
-  /** Builder for <code>CollectionMapping</code> */
-  public static class Builder {
-    // Required parameters
-    private final String collectionName;
-    private final long dimension;
-
-    // Optional parameters - initialized to default values
-    private long indexFileSize = 1024;
-    private MetricType metricType = MetricType.L2;
-
-    /**
-     * @param collectionName collection name
-     * @param dimension vector dimension
-     */
-    public Builder(@Nonnull String collectionName, long dimension) {
-      this.collectionName = collectionName;
-      this.dimension = dimension;
-    }
-
-    /**
-     * Optional. Default to 1024 MB.
-     *
-     * @param indexFileSize in megabytes.
-     * @return <code>Builder</code>
-     */
-    public Builder withIndexFileSize(long indexFileSize) {
-      this.indexFileSize = indexFileSize;
-      return this;
-    }
-
-    /**
-     * Optional. Default to MetricType.L2
-     *
-     * @param metricType a <code>MetricType</code> value
-     * @return <code>Builder</code>
-     * @see MetricType
-     */
-    public Builder withMetricType(@Nonnull MetricType metricType) {
-      this.metricType = metricType;
-      return this;
-    }
-
-    public CollectionMapping build() {
-      return new CollectionMapping(this);
-    }
-  }
-}

+ 0 - 28
src/main/java/io/milvus/client/ConnectFailedException.java

@@ -1,28 +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.client;
-
-/** Thrown when client failed to connect to server */
-public class ConnectFailedException extends Exception {
-
-  public ConnectFailedException(String message) {
-    super(message);
-  }
-}

+ 0 - 204
src/main/java/io/milvus/client/ConnectParam.java

@@ -1,204 +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.client;
-
-import javax.annotation.Nonnull;
-import java.util.concurrent.TimeUnit;
-
-/** Contains parameters for connecting to Milvus server */
-public class ConnectParam {
-  private final String host;
-  private final int port;
-  private final long connectTimeoutNanos;
-  private final long keepAliveTimeNanos;
-  private final long keepAliveTimeoutNanos;
-  private final boolean keepAliveWithoutCalls;
-  private final long idleTimeoutNanos;
-
-  private ConnectParam(@Nonnull Builder builder) {
-    this.host = builder.host;
-    this.port = builder.port;
-    this.connectTimeoutNanos = builder.connectTimeoutNanos;
-    this.keepAliveTimeNanos = builder.keepAliveTimeNanos;
-    this.keepAliveTimeoutNanos = builder.keepAliveTimeoutNanos;
-    this.keepAliveWithoutCalls = builder.keepAliveWithoutCalls;
-    this.idleTimeoutNanos = builder.idleTimeoutNanos;
-  }
-
-  public String getHost() {
-    return host;
-  }
-
-  public int getPort() {
-    return port;
-  }
-
-  public long getConnectTimeout(@Nonnull TimeUnit timeUnit) {
-    return timeUnit.convert(connectTimeoutNanos, TimeUnit.NANOSECONDS);
-  }
-
-  public long getKeepAliveTime(@Nonnull TimeUnit timeUnit) {
-    return timeUnit.convert(keepAliveTimeNanos, TimeUnit.NANOSECONDS);
-  }
-
-  public long getKeepAliveTimeout(@Nonnull TimeUnit timeUnit) {
-    return timeUnit.convert(keepAliveTimeoutNanos, TimeUnit.NANOSECONDS);
-  }
-
-  public boolean isKeepAliveWithoutCalls() {
-    return keepAliveWithoutCalls;
-  }
-
-  public long getIdleTimeout(@Nonnull TimeUnit timeUnit) {
-    return timeUnit.convert(idleTimeoutNanos, TimeUnit.NANOSECONDS);
-  }
-
-  /** Builder for <code>ConnectParam</code> */
-  public static class Builder {
-    // Optional parameters - initialized to default values
-    private String host = "localhost";
-    private int port = 19530;
-    private long connectTimeoutNanos = TimeUnit.NANOSECONDS.convert(10, TimeUnit.SECONDS);
-    private long keepAliveTimeNanos = Long.MAX_VALUE; // Disabling keepalive
-    private long keepAliveTimeoutNanos = TimeUnit.NANOSECONDS.convert(20, TimeUnit.SECONDS);
-    private boolean keepAliveWithoutCalls = false;
-    private long idleTimeoutNanos = TimeUnit.NANOSECONDS.convert(24, TimeUnit.HOURS);
-
-    /**
-     * Optional. Defaults to "localhost".
-     *
-     * @param host server host
-     * @return <code>Builder</code>
-     */
-    public Builder withHost(@Nonnull String host) {
-      this.host = host;
-      return this;
-    }
-
-    /**
-     * Optional. Defaults to "19530".
-     *
-     * @param port server port
-     * @return <code>Builder</code>
-     */
-    public Builder withPort(int port) throws IllegalArgumentException {
-      if (port < 0 || port > 0xFFFF) {
-        throw new IllegalArgumentException("Port is out of range!");
-      }
-      this.port = port;
-      return this;
-    }
-
-    /**
-     * Optional. Defaults to 10 seconds.
-     *
-     * @param connectTimeout Timeout for client to establish a connection to server
-     * @return <code>Builder</code>
-     * @throws IllegalArgumentException
-     */
-    public Builder withConnectTimeout(long connectTimeout, @Nonnull TimeUnit timeUnit)
-        throws IllegalArgumentException {
-      if (connectTimeout <= 0L) {
-        throw new IllegalArgumentException("Connect timeout must be positive!");
-      }
-      connectTimeoutNanos = timeUnit.toNanos(connectTimeout);
-      return this;
-    }
-
-    /**
-     * Optional. Sets the time without read activity before sending a keepalive ping. An
-     * unreasonably small value might be increased, and Long.MAX_VALUE nano seconds or an
-     * unreasonably large value will disable keepalive. Defaults to infinite.
-     *
-     * @see <a
-     *     href="https://grpc.github.io/grpc-java/javadoc/io/grpc/ManagedChannelBuilder.html#keepAliveTime-long-java.util.concurrent.TimeUnit-">
-     *     GRPC keepAliveTime Javadoc</a>
-     * @return <code>Builder</code>
-     * @throws IllegalArgumentException
-     */
-    public Builder withKeepAliveTime(long keepAliveTime, @Nonnull TimeUnit timeUnit)
-        throws IllegalArgumentException {
-      if (keepAliveTime <= 0L) {
-        throw new IllegalArgumentException("Keepalive time must be positive!");
-      }
-      keepAliveTimeNanos = timeUnit.toNanos(keepAliveTime);
-      return this;
-    }
-
-    /**
-     * Optional. Sets the time waiting for read activity after sending a keepalive ping. If the time
-     * expires without any read activity on the connection, the connection is considered dead. An
-     * unreasonably small value might be increased. Defaults to 20 seconds.
-     *
-     * <p>This value should be at least multiple times the RTT to allow for lost packets.
-     *
-     * @see <a
-     *     href="https://grpc.github.io/grpc-java/javadoc/io/grpc/ManagedChannelBuilder.html#keepAliveTimeout-long-java.util.concurrent.TimeUnit-">
-     *     GRPC keepAliveTimeout Javadoc</a>
-     * @return <code>Builder</code>
-     * @throws IllegalArgumentException
-     */
-    public Builder withKeepAliveTimeout(long keepAliveTimeout, @Nonnull TimeUnit timeUnit)
-        throws IllegalArgumentException {
-      if (keepAliveTimeout <= 0L) {
-        throw new IllegalArgumentException("Keepalive timeout must be positive!");
-      }
-      keepAliveTimeoutNanos = timeUnit.toNanos(keepAliveTimeout);
-      return this;
-    }
-
-    /**
-     * Optional. Sets whether keepalive will be performed when there are no outstanding RPC on a
-     * connection. Defaults to false.
-     *
-     * @see <a
-     *     href="https://grpc.github.io/grpc-java/javadoc/io/grpc/ManagedChannelBuilder.html#keepAliveWithoutCalls-boolean-">
-     *     GRPC keepAliveWithoutCalls Javadoc</a>
-     * @return <code>Builder</code>
-     */
-    public Builder keepAliveWithoutCalls(boolean enable) {
-      keepAliveWithoutCalls = enable;
-      return this;
-    }
-
-    /**
-     * Optional. Set the duration without ongoing RPCs before going to idle mode. A new RPC would
-     * take the channel out of idle mode. Defaults to 24 hour.
-     *
-     * @see <a
-     *     href="https://grpc.github.io/grpc-java/javadoc/io/grpc/ManagedChannelBuilder.html#idleTimeout-long-java.util.concurrent.TimeUnit-">
-     *     GRPC idleTimeout Javadoc</a>
-     * @return <code>Builder</code>
-     * @throws IllegalArgumentException
-     */
-    public Builder withIdleTimeout(long idleTimeout, TimeUnit timeUnit)
-        throws IllegalArgumentException {
-      if (idleTimeout <= 0L) {
-        throw new IllegalArgumentException("Idle timeout must be positive!");
-      }
-      idleTimeoutNanos = timeUnit.toNanos(idleTimeout);
-      return this;
-    }
-
-    public ConnectParam build() {
-      return new ConnectParam(this);
-    }
-  }
-}

+ 0 - 54
src/main/java/io/milvus/client/CountEntitiesResponse.java

@@ -1,54 +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.client;
-
-/**
- * Contains the returned <code>response</code> and <code>collectionEntityCount</code> for <code>
- * countEntities</code>
- */
-public class CountEntitiesResponse {
-  private final Response response;
-  private final long collectionEntityCount;
-
-  CountEntitiesResponse(Response response, long collectionEntityCount) {
-    this.response = response;
-    this.collectionEntityCount = collectionEntityCount;
-  }
-
-  public long getCollectionEntityCount() {
-    return collectionEntityCount;
-  }
-
-  public Response getResponse() {
-    return response;
-  }
-
-  /** @return <code>true</code> if the response status equals SUCCESS */
-  public boolean ok() {
-    return response.ok();
-  }
-
-  @Override
-  public String toString() {
-    return String.format(
-        "CountCollectionResponse {%s, collection entity count = %d}",
-        response.toString(), collectionEntityCount);
-  }
-}

+ 0 - 64
src/main/java/io/milvus/client/GetCollectionInfoResponse.java

@@ -1,64 +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.client;
-
-import javax.annotation.Nullable;
-import java.util.Optional;
-
-/**
- * Contains the returned <code>response</code> and <code>collectionMapping</code> for <code>
- * getCollectionInfo
- * </code>
- */
-public class GetCollectionInfoResponse {
-  private final Response response;
-  private final CollectionMapping collectionMapping;
-
-  GetCollectionInfoResponse(Response response, @Nullable CollectionMapping collectionMapping) {
-    this.response = response;
-    this.collectionMapping = collectionMapping;
-  }
-
-  /**
-   * @return an <code>Optional</code> object which may or may not contain a <code>CollectionMapping
-   *     </code> object
-   * @see Optional
-   */
-  public Optional<CollectionMapping> getCollectionMapping() {
-    return Optional.ofNullable(collectionMapping);
-  }
-
-  public Response getResponse() {
-    return response;
-  }
-
-  /** @return <code>true</code> if the response status equals SUCCESS */
-  public boolean ok() {
-    return response.ok();
-  }
-
-  @Override
-  public String toString() {
-    return String.format(
-        "GetCollectionInfoResponse {%s, %s}",
-        response.toString(),
-        collectionMapping == null ? "Collection mapping = None" : collectionMapping.toString());
-  }
-}

+ 0 - 41
src/main/java/io/milvus/client/GetEntityByIDResponse.java

@@ -1,41 +0,0 @@
-package io.milvus.client;
-
-import java.nio.ByteBuffer;
-import java.util.List;
-
-/**
- * Contains the returned <code>response</code> and either a <code>List</code> of <code>floatVectors
- * </code> or <code>
- * binaryVectors</code> for <code>getEntityByID</code>. If the id does not exist, both float and
- * binary vectors corresponding to the id will be empty.
- */
-public class GetEntityByIDResponse {
-  private final Response response;
-  private final List<List<Float>> floatVectors;
-  private final List<ByteBuffer> binaryVectors;
-
-  GetEntityByIDResponse(
-      Response response, List<List<Float>> floatVectors, List<ByteBuffer> binaryVectors) {
-    this.response = response;
-    this.floatVectors = floatVectors;
-    this.binaryVectors = binaryVectors;
-  }
-
-  public List<List<Float>> getFloatVectors() {
-    return floatVectors;
-  }
-
-  /** @return a <code>List</code> of <code>ByteBuffer</code> object */
-  public List<ByteBuffer> getBinaryVectors() {
-    return binaryVectors;
-  }
-
-  public Response getResponse() {
-    return response;
-  }
-
-  /** @return <code>true</code> if the response status equals SUCCESS */
-  public boolean ok() {
-    return response.ok();
-  }
-}

+ 0 - 61
src/main/java/io/milvus/client/GetIndexInfoResponse.java

@@ -1,61 +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.client;
-
-import javax.annotation.Nullable;
-import java.util.Optional;
-
-/**
- * Contains the returned <code>response</code> and <code>index</code> for <code>getIndexInfo</code>
- */
-public class GetIndexInfoResponse {
-  private final Response response;
-  private final Index index;
-
-  GetIndexInfoResponse(Response response, @Nullable Index index) {
-    this.response = response;
-    this.index = index;
-  }
-
-  /**
-   * @return an <code>Optional</code> object which may or may not contain an <code>Index</code>
-   *     object
-   * @see Optional
-   */
-  public Optional<Index> getIndex() {
-    return Optional.ofNullable(index);
-  }
-
-  public Response getResponse() {
-    return response;
-  }
-
-  /** @return <code>true</code> if the response status equals SUCCESS */
-  public boolean ok() {
-    return response.ok();
-  }
-
-  @Override
-  public String toString() {
-    return String.format(
-        "GetIndexInfoResponse {%s, %s}",
-        response.toString(), index == null ? "Index = Null" : index.toString());
-  }
-}

+ 0 - 53
src/main/java/io/milvus/client/HasCollectionResponse.java

@@ -1,53 +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.client;
-
-/**
- * Contains the returned <code>response</code> and <code>hasCollection</code> for <code>
- * hasCollection</code>
- */
-public class HasCollectionResponse {
-  private final Response response;
-  private final boolean hasCollection;
-
-  HasCollectionResponse(Response response, boolean hasCollection) {
-    this.response = response;
-    this.hasCollection = hasCollection;
-  }
-
-  public boolean hasCollection() {
-    return hasCollection;
-  }
-
-  public Response getResponse() {
-    return response;
-  }
-
-  /** @return <code>true</code> if the response status equals SUCCESS */
-  public boolean ok() {
-    return response.ok();
-  }
-
-  @Override
-  public String toString() {
-    return String.format(
-        "HasCollectionResponse {%s, has collection = %s}", response.toString(), hasCollection);
-  }
-}

+ 0 - 53
src/main/java/io/milvus/client/HasPartitionResponse.java

@@ -1,53 +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.client;
-
-/**
- * Contains the returned <code>response</code> and <code>hasPartition</code> for <code>
- * hasPartition</code>
- */
-public class HasPartitionResponse {
-    private final Response response;
-    private final boolean hasPartition;
-
-    HasPartitionResponse(Response response, boolean hasPartition) {
-        this.response = response;
-        this.hasPartition = hasPartition;
-    }
-
-    public boolean hasPartition() {
-        return hasPartition;
-    }
-
-    public Response getResponse() {
-        return response;
-    }
-
-    /** @return <code>true</code> if the response status equals SUCCESS */
-    public boolean ok() {
-        return response.ok();
-    }
-
-    @Override
-    public String toString() {
-        return String.format(
-                "HasPartitionResponse {%s, has partition = %s}", response.toString(), hasPartition);
-    }
-}

+ 0 - 118
src/main/java/io/milvus/client/Index.java

@@ -1,118 +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.client;
-
-import javax.annotation.Nonnull;
-
-/** Represents an index containing <code>indexType</code> and <code>nList</code> */
-public class Index {
-  private final String collectionName;
-  private final IndexType indexType;
-  private final String paramsInJson;
-
-  private Index(@Nonnull Builder builder) {
-    this.collectionName = builder.collectionName;
-    this.indexType = builder.indexType;
-    this.paramsInJson = builder.paramsInJson;
-  }
-
-  public String getCollectionName() {
-    return collectionName;
-  }
-
-  public IndexType getIndexType() {
-    return indexType;
-  }
-
-  public String getParamsInJson() {
-    return paramsInJson;
-  }
-
-  @Override
-  public String toString() {
-    return "Index {"
-        + "collectionName="
-        + collectionName
-        + ", indexType="
-        + indexType
-        + ", params="
-        + paramsInJson
-        + '}';
-  }
-
-  /** Builder for <code>Index</code> */
-  public static class Builder {
-    // Required parameters
-    private final String collectionName;
-    private final IndexType indexType;
-
-    // Optional parameters - initialized to default values
-    private String paramsInJson;
-
-    /**
-     * @param collectionName collection to create index on
-     * @param indexType a <code>IndexType</code> object
-     */
-    public Builder(@Nonnull String collectionName, @Nonnull IndexType indexType) {
-      this.collectionName = collectionName;
-      this.indexType = indexType;
-    }
-
-    /**
-     * Optional. Default to empty <code>String</code>. Index parameters are different for different
-     * index types. Refer to <a
-     * href="https://milvus.io/docs/milvus_operation.md">https://milvus.io/docs/milvus_operation.md</a>
-     * for more information.
-     *
-     * <pre>
-     * FLAT/IVFLAT/SQ8: {"nlist": 16384}
-     * nlist range:[1, 999999]
-     *
-     * IVFPQ: {"nlist": 16384, "m": 12}
-     * nlist range:[1, 999999]
-     * m is decided by dim and have a couple of results.
-     *
-     * NSG: {"search_length": 45, "out_degree": 50, "candidate_pool_size": 300, "knng": 100}
-     * search_length range:[10, 300]
-     * out_degree range:[5, 300]
-     * candidate_pool_size range:[50, 1000]
-     * knng range:[5, 300]
-     *
-     * HNSW: {"M": 16, "efConstruction": 500}
-     * M range:[5, 48]
-     * efConstruction range:[100, 500]
-     *
-     * ANNOY: {"n_trees": 4}
-     * n_trees range: [1, 16384)
-     * </pre>
-     *
-     * @param paramsInJson extra parameters in JSON format
-     * @return <code>Builder</code>
-     */
-    public Builder withParamsInJson(@Nonnull String paramsInJson) {
-      this.paramsInJson = paramsInJson;
-      return this;
-    }
-
-    public Index build() {
-      return new Index(this);
-    }
-  }
-}

+ 0 - 58
src/main/java/io/milvus/client/IndexType.java

@@ -1,58 +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.client;
-
-import java.util.Arrays;
-import java.util.Optional;
-
-/**
- * Represents different types of indexing method to query the collection. Refer to <a
- * href="https://milvus.io/docs/index.md">https://milvus.io/docs/index.md</a>
- * for more information.
- */
-public enum IndexType {
-  INVALID(0),
-  FLAT(1),
-  IVFLAT(2),
-  IVF_SQ8(3),
-  RNSG(4),
-  IVF_SQ8_H(5),
-  IVF_PQ(6),
-  HNSW(11),
-  ANNOY(12),
-
-  UNKNOWN(-1);
-
-  private final int val;
-
-  IndexType(int val) {
-    this.val = val;
-  }
-
-  public static IndexType valueOf(int val) {
-    Optional<IndexType> search =
-        Arrays.stream(values()).filter(indexType -> indexType.val == val).findFirst();
-    return search.orElse(UNKNOWN);
-  }
-
-  public int getVal() {
-    return val;
-  }
-}

+ 0 - 132
src/main/java/io/milvus/client/InsertParam.java

@@ -1,132 +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.client;
-
-import javax.annotation.Nonnull;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
-
-/** Contains parameters for <code>insert</code> */
-public class InsertParam {
-  private final String collectionName;
-  private final List<List<Float>> floatVectors;
-  private final List<ByteBuffer> binaryVectors;
-  private final List<Long> vectorIds;
-  private final String partitionTag;
-
-  private InsertParam(@Nonnull Builder builder) {
-    this.collectionName = builder.collectionName;
-    this.floatVectors = builder.floatVectors;
-    this.binaryVectors = builder.binaryVectors;
-    this.vectorIds = builder.vectorIds;
-    this.partitionTag = builder.partitionTag;
-  }
-
-  public String getCollectionName() {
-    return collectionName;
-  }
-
-  public List<List<Float>> getFloatVectors() {
-    return floatVectors;
-  }
-
-  public List<ByteBuffer> getBinaryVectors() {
-    return binaryVectors;
-  }
-
-  public List<Long> getVectorIds() {
-    return vectorIds;
-  }
-
-  public String getPartitionTag() {
-    return partitionTag;
-  }
-
-  /** Builder for <code>InsertParam</code> */
-  public static class Builder {
-    // Required parameters
-    private final String collectionName;
-
-    // Optional parameters - initialized to default values
-    private List<List<Float>> floatVectors = new ArrayList<>();
-    private List<ByteBuffer> binaryVectors = new ArrayList<>();
-    private List<Long> vectorIds = new ArrayList<>();
-    private String partitionTag = "";
-
-    /** @param collectionName collection to insert vectors to */
-    public Builder(@Nonnull String collectionName) {
-      this.collectionName = collectionName;
-    }
-
-    /**
-     * Default to an empty <code>ArrayList</code>. You can only insert either float or binary
-     * vectors to a collection, not both.
-     *
-     * @param floatVectors a <code>List</code> of float vectors to insert. Each inner <code>List
-     *     </code> represents a float vector.
-     * @return <code>Builder</code>
-     */
-    public Builder withFloatVectors(@Nonnull List<List<Float>> floatVectors) {
-      this.floatVectors = floatVectors;
-      return this;
-    }
-
-    /**
-     * Default to an empty <code>ArrayList</code>. You can only insert either float or binary
-     * vectors to a collection, not both.
-     *
-     * @param binaryVectors a <code>List</code> of binary vectors to insert. Each <code>ByteBuffer
-     *     </code> object represents a binary vector, with every 8 bits constituting a byte.
-     * @return <code>Builder</code>
-     * @see ByteBuffer
-     */
-    public Builder withBinaryVectors(@Nonnull List<ByteBuffer> binaryVectors) {
-      this.binaryVectors = binaryVectors;
-      return this;
-    }
-
-    /**
-     * Optional. Default to an empty <code>ArrayList</code>
-     *
-     * @param vectorIds a <code>List</code> of ids associated with the vectors to insert
-     * @return <code>Builder</code>
-     */
-    public Builder withVectorIds(@Nonnull List<Long> vectorIds) {
-      this.vectorIds = vectorIds;
-      return this;
-    }
-
-    /**
-     * Optional. Default to an empty <code>String</code>
-     *
-     * @param partitionTag partition tag
-     * @return <code>Builder</code>
-     */
-    public Builder withPartitionTag(@Nonnull String partitionTag) {
-      this.partitionTag = partitionTag;
-      return this;
-    }
-
-    public InsertParam build() {
-      return new InsertParam(this);
-    }
-  }
-}

+ 0 - 54
src/main/java/io/milvus/client/InsertResponse.java

@@ -1,54 +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.client;
-
-import java.util.List;
-
-/**
- * Contains the returned <code>response</code> and <code>vectorIds</code> for <code>insert</code>
- */
-public class InsertResponse {
-  private final Response response;
-  private final List<Long> vectorIds;
-
-  InsertResponse(Response response, List<Long> vectorIds) {
-    this.response = response;
-    this.vectorIds = vectorIds;
-  }
-
-  public List<Long> getVectorIds() {
-    return vectorIds;
-  }
-
-  public Response getResponse() {
-    return response;
-  }
-
-  /** @return <code>true</code> if the response status equals SUCCESS */
-  public boolean ok() {
-    return response.ok();
-  }
-
-  @Override
-  public String toString() {
-    return String.format(
-        "InsertResponse {%s, returned %d vector ids}", response.toString(), this.vectorIds.size());
-  }
-}

+ 0 - 57
src/main/java/io/milvus/client/ListCollectionsResponse.java

@@ -1,57 +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.client;
-
-import java.util.List;
-
-/**
- * Contains the returned <code>response</code> and <code>collectionNames</code> for <code>
- * listCollections
- * </code>
- */
-public class ListCollectionsResponse {
-  private final Response response;
-  private final List<String> collectionNames;
-
-  ListCollectionsResponse(Response response, List<String> collectionNames) {
-    this.response = response;
-    this.collectionNames = collectionNames;
-  }
-
-  public List<String> getCollectionNames() {
-    return collectionNames;
-  }
-
-  public Response getResponse() {
-    return response;
-  }
-
-  /** @return <code>true</code> if the response status equals SUCCESS */
-  public boolean ok() {
-    return response.ok();
-  }
-
-  @Override
-  public String toString() {
-    return String.format(
-        "ListCollectionsResponse {%s, collection names = %s}",
-        response, collectionNames.toString());
-  }
-}

+ 0 - 30
src/main/java/io/milvus/client/ListIDInSegmentResponse.java

@@ -1,30 +0,0 @@
-package io.milvus.client;
-
-import java.util.List;
-
-/**
- * Contains the returned <code>response</code> and a <code>List</code> of ids present in a segment
- * for <code>listIDInSegment</code>.
- */
-public class ListIDInSegmentResponse {
-  private final Response response;
-  private final List<Long> ids;
-
-  ListIDInSegmentResponse(Response response, List<Long> ids) {
-    this.response = response;
-    this.ids = ids;
-  }
-
-  public List<Long> getIds() {
-    return ids;
-  }
-
-  public Response getResponse() {
-    return response;
-  }
-
-  /** @return <code>true</code> if the response status equals SUCCESS */
-  public boolean ok() {
-    return response.ok();
-  }
-}

+ 0 - 51
src/main/java/io/milvus/client/ListPartitionsResponse.java

@@ -1,51 +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.client;
-
-import java.util.List;
-
-/**
- * Contains the returned <code>response</code> and <code>partitionList</code> for <code>
- * listPartitions
- * </code>
- */
-public class ListPartitionsResponse {
-  private final Response response;
-  private final List<String> partitionList;
-
-  ListPartitionsResponse(Response response, List<String> partitionList) {
-    this.response = response;
-    this.partitionList = partitionList;
-  }
-
-  /** @return a <code>List</code> of partition tags. */
-  public List<String> getPartitionList() {
-    return partitionList;
-  }
-
-  public Response getResponse() {
-    return response;
-  }
-
-  /** @return <code>true</code> if the response status equals SUCCESS */
-  public boolean ok() {
-    return response.ok();
-  }
-}

+ 0 - 64
src/main/java/io/milvus/client/MetricType.java

@@ -1,64 +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.client;
-
-import java.util.Arrays;
-import java.util.Optional;
-
-/**
- * Represents available metric types. Refer to <a
- * href="https://milvus.io/docs/metric.md">https://milvus.io/docs/metric.md</a>
- * for more information.
- */
-public enum MetricType {
-  INVALID(0),
-  /** Euclidean distance. For float vectors only */
-  L2(1),
-  /** Inner product. For float vectors only */
-  IP(2),
-  /** Hamming distance. For binary vectors only */
-  HAMMING(3),
-  /** Jaccard distance. For binary vectors only */
-  JACCARD(4),
-  /** Tanimoto distance. For binary vectors only */
-  TANIMOTO(5),
-  /** Substructure. For binary vectors only */
-  SUBSTRUCTURE(6),
-  /** Superstructure. For binary vectors only */
-  SUPERSTRUCTURE(7),
-
-  UNKNOWN(-1);
-
-  private final int val;
-
-  MetricType(int val) {
-    this.val = val;
-  }
-
-  public static MetricType valueOf(int val) {
-    Optional<MetricType> search =
-        Arrays.stream(values()).filter(metricType -> metricType.val == val).findFirst();
-    return search.orElse(UNKNOWN);
-  }
-
-  public int getVal() {
-    return val;
-  }
-}

+ 0 - 487
src/main/java/io/milvus/client/MilvusClient.java

@@ -1,487 +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.client;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import org.apache.commons.lang3.exception.ExceptionUtils;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.List;
-import java.util.Properties;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Supplier;
-
-/** The Milvus Client Interface */
-public interface MilvusClient {
-
-  String clientVersion = new Supplier<String>() {
-    @Override
-    public String get() {
-      Properties properties = new Properties();
-      InputStream inputStream = MilvusClient.class
-          .getClassLoader().getResourceAsStream("milvus-client.properties");
-      try {
-        properties.load(inputStream);
-      } catch (IOException ex) {
-        ExceptionUtils.wrapAndThrow(ex);
-      } finally {
-        try {
-          inputStream.close();
-        } catch (IOException ex) {
-        }
-      }
-      return properties.getProperty("version");
-    }
-  }.get();
-
-  /** @return current Milvus client version */
-  default String getClientVersion() {
-    return clientVersion;
-  }
-
-  /**
-   * Close this MilvusClient. Wait at most 1 minute for graceful shutdown.
-   */
-  default void close() {
-    close(TimeUnit.MINUTES.toSeconds(1));
-  }
-
-  /**
-   * Close this MilvusClient. Wait at most `maxWaitSeconds` for graceful shutdown.
-   */
-  void close(long maxWaitSeconds);
-
-  MilvusClient withTimeout(long timeout, TimeUnit timeoutUnit);
-
-  /**
-   * Creates collection specified by <code>collectionMapping</code>
-   *
-   * @param collectionMapping the <code>CollectionMapping</code> object
-   *     <pre>
-   * example usage:
-   * <code>
-   * CollectionMapping collectionMapping = new CollectionMapping.Builder(collectionName, dimension)
-   *                                          .withIndexFileSize(1024)
-   *                                          .withMetricType(MetricType.IP)
-   *                                          .build();
-   * </code>
-   * </pre>
-   *
-   * @return <code>Response</code>
-   * @see CollectionMapping
-   * @see MetricType
-   * @see Response
-   */
-  Response createCollection(CollectionMapping collectionMapping);
-
-  /**
-   * Checks whether the collection exists
-   *
-   * @param collectionName collection to check
-   * @return <code>HasCollectionResponse</code>
-   * @see HasCollectionResponse
-   * @see Response
-   */
-  HasCollectionResponse hasCollection(String collectionName);
-
-  /**
-   * Drops collection
-   *
-   * @param collectionName collection to drop
-   * @return <code>Response</code>
-   * @see Response
-   */
-  Response dropCollection(String collectionName);
-
-  /**
-   * Creates index specified by <code>index</code>
-   *
-   * @param index the <code>Index</code> object
-   *     <pre>
-   * example usage:
-   * <code>
-   * Index index = new Index.Builder(collectionName, IndexType.IVF_SQ8)
-   *                        .withParamsInJson("{\"nlist\": 16384}")
-   *                        .build();
-   * </code>
-   * </pre>
-   *
-   * @return <code>Response</code>
-   * @see Index
-   * @see IndexType
-   * @see Response
-   */
-  Response createIndex(Index index);
-
-  /**
-   * Creates index specified by <code>index</code> asynchronously
-   *
-   * @param index the <code>Index</code> object
-   *     <pre>
-   * example usage:
-   * <code>
-   * Index index = new Index.Builder(collectionName, IndexType.IVF_SQ8)
-   *                        .withParamsInJson("{\"nlist\": 16384}")
-   *                        .build();
-   * </code>
-   * </pre>
-   *
-   * @return a <code>ListenableFuture</code> object which holds the <code>Response</code>
-   * @see Index
-   * @see IndexType
-   * @see Response
-   * @see ListenableFuture
-   */
-  ListenableFuture<Response> createIndexAsync(Index index);
-
-  /**
-   * Creates a partition specified by <code>collectionName</code> and <code>tag</code>
-   *
-   * @param collectionName collection name
-   * @param tag partition tag
-   * @return <code>Response</code>
-   * @see Response
-   */
-  Response createPartition(String collectionName, String tag);
-
-  /**
-   * Checks whether the partition exists
-   *
-   * @param collectionName collection name
-   * @param tag partition tag
-   * @return <code>HasPartitionResponse</code>
-   * @see Response
-   */
-  HasPartitionResponse hasPartition(String collectionName, String tag);
-
-  /**
-   * Lists current partitions of a collection
-   *
-   * @param collectionName collection name
-   * @return <code>ListPartitionsResponse</code>
-   * @see ListPartitionsResponse
-   * @see Response
-   */
-  ListPartitionsResponse listPartitions(String collectionName);
-
-  /**
-   * Drops partition specified by <code>collectionName</code> and <code>tag</code>
-   *
-   * @param collectionName collection name
-   * @param tag partition tag
-   * @see Response
-   */
-  Response dropPartition(String collectionName, String tag);
-
-  /**
-   * Inserts data specified by <code>insertParam</code>
-   *
-   * @param insertParam the <code>InsertParam</code> object
-   *     <pre>
-   * example usage:
-   * <code>
-   * InsertParam insertParam = new InsertParam.Builder(collectionName)
-   *                                          .withFloatVectors(floatVectors)
-   *                                          .withVectorIds(vectorIds)
-   *                                          .withPartitionTag(tag)
-   *                                          .build();
-   * </code>
-   * </pre>
-   *
-   * @return <code>InsertResponse</code>
-   * @see InsertParam
-   * @see InsertResponse
-   * @see Response
-   */
-  InsertResponse insert(InsertParam insertParam);
-
-  /**
-   * Inserts data specified by <code>insertParam</code> asynchronously
-   *
-   * @param insertParam the <code>InsertParam</code> object
-   *     <pre>
-   * example usage:
-   * <code>
-   * InsertParam insertParam = new InsertParam.Builder(collectionName)
-   *                                          .withFloatVectors(floatVectors)
-   *                                          .withVectorIds(vectorIds)
-   *                                          .withPartitionTag(tag)
-   *                                          .build();
-   * </code>
-   * </pre>
-   *
-   * @return a <code>ListenableFuture</code> object which holds the <code>InsertResponse</code>
-   * @see InsertParam
-   * @see InsertResponse
-   * @see Response
-   * @see ListenableFuture
-   */
-  ListenableFuture<InsertResponse> insertAsync(InsertParam insertParam);
-
-  /**
-   * Searches vectors specified by <code>searchParam</code>
-   *
-   * @param searchParam the <code>SearchParam</code> object
-   *     <pre>
-   * example usage:
-   * <code>
-   * SearchParam searchParam = new SearchParam.Builder(collectionName)
-   *                                          .withFloatVectors(floatVectors)
-   *                                          .withTopK(topK)
-   *                                          .withPartitionTags(partitionTagsList)
-   *                                          .withParamsInJson("{\"nprobe\": 20}")
-   *                                          .build();
-   * </code>
-   * </pre>
-   *
-   * @return <code>SearchResponse</code>
-   * @see SearchParam
-   * @see SearchResponse
-   * @see SearchResponse.QueryResult
-   * @see Response
-   */
-  SearchResponse search(SearchParam searchParam);
-
-  /**
-   * Searches vectors specified by <code>searchParam</code> asynchronously
-   *
-   * @param searchParam the <code>SearchParam</code> object
-   *     <pre>
-   * example usage:
-   * <code>
-   * SearchParam searchParam = new SearchParam.Builder(collectionName)
-   *                                          .withFloatVectors(floatVectors)
-   *                                          .withTopK(topK)
-   *                                          .withPartitionTags(partitionTagsList)
-   *                                          .withParamsInJson("{\"nprobe\": 20}")
-   *                                          .build();
-   * </code>
-   * </pre>
-   *
-   * @return a <code>ListenableFuture</code> object which holds the <code>SearchResponse</code>
-   * @see SearchParam
-   * @see SearchResponse
-   * @see SearchResponse.QueryResult
-   * @see Response
-   * @see ListenableFuture
-   */
-  ListenableFuture<SearchResponse> searchAsync(SearchParam searchParam);
-
-  /**
-   * Gets collection info
-   *
-   * @param collectionName collection to describe
-   * @see GetCollectionInfoResponse
-   * @see CollectionMapping
-   * @see Response
-   */
-  GetCollectionInfoResponse getCollectionInfo(String collectionName);
-
-  /**
-   * Lists current collections
-   *
-   * @return <code>ListCollectionsResponse</code>
-   * @see ListCollectionsResponse
-   * @see Response
-   */
-  ListCollectionsResponse listCollections();
-
-  /**
-   * Gets current entity count of a collection
-   *
-   * @param collectionName collection to count entities
-   * @return <code>CountEntitiesResponse</code>
-   * @see CountEntitiesResponse
-   * @see Response
-   */
-  CountEntitiesResponse countEntities(String collectionName);
-
-  /**
-   * Get server status
-   *
-   * @return <code>Response</code>
-   * @see Response
-   */
-  Response getServerStatus();
-
-  /**
-   * Get server version
-   *
-   * @return <code>Response</code>
-   * @see Response
-   */
-  Response getServerVersion();
-
-  /**
-   * Sends a command to server
-   *
-   * @return <code>Response</code> command's response will be return in <code>message</code>
-   * @see Response
-   */
-  Response command(String command);
-
-  /**
-   * Pre-loads collection to memory
-   *
-   * @param collectionName collection to load
-   * @return <code>Response</code>
-   * @see Response
-   */
-  Response loadCollection(String collectionName);
-
-  /**
-   * Pre-loads collection/partitions to memory
-   *
-   * @param collectionName collection to load
-   * @param partitionTags partitions to load
-   * @return <code>Response</code>
-   * @see Response
-   */
-  Response loadCollection(String collectionName, List<String> partitionTags);
-
-  /**
-   * Gets collection index information
-   *
-   * @param collectionName collection to get info from
-   * @see GetIndexInfoResponse
-   * @see Index
-   * @see Response
-   */
-  GetIndexInfoResponse getIndexInfo(String collectionName);
-
-  /**
-   * Drops collection index
-   *
-   * @param collectionName collection to drop index of
-   * @return <code>Response</code>
-   * @see Response
-   */
-  Response dropIndex(String collectionName);
-
-  /**
-   * Shows collection information. A collection consists of one or multiple partitions (including
-   * the default partition), and a partitions consists of one or more segments. Each partition or
-   * segment can be uniquely identified by its partition tag or segment name respectively. The
-   * result will be returned as JSON string.
-   *
-   * @param collectionName collection to show info from
-   * @return <code>Response</code>
-   * @see Response
-   */
-  Response getCollectionStats(String collectionName);
-
-  /**
-   * Gets vectors data by id array
-   *
-   * @param collectionName collection to get vectors from
-   * @param ids a <code>List</code> of vector ids
-   * @return <code>GetEntityByIDResponse</code>
-   * @see GetEntityByIDResponse
-   * @see Response
-   */
-  GetEntityByIDResponse getEntityByID(String collectionName, List<Long> ids);
-
-  /**
-   * Gets all vector ids in a segment
-   *
-   * @param collectionName collection to get vector ids from
-   * @param segmentName segment name in the collection
-   * @return <code>ListIDInSegmentResponse</code>
-   * @see ListIDInSegmentResponse
-   * @see Response
-   */
-  ListIDInSegmentResponse listIDInSegment(String collectionName, String segmentName);
-
-  /**
-   * Deletes data in a collection by a list of ids
-   *
-   * @param collectionName collection to delete ids from
-   * @param ids a <code>List</code> of vector ids to delete
-   * @return <code>Response</code>
-   * @see Response
-   */
-  Response deleteEntityByID(String collectionName, List<Long> ids);
-
-  /**
-   * Flushes data in a list collections. Newly inserted or modifications on data will be visible
-   * after <code>flush</code> returned
-   *
-   * @param collectionNames a <code>List</code> of collections to flush
-   * @return <code>Response</code>
-   * @see Response
-   */
-  Response flush(List<String> collectionNames);
-
-  /**
-   * Flushes data in a list collections asynchronously. Newly inserted or modifications on data will
-   * be visible after <code>flush</code> returned
-   *
-   * @param collectionNames a <code>List</code> of collections to flush
-   * @return a <code>ListenableFuture</code> object which holds the <code>Response</code>
-   * @see Response
-   * @see ListenableFuture
-   */
-  ListenableFuture<Response> flushAsync(List<String> collectionNames);
-
-  /**
-   * Flushes data in a collection. Newly inserted or modifications on data will be visible after
-   * <code>flush</code> returned
-   *
-   * @param collectionName name of collection to flush
-   * @return <code>Response</code>
-   * @see Response
-   */
-  Response flush(String collectionName);
-
-  /**
-   * Flushes data in a collection asynchronously. Newly inserted or modifications on data will be
-   * visible after <code>flush</code> returned
-   *
-   * @param collectionName name of collection to flush
-   * @return a <code>ListenableFuture</code> object which holds the <code>Response</code>
-   * @see Response
-   * @see ListenableFuture
-   */
-  ListenableFuture<Response> flushAsync(String collectionName);
-
-  /**
-   * Compacts the collection, erasing deleted data from disk and rebuild index in background (if the
-   * data size after compaction is still larger than indexFileSize). Data was only soft-deleted
-   * until you call compact.
-   *
-   * @param collectionName name of collection to compact
-   * @return <code>Response</code>
-   * @see Response
-   */
-  Response compact(String collectionName);
-
-  /**
-   * Compacts the collection asynchronously, erasing deleted data from disk and rebuild index in
-   * background (if the data size after compaction is still larger than indexFileSize). Data was
-   * only soft-deleted until you call compact.
-   *
-   * @param collectionName name of collection to compact
-   * @return a <code>ListenableFuture</code> object which holds the <code>Response</code>
-   * @see Response
-   * @see ListenableFuture
-   */
-  ListenableFuture<Response> compactAsync(String collectionName);
-}

+ 0 - 1400
src/main/java/io/milvus/client/MilvusGrpcClient.java

@@ -1,1400 +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.client;
-
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-import com.google.protobuf.ByteString;
-import io.grpc.CallOptions;
-import io.grpc.Channel;
-import io.grpc.ClientCall;
-import io.grpc.ClientInterceptor;
-import io.grpc.ManagedChannel;
-import io.grpc.ManagedChannelBuilder;
-import io.grpc.MethodDescriptor;
-import io.grpc.StatusRuntimeException;
-import io.milvus.client.exception.InitializationException;
-import io.milvus.client.exception.UnsupportedServerVersion;
-import io.milvus.grpc.*;
-import java.nio.Buffer;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Function;
-import javax.annotation.Nonnull;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class MilvusGrpcClient extends AbstractMilvusGrpcClient {
-  private static String SUPPORTED_SERVER_VERSION = "1.0";
-  private final ManagedChannel channel;
-  private final MilvusServiceGrpc.MilvusServiceBlockingStub blockingStub;
-  private final MilvusServiceGrpc.MilvusServiceFutureStub futureStub;
-
-  public MilvusGrpcClient(ConnectParam connectParam) {
-    channel = ManagedChannelBuilder.forAddress(connectParam.getHost(), connectParam.getPort())
-        .usePlaintext()
-        .maxInboundMessageSize(Integer.MAX_VALUE)
-        .keepAliveTime(connectParam.getKeepAliveTime(TimeUnit.NANOSECONDS), TimeUnit.NANOSECONDS)
-        .keepAliveTimeout(connectParam.getKeepAliveTimeout(TimeUnit.NANOSECONDS), TimeUnit.NANOSECONDS)
-        .keepAliveWithoutCalls(connectParam.isKeepAliveWithoutCalls())
-        .idleTimeout(connectParam.getIdleTimeout(TimeUnit.NANOSECONDS), TimeUnit.NANOSECONDS)
-        .build();
-    blockingStub = MilvusServiceGrpc.newBlockingStub(channel);
-    futureStub = MilvusServiceGrpc.newFutureStub(channel);
-
-    try {
-      Response response = getServerVersion();
-      if (response.ok()) {
-        String serverVersion = getServerVersion().getMessage();
-        if (!serverVersion.matches("^" + SUPPORTED_SERVER_VERSION + "(\\..*)?$")) {
-          throw new UnsupportedServerVersion(connectParam.getHost(), SUPPORTED_SERVER_VERSION, serverVersion);
-        }
-      } else {
-        throw new InitializationException(connectParam.getHost(), response.getMessage());
-      }
-    } catch (Throwable t) {
-      channel.shutdownNow();
-      throw t;
-    }
-  }
-
-  @Override
-  protected MilvusServiceGrpc.MilvusServiceBlockingStub blockingStub() {
-    return blockingStub;
-  }
-
-  @Override
-  protected MilvusServiceGrpc.MilvusServiceFutureStub futureStub() {
-    return futureStub;
-  }
-
-  @Override
-  protected boolean maybeAvailable() {
-    switch (channel.getState(false)) {
-      case IDLE:
-      case CONNECTING:
-      case READY:
-        return true;
-      default:
-        return false;
-    }
-  }
-
-  @Override
-  public void close(long maxWaitSeconds) {
-    channel.shutdown();
-    long now = System.nanoTime();
-    long deadline = now + TimeUnit.SECONDS.toNanos(maxWaitSeconds);
-    boolean interrupted = false;
-    try {
-      while (now < deadline && !channel.isTerminated()) {
-        try {
-          channel.awaitTermination(deadline - now, TimeUnit.NANOSECONDS);
-        } catch (InterruptedException ex) {
-          interrupted = true;
-        }
-      }
-      if (!channel.isTerminated()) {
-        channel.shutdownNow();
-      }
-    } finally {
-      if (interrupted) {
-        Thread.currentThread().interrupt();
-      }
-    }
-  }
-
-  public MilvusClient withTimeout(long timeout, TimeUnit timeoutUnit) {
-    final long timeoutMillis = timeoutUnit.toMillis(timeout);
-    final TimeoutInterceptor timeoutInterceptor = new TimeoutInterceptor(timeoutMillis);
-    final MilvusServiceGrpc.MilvusServiceBlockingStub blockingStub =
-        this.blockingStub.withInterceptors(timeoutInterceptor);
-    final MilvusServiceGrpc.MilvusServiceFutureStub futureStub =
-        this.futureStub.withInterceptors(timeoutInterceptor);
-
-    return new AbstractMilvusGrpcClient() {
-
-      @Override
-      protected MilvusServiceGrpc.MilvusServiceBlockingStub blockingStub() {
-        return blockingStub;
-      }
-
-      @Override
-      protected MilvusServiceGrpc.MilvusServiceFutureStub futureStub() {
-        return futureStub;
-      }
-
-      @Override
-      protected boolean maybeAvailable() {
-        return MilvusGrpcClient.this.maybeAvailable();
-      }
-
-      @Override
-      public void close(long maxWaitSeconds) {
-        MilvusGrpcClient.this.close(maxWaitSeconds);
-      }
-
-      @Override
-      public MilvusClient withTimeout(long timeout, TimeUnit timeoutUnit) {
-        return MilvusGrpcClient.this.withTimeout(timeout, timeoutUnit);
-      }
-    };
-  }
-
-  private static class TimeoutInterceptor implements ClientInterceptor {
-    private long timeoutMillis;
-
-    TimeoutInterceptor(long timeoutMillis) {
-      this.timeoutMillis = timeoutMillis;
-    }
-
-    @Override
-    public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
-        MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
-      return next.newCall(method, callOptions.withDeadlineAfter(timeoutMillis, TimeUnit.MILLISECONDS));
-    }
-  }
-}
-
-abstract class AbstractMilvusGrpcClient implements MilvusClient {
-  private static final Logger logger = LoggerFactory.getLogger(AbstractMilvusGrpcClient.class);
-
-  private final String extraParamKey = "params";
-
-  protected abstract MilvusServiceGrpc.MilvusServiceBlockingStub blockingStub();
-
-  protected abstract MilvusServiceGrpc.MilvusServiceFutureStub futureStub();
-
-  protected abstract boolean maybeAvailable();
-
-  @Override
-  public Response createCollection(@Nonnull CollectionMapping collectionMapping) {
-
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return new Response(Response.Status.CLIENT_NOT_CONNECTED);
-    }
-
-    CollectionSchema request =
-        CollectionSchema.newBuilder()
-            .setCollectionName(collectionMapping.getCollectionName())
-            .setDimension(collectionMapping.getDimension())
-            .setIndexFileSize(collectionMapping.getIndexFileSize())
-            .setMetricType(collectionMapping.getMetricType().getVal())
-            .build();
-
-    Status response;
-
-    try {
-      response = blockingStub().createCollection(request);
-
-      if (response.getErrorCode() == ErrorCode.SUCCESS) {
-        logInfo("Created collection successfully!\n{}", collectionMapping.toString());
-        return new Response(Response.Status.SUCCESS);
-      } else if (response.getReason().contentEquals("Collection already exists")) {
-        logWarning("Collection `{}` already exists", collectionMapping.getCollectionName());
-        return new Response(
-            Response.Status.valueOf(response.getErrorCodeValue()), response.getReason());
-      } else {
-        logError(
-            "Create collection failed\n{}\n{}", collectionMapping.toString(), response.toString());
-        return new Response(
-            Response.Status.valueOf(response.getErrorCodeValue()), response.getReason());
-      }
-    } catch (StatusRuntimeException e) {
-      logError("createCollection RPC failed:\n{}", e.getStatus().toString());
-      return new Response(Response.Status.RPC_ERROR, e.toString());
-    }
-  }
-
-  @Override
-  public HasCollectionResponse hasCollection(@Nonnull String collectionName) {
-
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return new HasCollectionResponse(new Response(Response.Status.CLIENT_NOT_CONNECTED), false);
-    }
-
-    CollectionName request = CollectionName.newBuilder().setCollectionName(collectionName).build();
-    BoolReply response;
-
-    try {
-      response = blockingStub().hasCollection(request);
-
-      if (response.getStatus().getErrorCode() == ErrorCode.SUCCESS) {
-        logInfo("hasCollection `{}` = {}", collectionName, response.getBoolReply());
-        return new HasCollectionResponse(
-            new Response(Response.Status.SUCCESS), response.getBoolReply());
-      } else {
-        logError("hasCollection `{}` failed:\n{}", collectionName, response.toString());
-        return new HasCollectionResponse(
-            new Response(
-                Response.Status.valueOf(response.getStatus().getErrorCodeValue()),
-                response.getStatus().getReason()),
-            false);
-      }
-    } catch (StatusRuntimeException e) {
-      logError("hasCollection RPC failed:\n{}", e.getStatus().toString());
-      return new HasCollectionResponse(
-          new Response(Response.Status.RPC_ERROR, e.toString()), false);
-    }
-  }
-
-  @Override
-  public Response dropCollection(@Nonnull String collectionName) {
-
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return new Response(Response.Status.CLIENT_NOT_CONNECTED);
-    }
-
-    CollectionName request = CollectionName.newBuilder().setCollectionName(collectionName).build();
-    Status response;
-
-    try {
-      response = blockingStub().dropCollection(request);
-
-      if (response.getErrorCode() == ErrorCode.SUCCESS) {
-        logInfo("Dropped collection `{}` successfully!", collectionName);
-        return new Response(Response.Status.SUCCESS);
-      } else {
-        logError("Drop collection `{}` failed:\n{}", collectionName, response.toString());
-        return new Response(
-            Response.Status.valueOf(response.getErrorCodeValue()), response.getReason());
-      }
-    } catch (StatusRuntimeException e) {
-      logError("dropCollection RPC failed:\n{}", e.getStatus().toString());
-      return new Response(Response.Status.RPC_ERROR, e.toString());
-    }
-  }
-
-  @Override
-  public Response createIndex(@Nonnull Index index) {
-
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return new Response(Response.Status.CLIENT_NOT_CONNECTED);
-    }
-
-    KeyValuePair extraParam =
-        KeyValuePair.newBuilder().setKey(extraParamKey).setValue(index.getParamsInJson()).build();
-    IndexParam request =
-        IndexParam.newBuilder()
-            .setCollectionName(index.getCollectionName())
-            .setIndexType(index.getIndexType().getVal())
-            .addExtraParams(extraParam)
-            .build();
-
-    Status response;
-
-    try {
-      response = blockingStub().createIndex(request);
-
-      if (response.getErrorCode() == ErrorCode.SUCCESS) {
-        logInfo("Created index successfully!\n{}", index.toString());
-        return new Response(Response.Status.SUCCESS);
-      } else {
-        logError("Create index failed:\n{}\n{}", index.toString(), response.toString());
-        return new Response(
-            Response.Status.valueOf(response.getErrorCodeValue()), response.getReason());
-      }
-    } catch (StatusRuntimeException e) {
-      logError("createIndex RPC failed:\n{}", e.getStatus().toString());
-      return new Response(Response.Status.RPC_ERROR, e.toString());
-    }
-  }
-
-  @Override
-  public ListenableFuture<Response> createIndexAsync(@Nonnull Index index) {
-
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return Futures.immediateFuture(new Response(Response.Status.CLIENT_NOT_CONNECTED));
-    }
-
-    KeyValuePair extraParam =
-        KeyValuePair.newBuilder().setKey(extraParamKey).setValue(index.getParamsInJson()).build();
-    IndexParam request =
-        IndexParam.newBuilder()
-            .setCollectionName(index.getCollectionName())
-            .setIndexType(index.getIndexType().getVal())
-            .addExtraParams(extraParam)
-            .build();
-
-    ListenableFuture<Status> response;
-
-    response = futureStub().createIndex(request);
-
-    Futures.addCallback(
-        response,
-        new FutureCallback<Status>() {
-          @Override
-          public void onSuccess(Status result) {
-            if (result.getErrorCode() == ErrorCode.SUCCESS) {
-              logInfo("Created index successfully!\n{}", index.toString());
-            } else {
-              logError("CreateIndexAsync failed:\n{}\n{}", index.toString(), result.toString());
-            }
-          }
-
-          @Override
-          public void onFailure(Throwable t) {
-            logError("CreateIndexAsync failed:\n{}", t.getMessage());
-          }
-        },
-        MoreExecutors.directExecutor());
-
-    return Futures.transform(
-        response, transformStatusToResponseFunc::apply, MoreExecutors.directExecutor());
-  }
-
-  @Override
-  public Response createPartition(String collectionName, String tag) {
-
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return new Response(Response.Status.CLIENT_NOT_CONNECTED);
-    }
-
-    PartitionParam request =
-        PartitionParam.newBuilder().setCollectionName(collectionName).setTag(tag).build();
-
-    Status response;
-
-    try {
-      response = blockingStub().createPartition(request);
-
-      if (response.getErrorCode() == ErrorCode.SUCCESS) {
-        logInfo("Created partition `{}` in collection `{}` successfully!", tag, collectionName);
-        return new Response(Response.Status.SUCCESS);
-      } else {
-        logError(
-            "Create partition `{}` in collection `{}` failed: {}",
-            tag,
-            collectionName,
-            response.toString());
-        return new Response(
-            Response.Status.valueOf(response.getErrorCodeValue()), response.getReason());
-      }
-    } catch (StatusRuntimeException e) {
-      logError("createPartition RPC failed:\n{}", e.getStatus().toString());
-      return new Response(Response.Status.RPC_ERROR, e.toString());
-    }
-  }
-
-  @Override
-  public HasPartitionResponse hasPartition(String collectionName, String tag) {
-
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return new HasPartitionResponse(new Response(Response.Status.CLIENT_NOT_CONNECTED), false);
-    }
-
-    PartitionParam request =
-        PartitionParam.newBuilder().setCollectionName(collectionName).setTag(tag).build();
-    BoolReply response;
-
-    try {
-      response = blockingStub().hasPartition(request);
-
-      if (response.getStatus().getErrorCode() == ErrorCode.SUCCESS) {
-        logInfo(
-            "hasPartition with tag `{}` in `{}` = {}",
-            tag,
-            collectionName,
-            response.getBoolReply());
-        return new HasPartitionResponse(
-            new Response(Response.Status.SUCCESS), response.getBoolReply());
-      } else {
-        logError(
-            "hasPartition with tag `{}` in `{}` failed:\n{}",
-            tag,
-            collectionName,
-            response.toString());
-        return new HasPartitionResponse(
-            new Response(
-                Response.Status.valueOf(response.getStatus().getErrorCodeValue()),
-                response.getStatus().getReason()),
-            false);
-      }
-    } catch (StatusRuntimeException e) {
-      logError("hasPartition RPC failed:\n{}", e.getStatus().toString());
-      return new HasPartitionResponse(new Response(Response.Status.RPC_ERROR, e.toString()), false);
-    }
-  }
-
-  @Override
-  public ListPartitionsResponse listPartitions(String collectionName) {
-
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return new ListPartitionsResponse(
-          new Response(Response.Status.CLIENT_NOT_CONNECTED), Collections.emptyList());
-    }
-
-    CollectionName request = CollectionName.newBuilder().setCollectionName(collectionName).build();
-    PartitionList response;
-
-    try {
-      response = blockingStub().showPartitions(request);
-
-      if (response.getStatus().getErrorCode() == ErrorCode.SUCCESS) {
-        logInfo(
-            "Current partitions of collection {}: {}",
-            collectionName,
-            response.getPartitionTagArrayList());
-        return new ListPartitionsResponse(
-            new Response(Response.Status.SUCCESS), response.getPartitionTagArrayList());
-      } else {
-        logError("List partitions failed:\n{}", response.toString());
-        return new ListPartitionsResponse(
-            new Response(
-                Response.Status.valueOf(response.getStatus().getErrorCodeValue()),
-                response.getStatus().getReason()),
-            Collections.emptyList());
-      }
-    } catch (StatusRuntimeException e) {
-      logError("listPartitions RPC failed:\n{}", e.getStatus().toString());
-      return new ListPartitionsResponse(
-          new Response(Response.Status.RPC_ERROR, e.toString()), Collections.emptyList());
-    }
-  }
-
-  @Override
-  public Response dropPartition(String collectionName, String tag) {
-
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return new Response(Response.Status.CLIENT_NOT_CONNECTED);
-    }
-
-    PartitionParam request =
-        PartitionParam.newBuilder().setCollectionName(collectionName).setTag(tag).build();
-    Status response;
-
-    try {
-      response = blockingStub().dropPartition(request);
-
-      if (response.getErrorCode() == ErrorCode.SUCCESS) {
-        logInfo("Dropped partition `{}` in collection `{}` successfully!", tag, collectionName);
-        return new Response(Response.Status.SUCCESS);
-      } else {
-        logError(
-            "Drop partition `{}` in collection `{}` failed:\n{}",
-            tag,
-            collectionName,
-            response.toString());
-        return new Response(
-            Response.Status.valueOf(response.getErrorCodeValue()), response.getReason());
-      }
-    } catch (StatusRuntimeException e) {
-      logError("dropPartition RPC failed:\n{}", e.getStatus().toString());
-      return new Response(Response.Status.RPC_ERROR, e.toString());
-    }
-  }
-
-  @Override
-  public InsertResponse insert(@Nonnull InsertParam insertParam) {
-
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return new InsertResponse(
-          new Response(Response.Status.CLIENT_NOT_CONNECTED), Collections.emptyList());
-    }
-
-    List<RowRecord> rowRecordList =
-        buildRowRecordList(insertParam.getFloatVectors(), insertParam.getBinaryVectors());
-
-    io.milvus.grpc.InsertParam request =
-        io.milvus.grpc.InsertParam.newBuilder()
-            .setCollectionName(insertParam.getCollectionName())
-            .addAllRowRecordArray(rowRecordList)
-            .addAllRowIdArray(insertParam.getVectorIds())
-            .setPartitionTag(insertParam.getPartitionTag())
-            .build();
-    VectorIds response;
-
-    try {
-      response = blockingStub().insert(request);
-
-      if (response.getStatus().getErrorCode() == ErrorCode.SUCCESS) {
-        logInfo(
-            "Inserted {} vectors to collection `{}` successfully!",
-            response.getVectorIdArrayCount(),
-            insertParam.getCollectionName());
-        return new InsertResponse(
-            new Response(Response.Status.SUCCESS), response.getVectorIdArrayList());
-      } else {
-        logError("Insert vectors failed:\n{}", response.getStatus().toString());
-        return new InsertResponse(
-            new Response(
-                Response.Status.valueOf(response.getStatus().getErrorCodeValue()),
-                response.getStatus().getReason()),
-            Collections.emptyList());
-      }
-    } catch (StatusRuntimeException e) {
-      logError("insert RPC failed:\n{}", e.getStatus().toString());
-      return new InsertResponse(
-          new Response(Response.Status.RPC_ERROR, e.toString()), Collections.emptyList());
-    }
-  }
-
-  @Override
-  public ListenableFuture<InsertResponse> insertAsync(@Nonnull InsertParam insertParam) {
-
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return Futures.immediateFuture(
-          new InsertResponse(
-              new Response(Response.Status.CLIENT_NOT_CONNECTED), Collections.emptyList()));
-    }
-
-    List<RowRecord> rowRecordList =
-        buildRowRecordList(insertParam.getFloatVectors(), insertParam.getBinaryVectors());
-
-    io.milvus.grpc.InsertParam request =
-        io.milvus.grpc.InsertParam.newBuilder()
-            .setCollectionName(insertParam.getCollectionName())
-            .addAllRowRecordArray(rowRecordList)
-            .addAllRowIdArray(insertParam.getVectorIds())
-            .setPartitionTag(insertParam.getPartitionTag())
-            .build();
-
-    ListenableFuture<VectorIds> response;
-
-    response = futureStub().insert(request);
-
-    Futures.addCallback(
-        response,
-        new FutureCallback<VectorIds>() {
-          @Override
-          public void onSuccess(VectorIds result) {
-            if (result.getStatus().getErrorCode() == ErrorCode.SUCCESS) {
-              logInfo(
-                  "Inserted {} vectors to collection `{}` successfully!",
-                  result.getVectorIdArrayCount(),
-                  insertParam.getCollectionName());
-            } else {
-              logError("InsertAsync failed:\n{}", result.getStatus().toString());
-            }
-          }
-
-          @Override
-          public void onFailure(Throwable t) {
-            logError("InsertAsync failed:\n{}", t.getMessage());
-          }
-        },
-        MoreExecutors.directExecutor());
-
-    Function<VectorIds, InsertResponse> transformFunc =
-        vectorIds -> {
-          if (vectorIds.getStatus().getErrorCode() == ErrorCode.SUCCESS) {
-            return new InsertResponse(
-                new Response(Response.Status.SUCCESS), vectorIds.getVectorIdArrayList());
-          } else {
-            return new InsertResponse(
-                new Response(
-                    Response.Status.valueOf(vectorIds.getStatus().getErrorCodeValue()),
-                    vectorIds.getStatus().getReason()),
-                Collections.emptyList());
-          }
-        };
-
-    return Futures.transform(response, transformFunc::apply, MoreExecutors.directExecutor());
-  }
-
-  @Override
-  public SearchResponse search(@Nonnull SearchParam searchParam) {
-
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      SearchResponse searchResponse = new SearchResponse();
-      searchResponse.setResponse(new Response(Response.Status.CLIENT_NOT_CONNECTED));
-      return searchResponse;
-    }
-
-    List<RowRecord> rowRecordList =
-        buildRowRecordList(searchParam.getFloatVectors(), searchParam.getBinaryVectors());
-
-    KeyValuePair extraParam =
-        KeyValuePair.newBuilder()
-            .setKey(extraParamKey)
-            .setValue(searchParam.getParamsInJson())
-            .build();
-
-    io.milvus.grpc.SearchParam request =
-        io.milvus.grpc.SearchParam.newBuilder()
-            .setCollectionName(searchParam.getCollectionName())
-            .addAllQueryRecordArray(rowRecordList)
-            .addAllPartitionTagArray(searchParam.getPartitionTags())
-            .setTopk(searchParam.getTopK())
-            .addExtraParams(extraParam)
-            .build();
-
-    TopKQueryResult response;
-
-    try {
-      response = blockingStub().search(request);
-
-      if (response.getStatus().getErrorCode() == ErrorCode.SUCCESS) {
-        SearchResponse searchResponse = buildSearchResponse(response);
-        searchResponse.setResponse(new Response(Response.Status.SUCCESS));
-        logInfo(
-            "Search completed successfully! Returned results for {} queries",
-            searchResponse.getNumQueries());
-        return searchResponse;
-      } else {
-        logError("Search failed:\n{}", response.getStatus().toString());
-        SearchResponse searchResponse = new SearchResponse();
-        searchResponse.setResponse(
-            new Response(
-                Response.Status.valueOf(response.getStatus().getErrorCodeValue()),
-                response.getStatus().getReason()));
-        return searchResponse;
-      }
-    } catch (StatusRuntimeException e) {
-      logError("search RPC failed:\n{}", e.getStatus().toString());
-      SearchResponse searchResponse = new SearchResponse();
-      searchResponse.setResponse(new Response(Response.Status.RPC_ERROR, e.toString()));
-      return searchResponse;
-    }
-  }
-
-  @Override
-  public ListenableFuture<SearchResponse> searchAsync(@Nonnull SearchParam searchParam) {
-
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      SearchResponse searchResponse = new SearchResponse();
-      searchResponse.setResponse(new Response(Response.Status.CLIENT_NOT_CONNECTED));
-      return Futures.immediateFuture(searchResponse);
-    }
-
-    List<RowRecord> rowRecordList =
-        buildRowRecordList(searchParam.getFloatVectors(), searchParam.getBinaryVectors());
-
-    KeyValuePair extraParam =
-        KeyValuePair.newBuilder()
-            .setKey(extraParamKey)
-            .setValue(searchParam.getParamsInJson())
-            .build();
-
-    io.milvus.grpc.SearchParam request =
-        io.milvus.grpc.SearchParam.newBuilder()
-            .setCollectionName(searchParam.getCollectionName())
-            .addAllQueryRecordArray(rowRecordList)
-            .addAllPartitionTagArray(searchParam.getPartitionTags())
-            .setTopk(searchParam.getTopK())
-            .addExtraParams(extraParam)
-            .build();
-
-    ListenableFuture<TopKQueryResult> response;
-
-    response = futureStub().search(request);
-
-    Futures.addCallback(
-        response,
-        new FutureCallback<TopKQueryResult>() {
-          @Override
-          public void onSuccess(TopKQueryResult result) {
-            if (result.getStatus().getErrorCode() == ErrorCode.SUCCESS) {
-              logInfo(
-                  "SearchAsync completed successfully! Returned results for {} queries",
-                  result.getRowNum());
-            } else {
-              logError("SearchAsync failed:\n{}", result.getStatus().toString());
-            }
-          }
-
-          @Override
-          public void onFailure(Throwable t) {
-            logError("SearchAsync failed:\n{}", t.getMessage());
-          }
-        },
-        MoreExecutors.directExecutor());
-
-    Function<TopKQueryResult, SearchResponse> transformFunc =
-        topKQueryResult -> {
-          if (topKQueryResult.getStatus().getErrorCode() == ErrorCode.SUCCESS) {
-            SearchResponse searchResponse = buildSearchResponse(topKQueryResult);
-            searchResponse.setResponse(new Response(Response.Status.SUCCESS));
-            return searchResponse;
-          } else {
-            SearchResponse searchResponse = new SearchResponse();
-            searchResponse.setResponse(
-                new Response(
-                    Response.Status.valueOf(topKQueryResult.getStatus().getErrorCodeValue()),
-                    topKQueryResult.getStatus().getReason()));
-            return searchResponse;
-          }
-        };
-
-    return Futures.transform(response, transformFunc::apply, MoreExecutors.directExecutor());
-  }
-
-  @Override
-  public GetCollectionInfoResponse getCollectionInfo(@Nonnull String collectionName) {
-
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return new GetCollectionInfoResponse(
-          new Response(Response.Status.CLIENT_NOT_CONNECTED), null);
-    }
-
-    CollectionName request = CollectionName.newBuilder().setCollectionName(collectionName).build();
-    CollectionSchema response;
-
-    try {
-      response = blockingStub().describeCollection(request);
-
-      if (response.getStatus().getErrorCode() == ErrorCode.SUCCESS) {
-        CollectionMapping collectionMapping =
-            new CollectionMapping.Builder(response.getCollectionName(), response.getDimension())
-                .withIndexFileSize(response.getIndexFileSize())
-                .withMetricType(MetricType.valueOf(response.getMetricType()))
-                .build();
-        logInfo("Get Collection Info `{}` returned:\n{}", collectionName, collectionMapping);
-        return new GetCollectionInfoResponse(
-            new Response(Response.Status.SUCCESS), collectionMapping);
-      } else {
-        logError(
-            "Get Collection Info `{}` failed:\n{}",
-            collectionName,
-            response.getStatus().toString());
-        return new GetCollectionInfoResponse(
-            new Response(
-                Response.Status.valueOf(response.getStatus().getErrorCodeValue()),
-                response.getStatus().getReason()),
-            null);
-      }
-    } catch (StatusRuntimeException e) {
-      logError("getCollectionInfo RPC failed:\n{}", e.getStatus().toString());
-      return new GetCollectionInfoResponse(
-          new Response(Response.Status.RPC_ERROR, e.toString()), null);
-    }
-  }
-
-  @Override
-  public ListCollectionsResponse listCollections() {
-
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return new ListCollectionsResponse(
-          new Response(Response.Status.CLIENT_NOT_CONNECTED), Collections.emptyList());
-    }
-
-    Command request = Command.newBuilder().setCmd("").build();
-    CollectionNameList response;
-
-    try {
-      response = blockingStub().showCollections(request);
-
-      if (response.getStatus().getErrorCode() == ErrorCode.SUCCESS) {
-        List<String> collectionNames = response.getCollectionNamesList();
-        logInfo("Current collections: {}", collectionNames.toString());
-        return new ListCollectionsResponse(new Response(Response.Status.SUCCESS), collectionNames);
-      } else {
-        logError("List collections failed:\n{}", response.getStatus().toString());
-        return new ListCollectionsResponse(
-            new Response(
-                Response.Status.valueOf(response.getStatus().getErrorCodeValue()),
-                response.getStatus().getReason()),
-            Collections.emptyList());
-      }
-    } catch (StatusRuntimeException e) {
-      logError("listCollections RPC failed:\n{}", e.getStatus().toString());
-      return new ListCollectionsResponse(
-          new Response(Response.Status.RPC_ERROR, e.toString()), Collections.emptyList());
-    }
-  }
-
-  @Override
-  public CountEntitiesResponse countEntities(@Nonnull String collectionName) {
-
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return new CountEntitiesResponse(new Response(Response.Status.CLIENT_NOT_CONNECTED), 0);
-    }
-
-    CollectionName request = CollectionName.newBuilder().setCollectionName(collectionName).build();
-    CollectionRowCount response;
-
-    try {
-      response = blockingStub().countCollection(request);
-
-      if (response.getStatus().getErrorCode() == ErrorCode.SUCCESS) {
-        long collectionRowCount = response.getCollectionRowCount();
-        logInfo("Collection `{}` has {} entities", collectionName, collectionRowCount);
-        return new CountEntitiesResponse(new Response(Response.Status.SUCCESS), collectionRowCount);
-      } else {
-        logError(
-            "Get collection `{}` entity count failed:\n{}",
-            collectionName,
-            response.getStatus().toString());
-        return new CountEntitiesResponse(
-            new Response(
-                Response.Status.valueOf(response.getStatus().getErrorCodeValue()),
-                response.getStatus().getReason()),
-            0);
-      }
-    } catch (StatusRuntimeException e) {
-      logError("countEntities RPC failed:\n{}", e.getStatus().toString());
-      return new CountEntitiesResponse(new Response(Response.Status.RPC_ERROR, e.toString()), 0);
-    }
-  }
-
-  @Override
-  public Response getServerStatus() {
-    return command("status");
-  }
-
-  @Override
-  public Response getServerVersion() {
-    return command("version");
-  }
-
-  public Response command(@Nonnull String command) {
-
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return new Response(Response.Status.CLIENT_NOT_CONNECTED);
-    }
-
-    Command request = Command.newBuilder().setCmd(command).build();
-    StringReply response;
-
-    try {
-      response = blockingStub().cmd(request);
-
-      if (response.getStatus().getErrorCode() == ErrorCode.SUCCESS) {
-        logInfo("Command `{}`: {}", command, response.getStringReply());
-        return new Response(Response.Status.SUCCESS, response.getStringReply());
-      } else {
-        logError("Command `{}` failed:\n{}", command, response.toString());
-        return new Response(
-            Response.Status.valueOf(response.getStatus().getErrorCodeValue()),
-            response.getStatus().getReason());
-      }
-    } catch (StatusRuntimeException e) {
-      logError("Command RPC failed:\n{}", e.getStatus().toString());
-      return new Response(Response.Status.RPC_ERROR, e.toString());
-    }
-  }
-
-  @Override
-  public Response loadCollection(@Nonnull String collectionName) {
-    return loadCollection(collectionName, new ArrayList<>());
-  }
-
-  @Override
-  public Response loadCollection(@Nonnull String collectionName, List<String> partitionTags) {
-
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return new Response(Response.Status.CLIENT_NOT_CONNECTED);
-    }
-
-    PreloadCollectionParam request =
-        PreloadCollectionParam.newBuilder()
-            .setCollectionName(collectionName)
-            .addAllPartitionTagArray(partitionTags)
-            .build();
-    Status response;
-
-    try {
-      response = blockingStub().preloadCollection(request);
-
-      if (response.getErrorCode() == ErrorCode.SUCCESS) {
-        logInfo("Loaded collection `{}` successfully!", collectionName);
-        return new Response(Response.Status.SUCCESS);
-      } else {
-        logError("Load collection `{}` failed:\n{}", collectionName, response.toString());
-        return new Response(
-            Response.Status.valueOf(response.getErrorCodeValue()), response.getReason());
-      }
-    } catch (StatusRuntimeException e) {
-      logError("loadCollection RPC failed:\n{}", e.getStatus().toString());
-      return new Response(Response.Status.RPC_ERROR, e.toString());
-    }
-  }
-
-  @Override
-  public GetIndexInfoResponse getIndexInfo(@Nonnull String collectionName) {
-
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return new GetIndexInfoResponse(new Response(Response.Status.CLIENT_NOT_CONNECTED), null);
-    }
-
-    CollectionName request = CollectionName.newBuilder().setCollectionName(collectionName).build();
-    IndexParam response;
-
-    try {
-      response = blockingStub().describeIndex(request);
-
-      if (response.getStatus().getErrorCode() == ErrorCode.SUCCESS) {
-        String extraParam = "";
-        for (KeyValuePair kv : response.getExtraParamsList()) {
-          if (kv.getKey().contentEquals(extraParamKey)) {
-            extraParam = kv.getValue();
-          }
-        }
-        Index index =
-            new Index.Builder(
-                    response.getCollectionName(), IndexType.valueOf(response.getIndexType()))
-                .withParamsInJson(extraParam)
-                .build();
-        logInfo(
-            "Get index info for collection `{}` returned:\n{}", collectionName, index.toString());
-        return new GetIndexInfoResponse(new Response(Response.Status.SUCCESS), index);
-      } else {
-        logError(
-            "Get index info for collection `{}` failed:\n{}",
-            collectionName,
-            response.getStatus().toString());
-        return new GetIndexInfoResponse(
-            new Response(
-                Response.Status.valueOf(response.getStatus().getErrorCodeValue()),
-                response.getStatus().getReason()),
-            null);
-      }
-    } catch (StatusRuntimeException e) {
-      logError("getIndexInfo RPC failed:\n{}", e.getStatus().toString());
-      return new GetIndexInfoResponse(new Response(Response.Status.RPC_ERROR, e.toString()), null);
-    }
-  }
-
-  @Override
-  public Response dropIndex(@Nonnull String collectionName) {
-
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return new Response(Response.Status.CLIENT_NOT_CONNECTED);
-    }
-
-    CollectionName request = CollectionName.newBuilder().setCollectionName(collectionName).build();
-    Status response;
-
-    try {
-      response = blockingStub().dropIndex(request);
-
-      if (response.getErrorCode() == ErrorCode.SUCCESS) {
-        logInfo("Dropped index for collection `{}` successfully!", collectionName);
-        return new Response(Response.Status.SUCCESS);
-      } else {
-        logError("Drop index for collection `{}` failed:\n{}", collectionName, response.toString());
-        return new Response(
-            Response.Status.valueOf(response.getErrorCodeValue()), response.getReason());
-      }
-    } catch (StatusRuntimeException e) {
-      logError("dropIndex RPC failed:\n{}", e.getStatus().toString());
-      return new Response(Response.Status.RPC_ERROR, e.toString());
-    }
-  }
-
-  @Override
-  public Response getCollectionStats(String collectionName) {
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return new Response(Response.Status.CLIENT_NOT_CONNECTED);
-    }
-
-    CollectionName request = CollectionName.newBuilder().setCollectionName(collectionName).build();
-    io.milvus.grpc.CollectionInfo response;
-
-    try {
-      response = blockingStub().showCollectionInfo(request);
-
-      if (response.getStatus().getErrorCode() == ErrorCode.SUCCESS) {
-        logInfo("getCollectionStats for `{}` returned successfully!", collectionName);
-        return new Response(Response.Status.SUCCESS, response.getJsonInfo());
-      } else {
-        logError(
-            "getCollectionStats for `{}` failed:\n{}",
-            collectionName,
-            response.getStatus().toString());
-        return new Response(
-            Response.Status.valueOf(response.getStatus().getErrorCodeValue()),
-            response.getStatus().getReason());
-      }
-    } catch (StatusRuntimeException e) {
-      logError("getCollectionStats RPC failed:\n{}", e.getStatus().toString());
-      return new Response(Response.Status.RPC_ERROR, e.toString());
-    }
-  }
-
-  @Override
-  public GetEntityByIDResponse getEntityByID(String collectionName, List<Long> ids) {
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return new GetEntityByIDResponse(
-          new Response(Response.Status.CLIENT_NOT_CONNECTED), Collections.emptyList(), null);
-    }
-
-    VectorsIdentity request =
-        VectorsIdentity.newBuilder().setCollectionName(collectionName).addAllIdArray(ids).build();
-    VectorsData response;
-
-    try {
-      response = blockingStub().getVectorsByID(request);
-
-      if (response.getStatus().getErrorCode() == ErrorCode.SUCCESS) {
-
-        logInfo("getEntityByID in collection `{}` returned successfully!", collectionName);
-
-        List<List<Float>> floatVectors = new ArrayList<>(ids.size());
-        List<ByteBuffer> binaryVectors = new ArrayList<>(ids.size());
-        for (int i = 0; i < ids.size(); i++) {
-          floatVectors.add(response.getVectorsData(i).getFloatDataList());
-          binaryVectors.add(response.getVectorsData(i).getBinaryData().asReadOnlyByteBuffer());
-        }
-        return new GetEntityByIDResponse(
-            new Response(Response.Status.SUCCESS), floatVectors, binaryVectors);
-
-      } else {
-        logError(
-            "getEntityByID in collection `{}` failed:\n{}",
-            collectionName,
-            response.getStatus().toString());
-        return new GetEntityByIDResponse(
-            new Response(
-                Response.Status.valueOf(response.getStatus().getErrorCodeValue()),
-                response.getStatus().getReason()),
-            Collections.emptyList(),
-            null);
-      }
-    } catch (StatusRuntimeException e) {
-      logError("getEntityByID RPC failed:\n{}", e.getStatus().toString());
-      return new GetEntityByIDResponse(
-          new Response(Response.Status.RPC_ERROR, e.toString()), Collections.emptyList(), null);
-    }
-  }
-
-  @Override
-  public ListIDInSegmentResponse listIDInSegment(String collectionName, String segmentName) {
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return new ListIDInSegmentResponse(
-          new Response(Response.Status.CLIENT_NOT_CONNECTED), Collections.emptyList());
-    }
-
-    GetVectorIDsParam request =
-        GetVectorIDsParam.newBuilder()
-            .setCollectionName(collectionName)
-            .setSegmentName(segmentName)
-            .build();
-    VectorIds response;
-
-    try {
-      response = blockingStub().getVectorIDs(request);
-
-      if (response.getStatus().getErrorCode() == ErrorCode.SUCCESS) {
-
-        logInfo(
-            "listIDInSegment in collection `{}`, segment `{}` returned successfully!",
-            collectionName,
-            segmentName);
-        return new ListIDInSegmentResponse(
-            new Response(Response.Status.SUCCESS), response.getVectorIdArrayList());
-      } else {
-        logError(
-            "listIDInSegment in collection `{}`, segment `{}` failed:\n{}",
-            collectionName,
-            segmentName,
-            response.getStatus().toString());
-        return new ListIDInSegmentResponse(
-            new Response(
-                Response.Status.valueOf(response.getStatus().getErrorCodeValue()),
-                response.getStatus().getReason()),
-            Collections.emptyList());
-      }
-    } catch (StatusRuntimeException e) {
-      logError("listIDInSegment RPC failed:\n{}", e.getStatus().toString());
-      return new ListIDInSegmentResponse(
-          new Response(Response.Status.RPC_ERROR, e.toString()), Collections.emptyList());
-    }
-  }
-
-  @Override
-  public Response deleteEntityByID(String collectionName, List<Long> ids) {
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return new Response(Response.Status.CLIENT_NOT_CONNECTED);
-    }
-
-    DeleteByIDParam request =
-        DeleteByIDParam.newBuilder().setCollectionName(collectionName).addAllIdArray(ids).build();
-    Status response;
-
-    try {
-      response = blockingStub().deleteByID(request);
-
-      if (response.getErrorCode() == ErrorCode.SUCCESS) {
-        logInfo("deleteEntityByID in collection `{}` completed successfully!", collectionName);
-        return new Response(Response.Status.SUCCESS);
-      } else {
-        logError(
-            "deleteEntityByID in collection `{}` failed:\n{}", collectionName, response.toString());
-        return new Response(
-            Response.Status.valueOf(response.getErrorCodeValue()), response.getReason());
-      }
-    } catch (StatusRuntimeException e) {
-      logError("deleteEntityByID RPC failed:\n{}", e.getStatus().toString());
-      return new Response(Response.Status.RPC_ERROR, e.toString());
-    }
-  }
-
-  @Override
-  public Response flush(List<String> collectionNames) {
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return new Response(Response.Status.CLIENT_NOT_CONNECTED);
-    }
-
-    FlushParam request = FlushParam.newBuilder().addAllCollectionNameArray(collectionNames).build();
-    Status response;
-
-    try {
-      response = blockingStub().flush(request);
-
-      if (response.getErrorCode() == ErrorCode.SUCCESS) {
-        logInfo("Flushed collection {} successfully!", collectionNames);
-        return new Response(Response.Status.SUCCESS);
-      } else {
-        logError("Flush collection {} failed:\n{}", collectionNames, response.toString());
-        return new Response(
-            Response.Status.valueOf(response.getErrorCodeValue()), response.getReason());
-      }
-    } catch (StatusRuntimeException e) {
-      logError("flush RPC failed:\n{}", e.getStatus().toString());
-      return new Response(Response.Status.RPC_ERROR, e.toString());
-    }
-  }
-
-  @Override
-  public ListenableFuture<Response> flushAsync(@Nonnull List<String> collectionNames) {
-
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return Futures.immediateFuture(new Response(Response.Status.CLIENT_NOT_CONNECTED));
-    }
-
-    FlushParam request = FlushParam.newBuilder().addAllCollectionNameArray(collectionNames).build();
-
-    ListenableFuture<Status> response;
-
-    response = futureStub().flush(request);
-
-    Futures.addCallback(
-        response,
-        new FutureCallback<Status>() {
-          @Override
-          public void onSuccess(Status result) {
-            if (result.getErrorCode() == ErrorCode.SUCCESS) {
-              logInfo("Flushed collection {} successfully!", collectionNames);
-            } else {
-              logError("Flush collection {} failed:\n{}", collectionNames, result.toString());
-            }
-          }
-
-          @Override
-          public void onFailure(Throwable t) {
-            logError("FlushAsync failed:\n{}", t.getMessage());
-          }
-        },
-        MoreExecutors.directExecutor());
-
-    return Futures.transform(
-        response, transformStatusToResponseFunc::apply, MoreExecutors.directExecutor());
-  }
-
-  @Override
-  public Response flush(String collectionName) {
-    List<String> list =
-        new ArrayList<String>() {
-          {
-            add(collectionName);
-          }
-        };
-    return flush(list);
-  }
-
-  @Override
-  public ListenableFuture<Response> flushAsync(String collectionName) {
-    List<String> list =
-        new ArrayList<String>() {
-          {
-            add(collectionName);
-          }
-        };
-    return flushAsync(list);
-  }
-
-  @Override
-  public Response compact(String collectionName) {
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return new Response(Response.Status.CLIENT_NOT_CONNECTED);
-    }
-
-    CollectionName request = CollectionName.newBuilder().setCollectionName(collectionName).build();
-    Status response;
-
-    try {
-      response = blockingStub().compact(request);
-
-      if (response.getErrorCode() == ErrorCode.SUCCESS) {
-        logInfo("Compacted collection `{}` successfully!", collectionName);
-        return new Response(Response.Status.SUCCESS);
-      } else {
-        logError("Compact collection `{}` failed:\n{}", collectionName, response.toString());
-        return new Response(
-            Response.Status.valueOf(response.getErrorCodeValue()), response.getReason());
-      }
-    } catch (StatusRuntimeException e) {
-      logError("compact RPC failed:\n{}", e.getStatus().toString());
-      return new Response(Response.Status.RPC_ERROR, e.toString());
-    }
-  }
-
-  @Override
-  public ListenableFuture<Response> compactAsync(@Nonnull String collectionName) {
-
-    if (!maybeAvailable()) {
-      logWarning("You are not connected to Milvus server");
-      return Futures.immediateFuture(new Response(Response.Status.CLIENT_NOT_CONNECTED));
-    }
-
-    CollectionName request = CollectionName.newBuilder().setCollectionName(collectionName).build();
-
-    ListenableFuture<Status> response;
-
-    response = futureStub().compact(request);
-
-    Futures.addCallback(
-        response,
-        new FutureCallback<Status>() {
-          @Override
-          public void onSuccess(Status result) {
-            if (result.getErrorCode() == ErrorCode.SUCCESS) {
-              logInfo("Compacted collection `{}` successfully!", collectionName);
-            } else {
-              logError("Compact collection `{}` failed:\n{}", collectionName, result.toString());
-            }
-          }
-
-          @Override
-          public void onFailure(Throwable t) {
-            logError("CompactAsync failed:\n{}", t.getMessage());
-          }
-        },
-        MoreExecutors.directExecutor());
-
-    return Futures.transform(
-        response, transformStatusToResponseFunc::apply, MoreExecutors.directExecutor());
-  }
-
-  ///////////////////// Util Functions/////////////////////
-  Function<Status, Response> transformStatusToResponseFunc =
-      status -> {
-        if (status.getErrorCode() == ErrorCode.SUCCESS) {
-          return new Response(Response.Status.SUCCESS);
-        } else {
-          return new Response(
-              Response.Status.valueOf(status.getErrorCodeValue()), status.getReason());
-        }
-      };
-
-  private List<RowRecord> buildRowRecordList(
-      @Nonnull List<List<Float>> floatVectors, @Nonnull List<ByteBuffer> binaryVectors) {
-    int largerSize = Math.max(floatVectors.size(), binaryVectors.size());
-    
-    List<RowRecord> rowRecordList = new ArrayList<>(largerSize); 
-
-    for (int i = 0; i < largerSize; ++i) {
-
-      RowRecord.Builder rowRecordBuilder = RowRecord.newBuilder();
-
-      if (i < floatVectors.size()) {
-        rowRecordBuilder.addAllFloatData(floatVectors.get(i));
-      }
-      if (i < binaryVectors.size()) {
-        ((Buffer) binaryVectors.get(i)).rewind();
-        rowRecordBuilder.setBinaryData(ByteString.copyFrom(binaryVectors.get(i)));
-      }
-
-      rowRecordList.add(rowRecordBuilder.build());
-    }
-
-    return rowRecordList;
-  }
-
-  private SearchResponse buildSearchResponse(TopKQueryResult topKQueryResult) {
-
-    final int numQueries = (int) topKQueryResult.getRowNum();
-    final int topK =
-        numQueries == 0
-            ? 0
-            : topKQueryResult.getIdsCount()
-                / numQueries; // Guaranteed to be divisible from server side
-
-    List<List<Long>> resultIdsList = new ArrayList<>(numQueries);
-    List<List<Float>> resultDistancesList = new ArrayList<>(numQueries);
-
-    if (topK > 0) {
-      for (int i = 0; i < numQueries; i++) {
-        // Process result of query i
-        int pos = i * topK;
-        while (pos < i * topK + topK && topKQueryResult.getIdsList().get(pos) != -1) {
-          pos++;
-        }
-        resultIdsList.add(topKQueryResult.getIdsList().subList(i * topK, pos));
-        resultDistancesList.add(topKQueryResult.getDistancesList().subList(i * topK, pos));
-      }
-    }
-
-    SearchResponse searchResponse = new SearchResponse();
-    searchResponse.setNumQueries(numQueries);
-    searchResponse.setTopK(topK);
-    searchResponse.setResultIdsList(resultIdsList);
-    searchResponse.setResultDistancesList(resultDistancesList);
-
-    return searchResponse;
-  }
-
-  ///////////////////// Log Functions//////////////////////
-
-  private void logInfo(String msg, Object... params) {
-    logger.info(msg, params);
-  }
-
-  private void logWarning(String msg, Object... params) {
-    logger.warn(msg, params);
-  }
-
-  private void logError(String msg, Object... params) {
-    logger.error(msg, params);
-  }
-}

+ 0 - 115
src/main/java/io/milvus/client/Response.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.client;
-
-import java.util.Arrays;
-import java.util.Optional;
-
-/**
- * Represents response of a client call. Contains a <code>status</code> and a <code>message</code>
- */
-public class Response {
-
-  private final Status status;
-  private final String message;
-
-  public Response(Status status, String message) {
-    this.status = status;
-    this.message = message;
-  }
-
-  public Response(Status status) {
-    this.status = status;
-    if (status == Status.CLIENT_NOT_CONNECTED) {
-      this.message = "You are not connected to Milvus server";
-    } else {
-      this.message = "Success!";
-    }
-  }
-
-  public Status getStatus() {
-    return status;
-  }
-
-  public String getMessage() {
-    return message;
-  }
-
-  /** @return <code>true</code> if status equals SUCCESS */
-  public boolean ok() {
-    return status == Status.SUCCESS;
-  }
-
-  @Override
-  public String toString() {
-    return String.format("Response {code = %s, message = \"%s\"}", status.name(), this.message);
-  }
-
-  /** Represents server and client side status code */
-  public enum Status {
-    // Server side error
-    SUCCESS(0),
-    UNEXPECTED_ERROR(1),
-    CONNECT_FAILED(2),
-    PERMISSION_DENIED(3),
-    COLLECTION_NOT_EXISTS(4),
-    ILLEGAL_ARGUMENT(5),
-    ILLEGAL_DIMENSION(7),
-    ILLEGAL_INDEX_TYPE(8),
-    ILLEGAL_COLLECTION_NAME(9),
-    ILLEGAL_TOPK(10),
-    ILLEGAL_ROWRECORD(11),
-    ILLEGAL_VECTOR_ID(12),
-    ILLEGAL_SEARCH_RESULT(13),
-    FILE_NOT_FOUND(14),
-    META_FAILED(15),
-    CACHE_FAILED(16),
-    CANNOT_CREATE_FOLDER(17),
-    CANNOT_CREATE_FILE(18),
-    CANNOT_DELETE_FOLDER(19),
-    CANNOT_DELETE_FILE(20),
-    BUILD_INDEX_ERROR(21),
-    ILLEGAL_NLIST(22),
-    ILLEGAL_METRIC_TYPE(23),
-    OUT_OF_MEMORY(24),
-
-    // Client side error
-    RPC_ERROR(-1),
-    CLIENT_NOT_CONNECTED(-2),
-    UNKNOWN(-3),
-    VERSION_MISMATCH(-4);
-
-    private final int code;
-
-    Status(int code) {
-      this.code = code;
-    }
-
-    public static Status valueOf(int val) {
-      Optional<Status> search =
-          Arrays.stream(values()).filter(status -> status.code == val).findFirst();
-      return search.orElse(UNKNOWN);
-    }
-
-    public int getCode() {
-      return code;
-    }
-  }
-}

+ 0 - 170
src/main/java/io/milvus/client/SearchParam.java

@@ -1,170 +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.client;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
-import javax.annotation.Nonnull;
-
-/** Contains parameters for <code>search</code> */
-public class SearchParam {
-
-  private final String collectionName;
-  private final List<List<Float>> floatVectors;
-  private final List<ByteBuffer> binaryVectors;
-  private final List<String> partitionTags;
-  private final long topK;
-  private final String paramsInJson;
-
-  private SearchParam(@Nonnull Builder builder) {
-    this.collectionName = builder.collectionName;
-    this.floatVectors = builder.floatVectors;
-    this.binaryVectors = builder.binaryVectors;
-    this.partitionTags = builder.partitionTags;
-    this.topK = builder.topK;
-    this.paramsInJson = builder.paramsInJson;
-  }
-
-  public String getCollectionName() {
-    return collectionName;
-  }
-
-  public List<List<Float>> getFloatVectors() {
-    return floatVectors;
-  }
-
-  public List<ByteBuffer> getBinaryVectors() {
-    return binaryVectors;
-  }
-
-  public List<String> getPartitionTags() {
-    return partitionTags;
-  }
-
-  public long getTopK() {
-    return topK;
-  }
-
-  public String getParamsInJson() {
-    return paramsInJson;
-  }
-
-  /** Builder for <code>SearchParam</code> */
-  public static class Builder {
-    // Required parameters
-    private final String collectionName;
-
-    // Optional parameters - initialized to default values
-    private List<List<Float>> floatVectors = new ArrayList<>();
-    private List<ByteBuffer> binaryVectors = new ArrayList<>();
-    private List<String> partitionTags = new ArrayList<>();
-    private long topK = 1024;
-    private String paramsInJson;
-
-    /** @param collectionName collection to search from */
-    public Builder(@Nonnull String collectionName) {
-      this.collectionName = collectionName;
-    }
-
-    /**
-     * Default to an empty <code>ArrayList</code>. You can search either float or binary vectors,
-     * not both.
-     *
-     * @param floatVectors a <code>List</code> of float vectors to be queries. Each inner <code>List
-     *     </code> represents a float vector.
-     * @return <code>Builder</code>
-     */
-    public SearchParam.Builder withFloatVectors(@Nonnull List<List<Float>> floatVectors) {
-      this.floatVectors = floatVectors;
-      return this;
-    }
-
-    /**
-     * Default to an empty <code>ArrayList</code>. You can search either float or binary vectors,
-     * not both.
-     *
-     * @param binaryVectors a <code>List</code> of binary vectors to be queried. Each <code>
-     *     ByteBuffer</code> object represents a binary vector, with every 8 bits constituting a
-     *     byte.
-     * @return <code>Builder</code>
-     * @see ByteBuffer
-     */
-    public SearchParam.Builder withBinaryVectors(@Nonnull List<ByteBuffer> binaryVectors) {
-      this.binaryVectors = binaryVectors;
-      return this;
-    }
-
-    /**
-     * Optional. Search vectors with corresponding <code>partitionTags</code>. Default to an empty
-     * <code>List</code>
-     *
-     * @param partitionTags a <code>List</code> of partition tags
-     * @return <code>Builder</code>
-     */
-    public Builder withPartitionTags(@Nonnull List<String> partitionTags) {
-      this.partitionTags = partitionTags;
-      return this;
-    }
-
-    /**
-     * Optional. Limits search result to <code>topK</code>. Default to 1024.
-     *
-     * @param topK a topK number
-     * @return <code>Builder</code>
-     */
-    public Builder withTopK(long topK) {
-      this.topK = topK;
-      return this;
-    }
-
-    /**
-     * Optional. Default to empty <code>String</code>. Search parameters are different for different
-     * index types. Refer to <a
-     * href="https://milvus.io/docs/milvus_operation.md">https://milvus.io/docs/milvus_operation.md</a>
-     * for more information.
-     *
-     * <pre>
-     *   FLAT/IVFLAT/SQ8/IVFPQ: {"nprobe": 32}
-     *   nprobe range:[1,999999]
-     *
-     *   NSG: {"search_length": 100}
-     *   search_length range:[10, 300]
-     *
-     *   HNSW: {"ef": 64}
-     *   ef range:[topk, 4096]
-     *
-     *   ANNOY: {search_k", 0.05 * totalDataCount}
-     *   search_k range: none
-     * </pre>
-     *
-     * @param paramsInJson extra parameters in JSON format
-     * @return <code>Builder</code>
-     */
-    public SearchParam.Builder withParamsInJson(@Nonnull String paramsInJson) {
-      this.paramsInJson = paramsInJson;
-      return this;
-    }
-
-    public SearchParam build() {
-      return new SearchParam(this);
-    }
-  }
-}

+ 0 - 137
src/main/java/io/milvus/client/SearchResponse.java

@@ -1,137 +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.client;
-
-import java.util.List;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-import java.util.stream.LongStream;
-
-/**
- * Contains the returned <code>response</code> and <code>queryResultsList</code> for <code>search
- * </code>
- */
-public class SearchResponse {
-
-  private Response response;
-  private int numQueries;
-  private long topK;
-  private List<List<Long>> resultIdsList;
-  private List<List<Float>> resultDistancesList;
-
-  public int getNumQueries() {
-    return numQueries;
-  }
-
-  void setNumQueries(int numQueries) {
-    this.numQueries = numQueries;
-  }
-
-  public long getTopK() {
-    return topK;
-  }
-
-  void setTopK(long topK) {
-    this.topK = topK;
-  }
-
-  /**
-   * @return a <code>List</code> of <code>QueryResult</code>s. Each inner <code>List</code> contains
-   *     the query result of a vector.
-   */
-  public List<List<QueryResult>> getQueryResultsList() {
-    return IntStream.range(0, numQueries)
-        .mapToObj(
-            i ->
-                IntStream.range(0, resultIdsList.get(i).size())
-                    .mapToObj(
-                        j ->
-                            new QueryResult(
-                                resultIdsList.get(i).get(j),
-                                resultDistancesList.get(i).get(j)))
-                    .collect(Collectors.toList()))
-        .collect(Collectors.toList());
-  }
-
-  /**
-   * @return a <code>List</code> of result ids. Each inner <code>List</code> contains the result ids
-   *     of a vector.
-   */
-  public List<List<Long>> getResultIdsList() {
-    return resultIdsList;
-  }
-
-  void setResultIdsList(List<List<Long>> resultIdsList) {
-    this.resultIdsList = resultIdsList;
-  }
-
-  /**
-   * @return @return a <code>List</code> of result distances. Each inner <code>List</code> contains
-   *     the result distances of a vector.
-   */
-  public List<List<Float>> getResultDistancesList() {
-    return resultDistancesList;
-  }
-
-  void setResultDistancesList(List<List<Float>> resultDistancesList) {
-    this.resultDistancesList = resultDistancesList;
-  }
-
-  public Response getResponse() {
-    return response;
-  }
-
-  void setResponse(Response response) {
-    this.response = response;
-  }
-
-  /** @return <code>true</code> if the response status equals SUCCESS */
-  public boolean ok() {
-    return response.ok();
-  }
-
-  @Override
-  public String toString() {
-    return String.format(
-        "SearchResponse {%s, returned results for %d queries}", response.toString(), numQueries);
-  }
-
-  /**
-   * Represents a single result of a vector query. Contains the result <code>vectorId</code> and its
-   * <code>distance</code> to the vector being queried
-   */
-  public static class QueryResult {
-    private final long vectorId;
-    private final float distance;
-
-    QueryResult(long vectorId, float distance) {
-      this.vectorId = vectorId;
-      this.distance = distance;
-    }
-
-    public long getVectorId() {
-      return vectorId;
-    }
-
-    public float getDistance() {
-      return distance;
-    }
-  }
-}

+ 0 - 16
src/main/java/io/milvus/client/exception/InitializationException.java

@@ -1,16 +0,0 @@
-package io.milvus.client.exception;
-
-public class InitializationException extends MilvusException {
-  private String host;
-  private Throwable cause;
-
-  public InitializationException(String host, Throwable cause) {
-    super(false, cause);
-    this.host = host;
-  }
-
-  public InitializationException(String host, String message) {
-    super(false, message);
-    this.host = host;
-  }
-}

+ 0 - 24
src/main/java/io/milvus/client/exception/MilvusException.java

@@ -1,24 +0,0 @@
-package io.milvus.client.exception;
-
-public class MilvusException extends RuntimeException {
-  private boolean fillInStackTrace;
-
-  MilvusException(boolean fillInStackTrace) {
-    this.fillInStackTrace = fillInStackTrace;
-  }
-
-  MilvusException(boolean fillInStackTrace, Throwable cause) {
-    super(cause);
-    this.fillInStackTrace = fillInStackTrace;
-  }
-
-  MilvusException(boolean fillInStackTrace, String message) {
-    super(message);
-    this.fillInStackTrace = fillInStackTrace;
-  }
-
-  @Override
-  public synchronized Throwable fillInStackTrace() {
-    return fillInStackTrace ? super.fillInStackTrace() : this;
-  }
-}

+ 0 - 22
src/main/java/io/milvus/client/exception/UnsupportedServerVersion.java

@@ -1,22 +0,0 @@
-package io.milvus.client.exception;
-
-import io.milvus.client.MilvusClient;
-
-public class UnsupportedServerVersion extends MilvusException {
-  private String host;
-  private String expect;
-  private String actual;
-
-  public UnsupportedServerVersion(String host, String expect, String actual) {
-    super(false);
-    this.host = host;
-    this.expect = expect;
-    this.actual = actual;
-  }
-
-  @Override
-  public String getMessage() {
-    return String.format("%s: Milvus client %s is expected to work with Milvus server %s, but the version of the connected server is %s",
-        host, MilvusClient.clientVersion, expect, actual);
-  }
-}

+ 161 - 0
src/main/proto/common.proto

@@ -0,0 +1,161 @@
+syntax = "proto3";
+
+package common;
+option java_multiple_files = true;
+option java_package = "io.milvus.grpc";
+option java_outer_classname = "CommonProto";
+option java_generate_equals_and_hash = true;
+
+enum ErrorCode {
+    Success = 0;
+    UnexpectedError = 1;
+    ConnectFailed = 2;
+    PermissionDenied = 3;
+    CollectionNotExists = 4;
+    IllegalArgument = 5;
+    IllegalDimension = 7;
+    IllegalIndexType = 8;
+    IllegalCollectionName = 9;
+    IllegalTOPK = 10;
+    IllegalRowRecord = 11;
+    IllegalVectorID = 12;
+    IllegalSearchResult = 13;
+    FileNotFound = 14;
+    MetaFailed = 15;
+    CacheFailed = 16;
+    CannotCreateFolder = 17;
+    CannotCreateFile = 18;
+    CannotDeleteFolder = 19;
+    CannotDeleteFile = 20;
+    BuildIndexError = 21;
+    IllegalNLIST = 22;
+    IllegalMetricType = 23;
+    OutOfMemory = 24;
+    IndexNotExist = 25;
+    EmptyCollection = 26;
+
+    // internal error code.
+    DDRequestRace = 1000;
+}
+
+enum IndexState {
+    IndexStateNone = 0;
+    Unissued = 1;
+    InProgress = 2;
+    Finished = 3;
+    Failed = 4;
+}
+
+enum SegmentState {
+    SegmentStateNone = 0;
+    NotExist = 1;
+    Growing = 2;
+    Sealed = 3;
+    Flushed = 4;
+    Flushing = 5;
+}
+
+message Status {
+    ErrorCode error_code = 1;
+    string reason = 2;
+}
+
+message KeyValuePair {
+    string key = 1;
+    string value = 2;
+}
+
+message Blob {
+    bytes value = 1;
+}
+
+message Address {
+  string ip = 1;
+  int64 port = 2;
+}
+
+enum MsgType {
+    Undefined = 0;
+    /* DEFINITION REQUESTS: COLLECTION */
+    CreateCollection = 100;
+    DropCollection = 101;
+    HasCollection = 102;
+    DescribeCollection = 103;
+    ShowCollections = 104;
+    GetSystemConfigs = 105;
+    LoadCollection = 106;
+    ReleaseCollection = 107;
+
+    /* DEFINITION REQUESTS: PARTITION */
+    CreatePartition = 200;
+    DropPartition = 201;
+    HasPartition = 202;
+    DescribePartition = 203;
+    ShowPartitions = 204;
+    LoadPartitions = 205;
+    ReleasePartitions = 206;
+
+    /* DEFINE REQUESTS: SEGMENT */
+    ShowSegments = 250;
+    DescribeSegment = 251;
+    LoadSegments = 252;
+    ReleaseSegments = 253;
+    HandoffSegments = 254;
+    LoadBalanceSegments = 255;
+
+    /* DEFINITION REQUESTS: INDEX */
+    CreateIndex = 300;
+    DescribeIndex = 301;
+    DropIndex = 302;
+
+    /* MANIPULATION REQUESTS */
+    Insert = 400;
+    Delete = 401;
+    Flush = 402;
+
+    /* QUERY */
+    Search = 500;
+    SearchResult = 501;
+    GetIndexState = 502;
+    GetIndexBuildProgress = 503;
+    GetCollectionStatistics = 504;
+    GetPartitionStatistics = 505;
+    Retrieve = 506;
+    RetrieveResult = 507;
+    WatchDmChannels = 508;
+    RemoveDmChannels = 509;
+    WatchQueryChannels = 510;
+    RemoveQueryChannels = 511;
+
+    /* DATA SERVICE */
+    SegmentInfo = 600;
+
+    /* SYSTEM CONTROL */
+    TimeTick = 1200;
+    QueryNodeStats = 1201; // GOOSE TODO: Remove kQueryNodeStats
+    LoadIndex = 1202;
+    RequestID = 1203;
+    RequestTSO = 1204;
+    AllocateSegment = 1205;
+    SegmentStatistics = 1206;
+    SegmentFlushDone = 1207;
+
+    DataNodeTt = 1208;
+}
+
+message MsgBase {
+    MsgType msg_type = 1;
+    int64  msgID = 2;
+    uint64 timestamp = 3;
+    int64 sourceID = 4;
+}
+
+enum DslType {
+    Dsl = 0;
+    BoolExprV1 = 1;
+}
+
+// Don't Modify This. @czs
+message MsgHeader {
+    MsgBase base = 1;
+}

+ 437 - 405
src/main/proto/milvus.proto

@@ -1,469 +1,501 @@
 syntax = "proto3";
 
-import "status.proto";
+import "common.proto";
+import "schema.proto";
 
 option java_multiple_files = true;
 option java_package = "io.milvus.grpc";
 option java_outer_classname = "MilvusProto";
+option java_generate_equals_and_hash = true;
 
 package milvus.grpc;
 
-/**
- * @brief general usage
- */
-message KeyValuePair {
-    string key = 1;
+service MilvusService {
+    rpc CreateCollection(CreateCollectionRequest) returns (common.Status) {}
+    rpc DropCollection(DropCollectionRequest) returns (common.Status) {}
+    rpc HasCollection(HasCollectionRequest) returns (BoolResponse) {}
+    rpc LoadCollection(LoadCollectionRequest) returns (common.Status) {}
+    rpc ReleaseCollection(ReleaseCollectionRequest) returns (common.Status) {}
+    rpc DescribeCollection(DescribeCollectionRequest) returns (DescribeCollectionResponse) {}
+    rpc GetCollectionStatistics(GetCollectionStatisticsRequest) returns (GetCollectionStatisticsResponse) {}
+    rpc ShowCollections(ShowCollectionsRequest) returns (ShowCollectionsResponse) {}
+
+    rpc CreatePartition(CreatePartitionRequest) returns (common.Status) {}
+    rpc DropPartition(DropPartitionRequest) returns (common.Status) {}
+    rpc HasPartition(HasPartitionRequest) returns (BoolResponse) {}
+    rpc LoadPartitions(LoadPartitionsRequest) returns (common.Status) {}
+    rpc ReleasePartitions(ReleasePartitionsRequest) returns (common.Status) {}
+    rpc GetPartitionStatistics(GetPartitionStatisticsRequest) returns (GetPartitionStatisticsResponse) {}
+    rpc ShowPartitions(ShowPartitionsRequest) returns (ShowPartitionsResponse) {}
+
+    rpc CreateIndex(CreateIndexRequest) returns (common.Status) {}
+    rpc DescribeIndex(DescribeIndexRequest) returns (DescribeIndexResponse) {}
+    rpc GetIndexState(GetIndexStateRequest) returns (GetIndexStateResponse) {}
+    rpc GetIndexBuildProgress(GetIndexBuildProgressRequest) returns (GetIndexBuildProgressResponse) {}
+    rpc DropIndex(DropIndexRequest) returns (common.Status) {}
+
+    rpc Insert(InsertRequest) returns (MutationResult) {}
+    rpc Delete(DeleteRequest) returns (MutationResult) {}
+    rpc Search(SearchRequest) returns (SearchResults) {}
+    rpc Flush(FlushRequest) returns (FlushResponse) {}
+    rpc Query(QueryRequest) returns (QueryResults) {}
+    rpc CalcDistance(CalcDistanceRequest) returns (CalcDistanceResults) {}
+
+    rpc GetPersistentSegmentInfo(GetPersistentSegmentInfoRequest) returns (GetPersistentSegmentInfoResponse) {}
+    rpc GetQuerySegmentInfo(GetQuerySegmentInfoRequest) returns (GetQuerySegmentInfoResponse) {}
+
+    rpc Dummy(DummyRequest) returns (DummyResponse) {}
+
+    // TODO: remove
+    rpc RegisterLink(RegisterLinkRequest) returns (RegisterLinkResponse) {}
+
+    // https://wiki.lfaidata.foundation/display/MIL/MEP+8+--+Add+metrics+for+proxy
+    rpc GetMetrics(GetMetricsRequest) returns (GetMetricsResponse) {}
+}
+
+message CreateCollectionRequest {
+    common.MsgBase base = 1; // must
+    string db_name = 2;
+    string collection_name = 3; // must
+    // `schema` is the serialized `schema.CollectionSchema`
+    bytes schema = 4; // must
+    int32 shards_num = 5; // must. Once set, no modification is allowed
+}
+
+message DropCollectionRequest {
+    common.MsgBase base = 1; // must
+    string db_name = 2;
+    string collection_name = 3; // must
+}
+
+message HasCollectionRequest {
+    common.MsgBase base = 1; // must
+    string db_name = 2;
+    string collection_name = 3; // must
+    uint64 time_stamp = 4;
+}
+
+message BoolResponse {
+    common.Status status = 1;
+    bool value = 2;
+}
+
+message StringResponse {
+    common.Status status = 1;
     string value = 2;
 }
 
-/**
- * @brief Collection name
- */
-message CollectionName {
-    string collection_name = 1;
+message DescribeCollectionRequest {
+    common.MsgBase base = 1; // must
+    string db_name = 2;
+    string collection_name = 3; // must
+    int64 collectionID = 4;
+    uint64 time_stamp = 5;
+}
+
+message DescribeCollectionResponse {
+    common.Status status = 1;
+    schema.CollectionSchema schema = 2;
+    int64 collectionID = 3;
+    repeated string virtual_channel_names = 4;
+    repeated string physical_channel_names = 5;
+    uint64 created_timestamp = 6; // hybrid timestamp
+    uint64 created_utc_timestamp = 7; // physical timestamp
+}
+
+message LoadCollectionRequest {
+    common.MsgBase base = 1; // must
+    string db_name = 2;
+    string collection_name = 3; // must
+}
+
+message ReleaseCollectionRequest {
+    common.MsgBase base = 1; // must
+    string db_name = 2;
+    string collection_name = 3; // must
+}
+
+message GetCollectionStatisticsRequest {
+    common.MsgBase base = 1; // must
+    string db_name = 2;
+    string collection_name = 3; // must
+}
+
+message GetCollectionStatisticsResponse {
+    common.Status status = 1;
+    repeated common.KeyValuePair stats = 2;
+}
+
+enum ShowType {
+    All = 0;
+    InMemory = 1;
+}
+
+message ShowCollectionsRequest {
+    common.MsgBase base = 1; // must
+    string db_name = 2;
+    uint64 time_stamp = 3;
+    ShowType type = 4;
+    repeated string collection_names = 5; // show collection in querynode, showType = InMemory
 }
 
-/**
- * @brief Collection name list
- */
-message CollectionNameList {
-    Status status = 1;
+message ShowCollectionsResponse {
+    common.Status status = 1;
     repeated string collection_names = 2;
+    repeated int64 collection_ids = 3;
+    repeated uint64 created_timestamps = 4; // hybrid timestamps
+    repeated uint64 created_utc_timestamps = 5; // physical timestamps
+    repeated int64 inMemory_percentages = 6; // load percentage on querynode
 }
 
-/**
- * @brief Collection schema
- * metric_type: 1-L2, 2-IP
- */
-message CollectionSchema {
-    Status status = 1;
-    string collection_name = 2;
-    int64 dimension = 3;
-    int64 index_file_size = 4;
-    int32 metric_type = 5;
-    repeated KeyValuePair extra_params = 6;
+message CreatePartitionRequest {
+    common.MsgBase base = 1; // must
+    string db_name = 2;
+    string collection_name = 3; // must
+    string partition_name = 4; // must
 }
 
-/**
- * @brief Params of partition
- */
-message PartitionParam {
-    string collection_name = 1;
-    string tag = 2;
+message DropPartitionRequest {
+    common.MsgBase base = 1; // must
+    string db_name = 2;
+    string collection_name = 3; // must
+    string partition_name = 4; // must
 }
 
-/**
- * @brief Partition list
- */
-message PartitionList {
-    Status status = 1;
-    repeated string partition_tag_array = 2;
+message HasPartitionRequest {
+    common.MsgBase base = 1; // must
+    string db_name = 2;
+    string collection_name = 3; // must
+    string partition_name = 4; // must
 }
 
-/**
- * @brief Record inserted
- */
-message RowRecord {
-    repeated float float_data = 1;             //float vector data
-    bytes binary_data = 2;                      //binary vector data
+message LoadPartitionsRequest {
+    common.MsgBase base = 1; // must
+    string db_name = 2;
+    string collection_name = 3; // must
+    repeated string partition_names = 4; // must
 }
 
-/**
- * @brief Params to be inserted
- */
-message InsertParam {
-    string collection_name = 1;
-    repeated RowRecord row_record_array = 2;
-    repeated int64 row_id_array = 3;            //optional
-    string partition_tag = 4;
-    repeated KeyValuePair extra_params = 5;
+message ReleasePartitionsRequest {
+    common.MsgBase base = 1; // must
+    string db_name = 2;
+    string collection_name = 3; // must
+    repeated string partition_names = 4; // must
 }
 
-/**
- * @brief Vector ids
- */
-message VectorIds {
-    Status status = 1;
-    repeated int64 vector_id_array = 2;
+message GetPartitionStatisticsRequest {
+    common.MsgBase base = 1; // must
+    string db_name = 2;
+    string collection_name = 3; // must
+    string partition_name = 4; // must
 }
 
-/**
- * @brief Params for searching vector
- */
-message SearchParam {
-    string collection_name = 1;
-    repeated string partition_tag_array = 2;
-    repeated RowRecord query_record_array = 3;
-    int64 topk = 4;
-    repeated KeyValuePair extra_params = 5;
+message GetPartitionStatisticsResponse {
+    common.Status status = 1;
+    repeated common.KeyValuePair stats = 2;
 }
 
-/**
- * @brief Params for searching vector in files
- */
-message SearchInFilesParam {
-    repeated string file_id_array = 1;
-    SearchParam search_param = 2;
+message ShowPartitionsRequest {
+    common.MsgBase base = 1; // must
+    string db_name = 2;
+    string collection_name = 3; // must
+    int64 collectionID = 4;
+    repeated string partition_names = 5; // show partition in querynode, showType = InMemory
+    ShowType type = 6;
 }
 
-/**
- * @brief Params for searching vector by ID
- */
-message SearchByIDParam {
-    string collection_name = 1;
-    repeated string partition_tag_array = 2;
-    repeated int64 id_array = 3;
-    int64 topk = 4;
-    repeated KeyValuePair extra_params = 5;
+message ShowPartitionsResponse {
+    common.Status status = 1;
+    repeated string partition_names = 2;
+    repeated int64 partitionIDs = 3;
+    repeated uint64 created_timestamps = 4; // hybrid timestamps
+    repeated uint64 created_utc_timestamps = 5; // physical timestamps
+    repeated int64 inMemory_percentages = 6; // load percentage on querynode
 }
 
-/**
- * @brief Params for preload collection/partitions
- */
-message PreloadCollectionParam {
-    string collection_name = 1;
-    repeated string partition_tag_array = 2;
+message DescribeSegmentRequest {
+    common.MsgBase base = 1;
+    int64 collectionID = 2;
+    int64 segmentID = 3;
 }
 
-/**
- * @brief Params for reloading segments
- */
-message ReLoadSegmentsParam {
-    string collection_name = 1;
-    repeated string segment_id_array = 2;
+message DescribeSegmentResponse {
+    common.Status status = 1;
+    int64 indexID = 2;
+    int64 buildID = 3;
+    bool enable_index = 4;
 }
 
-/**
- * @brief Query result params
- */
-message TopKQueryResult {
-    Status status = 1;
-    int64 row_num = 2;
-    repeated int64 ids = 3;
-    repeated float distances = 4;
+message ShowSegmentsRequest {
+    common.MsgBase base = 1;
+    int64 collectionID = 2;
+    int64 partitionID = 3;
 }
 
-/**
- * @brief Server string Reply
- */
-message StringReply {
-    Status status = 1;
-    string string_reply = 2;
+message ShowSegmentsResponse {
+    common.Status status = 1;
+    repeated int64 segmentIDs = 2;
 }
 
-/**
- * @brief Server bool Reply
- */
-message BoolReply {
-    Status status = 1;
-    bool bool_reply = 2;
+message CreateIndexRequest {
+    common.MsgBase base = 1; // must
+    string db_name = 2;
+    string collection_name = 3; // must
+    string field_name = 4; // must
+    repeated common.KeyValuePair extra_params = 5; // must
 }
 
-/**
- * @brief Return collection row count
- */
-message CollectionRowCount {
-    Status status = 1;
-    int64 collection_row_count = 2;
+message DescribeIndexRequest {
+    common.MsgBase base = 1; // must
+    string db_name = 2;
+    string collection_name = 3; // must
+    string field_name = 4;
+    string index_name = 5; // No need to set up for now @2021.06.30
 }
 
-/**
- * @brief Give server Command
- */
-message Command {
-    string cmd = 1;
+message IndexDescription {
+    string index_name = 1;
+    int64 indexID = 2;
+    repeated common.KeyValuePair params = 3;
+    string field_name = 4;
 }
 
-/**
- * @brief Index params
- * @index_type: 0-invalid, 1-idmap, 2-ivflat, 3-ivfsq8, 4-nsgmix
- */
-message IndexParam {
-    Status status = 1;
-    string collection_name = 2;
-    int32 index_type = 3;
-    repeated KeyValuePair extra_params = 4;
+message DescribeIndexResponse {
+    common.Status status = 1;
+    repeated IndexDescription index_descriptions = 2;
 }
 
-/**
- * @brief Flush params
- */
-message FlushParam {
-    repeated string collection_name_array = 1;
+message GetIndexBuildProgressRequest {
+    common.MsgBase base = 1; // must
+    string db_name = 2 ;
+    string collection_name = 3; // must
+    string field_name = 4;
+    string index_name = 5; // must
 }
 
-/**
- * @brief Flush params
- */
-message DeleteByIDParam {
-    string collection_name = 1;
-    repeated int64 id_array = 2;
+message GetIndexBuildProgressResponse {
+    common.Status status = 1;
+    int64 indexed_rows = 2;
+    int64 total_rows = 3;
 }
 
-/**
- * @brief collection information
- */
-message CollectionInfo {
-    Status status = 1;
-    string json_info = 2;
+message GetIndexStateRequest {
+    common.MsgBase base = 1; // must
+    string db_name = 2 ;
+    string collection_name = 3; // must
+    string field_name = 4;
+    string index_name = 5; // No need to set up for now @2021.06.30
 }
 
-/**
- * @brief vectors identity
- */
-message VectorsIdentity {
-    string collection_name = 1;
-    repeated int64 id_array = 2;
+message GetIndexStateResponse {
+    common.Status status = 1;
+    common.IndexState state = 2;
+    string fail_reason = 3;
+}
+
+message DropIndexRequest {
+    common.MsgBase base = 1; // must
+    string db_name = 2;
+    string collection_name = 3; // must
+    string field_name = 4;
+    string index_name = 5; // No need to set up for now @2021.06.30
+}
+
+message InsertRequest {
+    common.MsgBase base = 1;
+    string db_name = 2;
+    string collection_name = 3;
+    string partition_name = 4;
+    repeated schema.FieldData fields_data = 5;
+    repeated uint32 hash_keys = 6;
+    uint32 num_rows = 7;
+}
+
+message MutationResult {
+    common.Status status = 1;
+    schema.IDs IDs = 2; // required for insert, delete
+    repeated uint32 succ_index = 3; // error indexes indicate
+    repeated uint32 err_index = 4; // error indexes indicate
+    bool acknowledged = 5;
+    int64 insert_cnt = 6;
+    int64 delete_cnt = 7;
+    int64 upsert_cnt = 8;
+    uint64 timestamp = 9;
+}
+
+message DeleteRequest {
+    common.MsgBase base = 1;
+    string db_name = 2;
+    string collection_name = 3;
+    string partition_name = 4;
+    string expr = 5;
+}
+
+enum PlaceholderType {
+    None = 0;
+    BinaryVector = 100;
+    FloatVector = 101;
+}
+
+message PlaceholderValue {
+    string tag = 1;
+    PlaceholderType type = 2;
+    // values is a 2d-array, every array contains a vector
+    repeated bytes values = 3;
 }
 
-/**
- * @brief vector data
- */
-message VectorsData {
-    Status status = 1;
-    repeated RowRecord vectors_data = 2;
+message PlaceholderGroup {
+    repeated PlaceholderValue placeholders = 1;
 }
 
-/**
- * @brief get vector ids from a segment parameters
- */
-message GetVectorIDsParam {
+message SearchRequest {
+    common.MsgBase base = 1; // must
+    string db_name = 2;
+    string collection_name = 3; // must
+    repeated string partition_names = 4; // must
+    string dsl = 5; // must
+    // serialized `PlaceholderGroup`
+    bytes placeholder_group = 6; // must
+    common.DslType dsl_type = 7; // must
+    repeated string output_fields = 8;
+    repeated common.KeyValuePair search_params = 9; // must
+    uint64 travel_timestamp = 10;
+    uint64 guarantee_timestamp = 11; // guarantee_timestamp
+}
+
+message Hits {
+    repeated int64 IDs = 1;
+    repeated bytes row_data = 2;
+    repeated float scores = 3;
+}
+
+message SearchResults {
+    common.Status status = 1;
+    schema.SearchResultData results = 2;
+}
+
+message FlushRequest {
+    common.MsgBase base = 1;
+    string db_name = 2;
+    repeated string collection_names = 3;
+}
+
+message FlushResponse{
+    common.Status status = 1;
+    string db_name = 2;
+    map<string, schema.LongArray> coll_segIDs = 3;
+}
+
+message QueryRequest {
+    common.MsgBase base = 1;
+    string db_name = 2;
+    string collection_name = 3;
+    string expr = 4;
+    repeated string output_fields = 5;
+    repeated string partition_names = 6;
+    uint64 travel_timestamp = 7;
+    uint64 guarantee_timestamp = 8; // guarantee_timestamp
+}
+
+message QueryResults {
+    common.Status status = 1;
+    repeated schema.FieldData fields_data = 2;
+}
+
+message VectorIDs {
     string collection_name = 1;
-    string segment_name = 2;
+    string field_name = 2;
+    schema.IDs id_array = 3;
+    repeated string partition_names = 4;
+}
+
+message VectorsArray {
+    oneof array {
+        VectorIDs id_array = 1; // vector ids
+        schema.VectorField data_array = 2; // vectors data
+    }
+}
+
+message CalcDistanceRequest {
+    common.MsgBase base = 1;
+    VectorsArray op_left = 2; // vectors on the left of operator
+    VectorsArray op_right = 3; // vectors on the right of operator
+    repeated common.KeyValuePair params = 4; // "metric":"L2"/"IP"/"HAMMIN"/"TANIMOTO"
+}
+
+message CalcDistanceResults {
+    common.Status status = 1;
+    // num(op_left)*num(op_right) distance values, "HAMMIN" return integer distance
+    oneof array {
+        schema.IntArray int_dist = 2;
+        schema.FloatArray float_dist = 3;
+    }
+}
+
+message PersistentSegmentInfo {
+    int64 segmentID = 1;
+    int64 collectionID = 2;
+    int64 partitionID = 3;
+    int64 num_rows = 4;
+    common.SegmentState state = 5;
+}
+
+message GetPersistentSegmentInfoRequest {
+    common.MsgBase base = 1; // must
+    string dbName = 2;
+    string collectionName = 3; // must
+}
+
+message GetPersistentSegmentInfoResponse {
+    common.Status status = 1;
+    repeated PersistentSegmentInfo infos = 2;
+}
+
+message QuerySegmentInfo {
+    int64 segmentID = 1;
+    int64 collectionID = 2;
+    int64 partitionID = 3;
+    int64 mem_size = 4;
+    int64 num_rows = 5;
+    string index_name = 6;
+    int64 indexID = 7;
+}
+
+message GetQuerySegmentInfoRequest {
+    common.MsgBase base = 1; // must
+    string dbName = 2;
+    string collectionName = 3; // must
+}
+
+message GetQuerySegmentInfoResponse {
+    common.Status status = 1;
+    repeated QuerySegmentInfo infos = 2;
+}
+
+message DummyRequest {
+    string request_type = 1;
+}
+
+message DummyResponse {
+    string response = 1;
+}
+
+message RegisterLinkRequest {
+}
+
+message RegisterLinkResponse {
+    common.Address address = 1;
+    common.Status status = 2;
+}
+
+message GetMetricsRequest {
+    common.MsgBase base = 1;
+    string request = 2; // request is of jsonic format
+}
+
+message GetMetricsResponse {
+    common.Status status = 1;
+    string response = 2;  // response is of jsonic format
+    string component_name = 3; // metrics from which component
 }
 
-service MilvusService {
-    /**
-     * @brief This method is used to create collection
-     *
-     * @param CollectionSchema, use to provide collection information to be created.
-     *
-     * @return Status
-     */
-    rpc CreateCollection(CollectionSchema) returns (Status){}
-
-    /**
-     * @brief This method is used to test collection existence.
-     *
-     * @param CollectionName, collection name is going to be tested.
-     *
-     * @return BoolReply
-     */
-    rpc HasCollection(CollectionName) returns (BoolReply) {}
-
-    /**
-     * @brief This method is used to get collection schema.
-     *
-     * @param CollectionName, target collection name.
-     *
-     * @return CollectionSchema
-     */
-    rpc DescribeCollection(CollectionName) returns (CollectionSchema) {}
-
-    /**
-     * @brief This method is used to get collection schema.
-     *
-     * @param CollectionName, target collection name.
-     *
-     * @return CollectionRowCount
-     */
-    rpc CountCollection(CollectionName) returns (CollectionRowCount) {}
-
-    /**
-     * @brief This method is used to list all collections.
-     *
-     * @param Command, dummy parameter.
-     *
-     * @return CollectionNameList
-     */
-    rpc ShowCollections(Command) returns (CollectionNameList) {}
-
-    /**
-     * @brief This method is used to get collection detail information.
-     *
-     * @param CollectionName, target collection name.
-     *
-     * @return CollectionInfo
-     */
-    rpc ShowCollectionInfo(CollectionName) returns (CollectionInfo) {}
-
-    /**
-     * @brief This method is used to delete collection.
-     *
-     * @param CollectionName, collection name is going to be deleted.
-     *
-     * @return CollectionNameList
-     */
-    rpc DropCollection(CollectionName) returns (Status) {}
-
-    /**
-     * @brief This method is used to build index by collection in sync mode.
-     *
-     * @param IndexParam, index paramters.
-     *
-     * @return Status
-     */
-    rpc CreateIndex(IndexParam) returns (Status) {}
-
-    /**
-     * @brief This method is used to describe index
-     *
-     * @param CollectionName, target collection name.
-     *
-     * @return IndexParam
-     */
-    rpc DescribeIndex(CollectionName) returns (IndexParam) {}
-
-    /**
-     * @brief This method is used to drop index
-     *
-     * @param CollectionName, target collection name.
-     *
-     * @return Status
-     */
-    rpc DropIndex(CollectionName) returns (Status) {}
-
-    /**
-     * @brief This method is used to create partition
-     *
-     * @param PartitionParam, partition parameters.
-     *
-     * @return Status
-     */
-    rpc CreatePartition(PartitionParam) returns (Status) {}
-
-    /**
-     * @brief This method is used to test partition existence.
-     *
-     * @param PartitionParam, target partition.
-     *
-     * @return BoolReply
-     */
-    rpc HasPartition(PartitionParam) returns (BoolReply) {}
-
-    /**
-     * @brief This method is used to show partition information
-     *
-     * @param CollectionName, target collection name.
-     *
-     * @return PartitionList
-     */
-    rpc ShowPartitions(CollectionName) returns (PartitionList) {}
-
-    /**
-     * @brief This method is used to drop partition
-     *
-     * @param PartitionParam, target partition.
-     *
-     * @return Status
-     */
-    rpc DropPartition(PartitionParam) returns (Status) {}
-
-    /**
-     * @brief This method is used to add vector array to collection.
-     *
-     * @param InsertParam, insert parameters.
-     *
-     * @return VectorIds
-     */
-    rpc Insert(InsertParam) returns (VectorIds) {}
-
-    /**
-     * @brief This method is used to get vectors data by id array.
-     *
-     * @param VectorsIdentity, target vector id array.
-     *
-     * @return VectorsData
-     */
-    rpc GetVectorsByID(VectorsIdentity) returns (VectorsData) {}
-
-    /**
-     * @brief This method is used to get vector ids from a segment
-     *
-     * @param GetVectorIDsParam, target collection and segment
-     *
-     * @return VectorIds
-     */
-    rpc GetVectorIDs(GetVectorIDsParam) returns (VectorIds) {}
-
-    /**
-     * @brief This method is used to query vector in collection.
-     *
-     * @param SearchParam, search parameters.
-     *
-     * @return TopKQueryResult
-     */
-    rpc Search(SearchParam) returns (TopKQueryResult) {}
-
-    /**
-     * @brief This method is used to query vector by id.
-     *
-     * @param SearchByIDParam, search parameters.
-     *
-     * @return TopKQueryResult
-     */
-    rpc SearchByID(SearchByIDParam) returns (TopKQueryResult) {}
-
-    /**
-     * @brief This method is used to query vector in specified files.
-     *
-     * @param SearchInFilesParam, search in files paremeters.
-     *
-     * @return TopKQueryResult
-     */
-    rpc SearchInFiles(SearchInFilesParam) returns (TopKQueryResult) {}
-
-    /**
-     * @brief This method is used to give the server status.
-     *
-     * @param Command, command string
-     *
-     * @return StringReply
-     */
-    rpc Cmd(Command) returns (StringReply) {}
-
-    /**
-     * @brief This method is used to delete vector by id
-     *
-     * @param DeleteByIDParam, delete parameters.
-     *
-     * @return status
-     */
-    rpc DeleteByID(DeleteByIDParam) returns (Status) {}
-
-    /**
-     * @brief This method is used to preload collection/partitions
-     *
-     * @param PreloadCollectionParam, target collection/partitions.
-     *
-     * @return Status
-     */
-    rpc PreloadCollection(PreloadCollectionParam) returns (Status) {}
-
-    /**
-     * @brief This method is used to reload collection segments
-     *
-     * @param ReLoadSegmentsParam, target segments information.
-     *
-     * @return Status
-     */
-    rpc ReloadSegments(ReLoadSegmentsParam) returns (Status) {}
-
-    /**
-     * @brief This method is used to flush buffer into storage.
-     *
-     * @param FlushParam, flush parameters
-     *
-     * @return Status
-     */
-    rpc Flush(FlushParam) returns (Status) {}
-
-    /**
-     * @brief This method is used to compact collection
-     *
-     * @param CollectionName, target collection name.
-     *
-     * @return Status
-     */
-    rpc Compact(CollectionName) returns (Status) {}
-}

+ 128 - 0
src/main/proto/schema.proto

@@ -0,0 +1,128 @@
+syntax = "proto3";
+
+import "common.proto";
+
+package schema;
+option java_multiple_files = true;
+option java_package = "io.milvus.grpc";
+option java_outer_classname = "SchemaProto";
+option java_generate_equals_and_hash = true;
+
+/**
+ * @brief Field data type
+ */
+enum DataType {
+  None = 0;
+  Bool = 1;
+  Int8 = 2;
+  Int16 = 3;
+  Int32 = 4;
+  Int64 = 5;
+
+  Float = 10;
+  Double = 11;
+
+  String = 20;
+
+  BinaryVector = 100;
+  FloatVector = 101;
+}
+
+/**
+ * @brief Field schema
+ */
+message FieldSchema {
+  int64 fieldID = 1;
+  string name = 2;
+  bool is_primary_key = 3;
+  string description = 4;
+  DataType data_type = 5;
+  repeated common.KeyValuePair type_params = 6;
+  repeated common.KeyValuePair index_params = 7;
+  bool autoID = 8;
+}
+
+/**
+ * @brief Collection schema
+ */
+message CollectionSchema {
+  string name = 1;
+  string description = 2;
+  bool autoID = 3; // deprecated later, keep compatible with c++ part now
+  repeated FieldSchema fields = 4;
+}
+
+message BoolArray {
+  repeated bool data = 1;
+}
+
+message IntArray {
+  repeated int32 data = 1;
+}
+
+message LongArray {
+  repeated int64 data = 1;
+}
+
+message FloatArray {
+  repeated float data = 1;
+}
+
+message DoubleArray {
+  repeated double data = 1;
+}
+
+// For special fields such as bigdecimal, array...
+message BytesArray {
+  repeated bytes data = 1;
+}
+
+message StringArray {
+  repeated string data = 1;
+}
+
+message ScalarField {
+  oneof data {
+    BoolArray bool_data = 1;
+    IntArray int_data = 2;
+    LongArray long_data = 3;
+    FloatArray float_data = 4;
+    DoubleArray double_data = 5;
+    StringArray string_data = 6;
+    BytesArray bytes_data = 7;
+  }
+}
+
+message VectorField {
+  int64 dim = 1;
+  oneof data {
+    FloatArray float_vector = 2;
+    bytes binary_vector = 3;
+  }
+}
+
+message FieldData {
+  DataType type = 1;
+  string field_name = 2;
+  oneof field {
+    ScalarField scalars = 3;
+    VectorField vectors = 4;
+  }
+  int64 field_id = 5;
+}
+
+message IDs {
+  oneof id_field {
+    LongArray int_id = 1;
+    StringArray str_id = 2;
+  }
+}
+
+message SearchResultData {
+  int64 num_queries = 1;
+  int64 top_k = 2;
+  repeated FieldData fields_data = 3;
+  repeated float scores = 4;
+  IDs ids = 5;
+  repeated int64 topks = 6;
+}

+ 0 - 39
src/main/proto/status.proto

@@ -1,39 +0,0 @@
-syntax = "proto3";
-
-option java_multiple_files = true;
-option java_package = "io.milvus.grpc";
-option java_outer_classname = "MilvusStatusProto";
-
-package milvus.grpc;
-
-enum ErrorCode {
-    SUCCESS = 0;
-    UNEXPECTED_ERROR = 1;
-    CONNECT_FAILED = 2;
-    PERMISSION_DENIED = 3;
-    COLLECTION_NOT_EXISTS = 4;
-    ILLEGAL_ARGUMENT = 5;
-    ILLEGAL_DIMENSION = 7;
-    ILLEGAL_INDEX_TYPE = 8;
-    ILLEGAL_COLLECTION_NAME = 9;
-    ILLEGAL_TOPK = 10;
-    ILLEGAL_ROWRECORD = 11;
-    ILLEGAL_VECTOR_ID = 12;
-    ILLEGAL_SEARCH_RESULT = 13;
-    FILE_NOT_FOUND = 14;
-    META_FAILED = 15;
-    CACHE_FAILED = 16;
-    CANNOT_CREATE_FOLDER = 17;
-    CANNOT_CREATE_FILE = 18;
-    CANNOT_DELETE_FOLDER = 19;
-    CANNOT_DELETE_FILE = 20;
-    BUILD_INDEX_ERROR = 21;
-    ILLEGAL_NLIST = 22;
-    ILLEGAL_METRIC_TYPE = 23;
-    OUT_OF_MEMORY = 24;
-}
-
-message Status {
-    ErrorCode error_code = 1;
-    string reason = 2;
-}

+ 0 - 787
src/test/java/io/milvus/client/MilvusGrpcClientTest.java

@@ -1,787 +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.client;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import io.milvus.client.exception.InitializationException;
-import io.milvus.client.exception.UnsupportedServerVersion;
-import org.apache.commons.text.RandomStringGenerator;
-import org.json.*;
-import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
-import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
-import org.testcontainers.containers.GenericContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.junit.jupiter.Testcontainers;
-
-import java.nio.ByteBuffer;
-import java.util.*;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-import java.util.stream.DoubleStream;
-import java.util.stream.LongStream;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-@Testcontainers
-@EnabledIfSystemProperty(named = "with-containers", matches = "true")
-class ContainerMilvusClientTest extends MilvusClientTest {
-  @Container
-  private static GenericContainer milvusContainer =
-      new GenericContainer("milvusdb/milvus:0.10.5-cpu-d010621-4eda95")
-          .withExposedPorts(19530);
-
-  @Container
-  private static GenericContainer unsupportedMilvusContainer =
-      new GenericContainer("milvusdb/milvus:0.9.1-cpu-d052920-e04ed5")
-          .withExposedPorts(19530);
-
-  @Override
-  protected ConnectParam.Builder connectParamBuilder() {
-    return connectParamBuilder(milvusContainer);
-  }
-
-  @org.junit.jupiter.api.Test
-  void unsupportedServerVersion() {
-    ConnectParam connectParam = connectParamBuilder(unsupportedMilvusContainer).build();
-    assertThrows(UnsupportedServerVersion.class, () -> new MilvusGrpcClient(connectParam));
-  }
-}
-
-@DisabledIfSystemProperty(named = "with-containers", matches = "true")
-class MilvusClientTest {
-
-  private MilvusClient client;
-
-  private RandomStringGenerator generator;
-
-  private String randomCollectionName;
-  private int size;
-  private int dimension;
-
-  protected ConnectParam.Builder connectParamBuilder() {
-    return connectParamBuilder("localhost", 19530);
-  }
-
-  protected ConnectParam.Builder connectParamBuilder(GenericContainer milvusContainer) {
-    return connectParamBuilder(milvusContainer.getHost(), milvusContainer.getFirstMappedPort());
-  }
-
-  private ConnectParam.Builder connectParamBuilder(String host, int port) {
-    return new ConnectParam.Builder().withHost(host).withPort(port);
-  }
-
-  // Helper function that generates random float vectors
-  static List<List<Float>> generateFloatVectors(int vectorCount, int dimension) {
-    SplittableRandom splittableRandom = new SplittableRandom();
-    List<List<Float>> vectors = new ArrayList<>(vectorCount);
-    for (int i = 0; i < vectorCount; ++i) {
-      splittableRandom = splittableRandom.split();
-      DoubleStream doubleStream = splittableRandom.doubles(dimension);
-      List<Float> vector =
-          doubleStream.boxed().map(Double::floatValue).collect(Collectors.toList());
-      vectors.add(vector);
-    }
-    return vectors;
-  }
-
-  // Helper function that generates random binary vectors
-  static List<ByteBuffer> generateBinaryVectors(int vectorCount, int dimension) {
-    Random random = new Random();
-    List<ByteBuffer> vectors = new ArrayList<>(vectorCount);
-    final int dimensionInByte = dimension / 8;
-    for (int i = 0; i < vectorCount; ++i) {
-      ByteBuffer byteBuffer = ByteBuffer.allocate(dimensionInByte);
-      random.nextBytes(byteBuffer.array());
-      vectors.add(byteBuffer);
-    }
-    return vectors;
-  }
-
-  // Helper function that normalizes a vector if you are using IP (Inner Product) as your metric
-  // type
-  static List<Float> normalizeVector(List<Float> vector) {
-    float squareSum = vector.stream().map(x -> x * x).reduce((float) 0, Float::sum);
-    final float norm = (float) Math.sqrt(squareSum);
-    vector = vector.stream().map(x -> x / norm).collect(Collectors.toList());
-    return vector;
-  }
-
-  @org.junit.jupiter.api.BeforeEach
-  void setUp() throws Exception {
-    ConnectParam connectParam = connectParamBuilder().build();
-    client = new MilvusGrpcClient(connectParam);
-
-    generator = new RandomStringGenerator.Builder().withinRange('a', 'z').build();
-    randomCollectionName = generator.generate(10);
-    size = 100000;
-    dimension = 128;
-    CollectionMapping collectionMapping =
-        new CollectionMapping.Builder(randomCollectionName, dimension)
-            .withIndexFileSize(1024)
-            .withMetricType(MetricType.IP)
-            .build();
-
-    assertTrue(client.createCollection(collectionMapping).ok());
-  }
-
-  @org.junit.jupiter.api.AfterEach
-  void tearDown() throws InterruptedException {
-    assertTrue(client.dropCollection(randomCollectionName).ok());
-    client.close();
-  }
-
-  @org.junit.jupiter.api.Test
-  void idleTest() throws InterruptedException, ConnectFailedException {
-    ConnectParam connectParam = connectParamBuilder()
-        .withIdleTimeout(1, TimeUnit.SECONDS)
-        .build();
-    MilvusClient client = new MilvusGrpcClient(connectParam);
-    TimeUnit.SECONDS.sleep(2);
-    // A new RPC would take the channel out of idle mode
-    assertTrue(client.listCollections().ok());
-  }
-
-  @org.junit.jupiter.api.Test
-  void setInvalidConnectParam() {
-    assertThrows(
-        IllegalArgumentException.class,
-        () -> {
-          ConnectParam connectParam = new ConnectParam.Builder().withPort(66666).build();
-        });
-    assertThrows(
-        IllegalArgumentException.class,
-        () -> {
-          ConnectParam connectParam =
-              new ConnectParam.Builder().withConnectTimeout(-1, TimeUnit.MILLISECONDS).build();
-        });
-    assertThrows(
-        IllegalArgumentException.class,
-        () -> {
-          ConnectParam connectParam =
-              new ConnectParam.Builder().withKeepAliveTime(-1, TimeUnit.MILLISECONDS).build();
-        });
-    assertThrows(
-        IllegalArgumentException.class,
-        () -> {
-          ConnectParam connectParam =
-              new ConnectParam.Builder().withKeepAliveTimeout(-1, TimeUnit.MILLISECONDS).build();
-        });
-    assertThrows(
-        IllegalArgumentException.class,
-        () -> {
-          ConnectParam connectParam =
-              new ConnectParam.Builder().withIdleTimeout(-1, TimeUnit.MILLISECONDS).build();
-        });
-  }
-
-  @org.junit.jupiter.api.Test
-  void connectUnreachableHost() {
-    ConnectParam connectParam = connectParamBuilder("250.250.250.250", 19530).build();
-    assertThrows(InitializationException.class, () -> new MilvusGrpcClient(connectParam));
-  }
-
-  @org.junit.jupiter.api.Test
-  void grpcTimeout() {
-    insert();
-    MilvusClient timeoutClient = client.withTimeout(1, TimeUnit.MILLISECONDS);
-    Response response = timeoutClient.createIndex(
-        new Index.Builder(randomCollectionName, IndexType.FLAT)
-            .withParamsInJson("{\"nlist\": 16384}").build());
-    assertEquals(Response.Status.RPC_ERROR, response.getStatus());
-  }
-
-  @org.junit.jupiter.api.Test
-  void createInvalidCollection() {
-    String invalidCollectionName = "╯°□°)╯";
-    CollectionMapping invalidCollectionMapping =
-        new CollectionMapping.Builder(invalidCollectionName, dimension).build();
-    Response createCollectionResponse = client.createCollection(invalidCollectionMapping);
-    assertFalse(createCollectionResponse.ok());
-    assertEquals(Response.Status.ILLEGAL_COLLECTION_NAME, createCollectionResponse.getStatus());
-  }
-
-  @org.junit.jupiter.api.Test
-  void hasCollection() {
-    HasCollectionResponse hasCollectionResponse = client.hasCollection(randomCollectionName);
-    assertTrue(hasCollectionResponse.ok());
-    assertTrue(hasCollectionResponse.hasCollection());
-  }
-
-  @org.junit.jupiter.api.Test
-  void dropCollection() {
-    String nonExistingCollectionName = generator.generate(10);
-    Response dropCollectionResponse = client.dropCollection(nonExistingCollectionName);
-    assertFalse(dropCollectionResponse.ok());
-    assertEquals(Response.Status.COLLECTION_NOT_EXISTS, dropCollectionResponse.getStatus());
-  }
-
-  @org.junit.jupiter.api.Test
-  void partitionTest() {
-    final String tag1 = "tag1";
-    Response createPartitionResponse = client.createPartition(randomCollectionName, tag1);
-    assertTrue(createPartitionResponse.ok());
-
-    final String tag2 = "tag2";
-    createPartitionResponse = client.createPartition(randomCollectionName, tag2);
-    assertTrue(createPartitionResponse.ok());
-
-    ListPartitionsResponse listPartitionsResponse = client.listPartitions(randomCollectionName);
-    assertTrue(listPartitionsResponse.ok());
-    assertEquals(3, listPartitionsResponse.getPartitionList().size()); // two tags plus _default
-
-    List<List<Float>> vectors1 = generateFloatVectors(size, dimension);
-    List<Long> vectorIds1 = LongStream.range(0, size).boxed().collect(Collectors.toList());
-    InsertParam insertParam =
-        new InsertParam.Builder(randomCollectionName)
-            .withFloatVectors(vectors1)
-            .withVectorIds(vectorIds1)
-            .withPartitionTag(tag1)
-            .build();
-    InsertResponse insertResponse = client.insert(insertParam);
-    assertTrue(insertResponse.ok());
-    List<List<Float>> vectors2 = generateFloatVectors(size, dimension);
-    List<Long> vectorIds2 = LongStream.range(size, size * 2).boxed().collect(Collectors.toList());
-    insertParam =
-        new InsertParam.Builder(randomCollectionName)
-            .withFloatVectors(vectors2)
-            .withVectorIds(vectorIds2)
-            .withPartitionTag(tag2)
-            .build();
-    insertResponse = client.insert(insertParam);
-    assertTrue(insertResponse.ok());
-
-    assertTrue(client.flush(randomCollectionName).ok());
-
-    assertEquals(size * 2, client.countEntities(randomCollectionName).getCollectionEntityCount());
-
-    final int searchSize = 1;
-    final long topK = 10;
-
-    List<List<Float>> vectorsToSearch1 = vectors1.subList(0, searchSize);
-    List<String> partitionTags1 = new ArrayList<>();
-    partitionTags1.add(tag1);
-    SearchParam searchParam1 =
-        new SearchParam.Builder(randomCollectionName)
-            .withFloatVectors(vectorsToSearch1)
-            .withTopK(topK)
-            .withPartitionTags(partitionTags1)
-            .withParamsInJson("{\"nprobe\": 20}")
-            .build();
-    SearchResponse searchResponse1 = client.search(searchParam1);
-    assertTrue(searchResponse1.ok());
-    List<List<Long>> resultIdsList1 = searchResponse1.getResultIdsList();
-    assertEquals(searchSize, resultIdsList1.size());
-    assertTrue(vectorIds1.containsAll(resultIdsList1.get(0)));
-
-    List<List<Float>> vectorsToSearch2 = vectors2.subList(0, searchSize);
-    List<String> partitionTags2 = new ArrayList<>();
-    partitionTags2.add(tag2);
-    SearchParam searchParam2 =
-        new SearchParam.Builder(randomCollectionName)
-            .withFloatVectors(vectorsToSearch2)
-            .withTopK(topK)
-            .withPartitionTags(partitionTags2)
-            .withParamsInJson("{\"nprobe\": 20}")
-            .build();
-    SearchResponse searchResponse2 = client.search(searchParam2);
-    assertTrue(searchResponse2.ok());
-    List<List<Long>> resultIdsList2 = searchResponse2.getResultIdsList();
-    assertEquals(searchSize, resultIdsList2.size());
-    assertTrue(vectorIds2.containsAll(resultIdsList2.get(0)));
-
-    assertTrue(Collections.disjoint(resultIdsList1, resultIdsList2));
-
-    HasPartitionResponse testHasPartition = client.hasPartition(randomCollectionName, tag1);
-    assertTrue(testHasPartition.hasPartition());
-
-    Response dropPartitionResponse = client.dropPartition(randomCollectionName, tag1);
-    assertTrue(dropPartitionResponse.ok());
-
-    testHasPartition = client.hasPartition(randomCollectionName, tag1);
-    assertFalse(testHasPartition.hasPartition());
-
-    dropPartitionResponse = client.dropPartition(randomCollectionName, tag2);
-    assertTrue(dropPartitionResponse.ok());
-  }
-
-  @org.junit.jupiter.api.Test
-  void createIndex() {
-    insert();
-    assertTrue(client.flush(randomCollectionName).ok());
-
-    Index index =
-        new Index.Builder(randomCollectionName, IndexType.IVF_SQ8)
-            .withParamsInJson("{\"nlist\": 16384}")
-            .build();
-
-    Response createIndexResponse = client.createIndex(index);
-    assertTrue(createIndexResponse.ok());
-  }
-
-  @org.junit.jupiter.api.Test
-  void createIndexAsync() throws ExecutionException, InterruptedException {
-    insert();
-    assertTrue(client.flush(randomCollectionName).ok());
-
-    Index index =
-        new Index.Builder(randomCollectionName, IndexType.IVF_SQ8)
-            .withParamsInJson("{\"nlist\": 16384}")
-            .build();
-
-    ListenableFuture<Response> createIndexResponseFuture = client.createIndexAsync(index);
-    Response createIndexResponse = createIndexResponseFuture.get();
-    assertTrue(createIndexResponse.ok());
-  }
-
-  @org.junit.jupiter.api.Test
-  void insert() {
-    List<List<Float>> vectors = generateFloatVectors(size, dimension);
-    InsertParam insertParam =
-        new InsertParam.Builder(randomCollectionName).withFloatVectors(vectors).build();
-    InsertResponse insertResponse = client.insert(insertParam);
-    assertTrue(insertResponse.ok());
-    assertEquals(size, insertResponse.getVectorIds().size());
-  }
-
-  @org.junit.jupiter.api.Test
-  void insertAsync() throws ExecutionException, InterruptedException {
-    List<List<Float>> vectors = generateFloatVectors(size, dimension);
-    InsertParam insertParam =
-        new InsertParam.Builder(randomCollectionName).withFloatVectors(vectors).build();
-    ListenableFuture<InsertResponse> insertResponseFuture = client.insertAsync(insertParam);
-    InsertResponse insertResponse = insertResponseFuture.get();
-    assertTrue(insertResponse.ok());
-    assertEquals(size, insertResponse.getVectorIds().size());
-  }
-
-  @org.junit.jupiter.api.Test
-  void insertBinary() {
-    final int binaryDimension = 10000;
-
-    String binaryCollectionName = generator.generate(10);
-    CollectionMapping collectionMapping =
-        new CollectionMapping.Builder(binaryCollectionName, binaryDimension)
-            .withIndexFileSize(1024)
-            .withMetricType(MetricType.JACCARD)
-            .build();
-
-    assertTrue(client.createCollection(collectionMapping).ok());
-
-    List<ByteBuffer> vectors = generateBinaryVectors(size, binaryDimension);
-    InsertParam insertParam =
-        new InsertParam.Builder(binaryCollectionName).withBinaryVectors(vectors).build();
-    InsertResponse insertResponse = client.insert(insertParam);
-    assertTrue(insertResponse.ok());
-    assertEquals(size, insertResponse.getVectorIds().size());
-
-    assertTrue(client.dropCollection(binaryCollectionName).ok());
-  }
-
-  @org.junit.jupiter.api.Test
-  void search() {
-    List<List<Float>> vectors = generateFloatVectors(size, dimension);
-    vectors = vectors.stream().map(MilvusClientTest::normalizeVector).collect(Collectors.toList());
-    InsertParam insertParam =
-        new InsertParam.Builder(randomCollectionName).withFloatVectors(vectors).build();
-    InsertResponse insertResponse = client.insert(insertParam);
-    assertTrue(insertResponse.ok());
-    List<Long> vectorIds = insertResponse.getVectorIds();
-    assertEquals(size, vectorIds.size());
-
-    assertTrue(client.flush(randomCollectionName).ok());
-
-    final int searchSize = 5;
-    List<List<Float>> vectorsToSearch = vectors.subList(0, searchSize);
-
-    final long topK = 10;
-    SearchParam searchParam =
-        new SearchParam.Builder(randomCollectionName)
-            .withFloatVectors(vectorsToSearch)
-            .withTopK(topK)
-            .withParamsInJson("{\"nprobe\": 20}")
-            .build();
-    SearchResponse searchResponse = client.search(searchParam);
-    assertTrue(searchResponse.ok());
-    List<List<Long>> resultIdsList = searchResponse.getResultIdsList();
-    assertEquals(searchSize, resultIdsList.size());
-    List<List<Float>> resultDistancesList = searchResponse.getResultDistancesList();
-    assertEquals(searchSize, resultDistancesList.size());
-    List<List<SearchResponse.QueryResult>> queryResultsList = searchResponse.getQueryResultsList();
-    assertEquals(searchSize, queryResultsList.size());
-
-    final double epsilon = 0.001;
-    for (int i = 0; i < searchSize; i++) {
-      SearchResponse.QueryResult firstQueryResult = queryResultsList.get(i).get(0);
-      assertEquals(vectorIds.get(i), firstQueryResult.getVectorId());
-      assertEquals(vectorIds.get(i), resultIdsList.get(i).get(0));
-      assertTrue(Math.abs(1 - firstQueryResult.getDistance()) < epsilon);
-      assertTrue(Math.abs(1 - resultDistancesList.get(i).get(0)) < epsilon);
-    }
-  }
-
-  @org.junit.jupiter.api.Test
-  void searchAsync() throws ExecutionException, InterruptedException {
-    List<List<Float>> vectors = generateFloatVectors(size, dimension);
-    vectors = vectors.stream().map(MilvusClientTest::normalizeVector).collect(Collectors.toList());
-    InsertParam insertParam =
-        new InsertParam.Builder(randomCollectionName).withFloatVectors(vectors).build();
-    InsertResponse insertResponse = client.insert(insertParam);
-    assertTrue(insertResponse.ok());
-    List<Long> vectorIds = insertResponse.getVectorIds();
-    assertEquals(size, vectorIds.size());
-
-    assertTrue(client.flush(randomCollectionName).ok());
-
-    final int searchSize = 5;
-    List<List<Float>> vectorsToSearch = vectors.subList(0, searchSize);
-
-    final long topK = 10;
-    SearchParam searchParam =
-        new SearchParam.Builder(randomCollectionName)
-            .withFloatVectors(vectorsToSearch)
-            .withTopK(topK)
-            .withParamsInJson("{\"nprobe\": 20}")
-            .build();
-    ListenableFuture<SearchResponse> searchResponseFuture = client.searchAsync(searchParam);
-    SearchResponse searchResponse = searchResponseFuture.get();
-    assertTrue(searchResponse.ok());
-    List<List<Long>> resultIdsList = searchResponse.getResultIdsList();
-    assertEquals(searchSize, resultIdsList.size());
-    List<List<Float>> resultDistancesList = searchResponse.getResultDistancesList();
-    assertEquals(searchSize, resultDistancesList.size());
-    List<List<SearchResponse.QueryResult>> queryResultsList = searchResponse.getQueryResultsList();
-    assertEquals(searchSize, queryResultsList.size());
-    final double epsilon = 0.001;
-    for (int i = 0; i < searchSize; i++) {
-      SearchResponse.QueryResult firstQueryResult = queryResultsList.get(i).get(0);
-      assertEquals(vectorIds.get(i), firstQueryResult.getVectorId());
-      assertEquals(vectorIds.get(i), resultIdsList.get(i).get(0));
-      assertTrue(Math.abs(1 - firstQueryResult.getDistance()) < epsilon);
-      assertTrue(Math.abs(1 - resultDistancesList.get(i).get(0)) < epsilon);
-    }
-  }
-
-  @org.junit.jupiter.api.Test
-  void searchBinary() {
-    final int binaryDimension = 10000;
-
-    String binaryCollectionName = generator.generate(10);
-    CollectionMapping collectionMapping =
-        new CollectionMapping.Builder(binaryCollectionName, binaryDimension)
-            .withIndexFileSize(1024)
-            .withMetricType(MetricType.JACCARD)
-            .build();
-
-    assertTrue(client.createCollection(collectionMapping).ok());
-
-    List<ByteBuffer> vectors = generateBinaryVectors(size, binaryDimension);
-    InsertParam insertParam =
-        new InsertParam.Builder(binaryCollectionName).withBinaryVectors(vectors).build();
-    InsertResponse insertResponse = client.insert(insertParam);
-    assertTrue(insertResponse.ok());
-    List<Long> vectorIds = insertResponse.getVectorIds();
-    assertEquals(size, vectorIds.size());
-
-    assertTrue(client.flush(binaryCollectionName).ok());
-
-    final int searchSize = 5;
-    List<ByteBuffer> vectorsToSearch = vectors.subList(0, searchSize);
-
-    final long topK = 10;
-    SearchParam searchParam =
-        new SearchParam.Builder(binaryCollectionName)
-            .withBinaryVectors(vectorsToSearch)
-            .withTopK(topK)
-            .withParamsInJson("{\"nprobe\": 20}")
-            .build();
-    SearchResponse searchResponse = client.search(searchParam);
-    assertTrue(searchResponse.ok());
-    List<List<Long>> resultIdsList = searchResponse.getResultIdsList();
-    assertEquals(searchSize, resultIdsList.size());
-    List<List<Float>> resultDistancesList = searchResponse.getResultDistancesList();
-    assertEquals(searchSize, resultDistancesList.size());
-    List<List<SearchResponse.QueryResult>> queryResultsList = searchResponse.getQueryResultsList();
-    assertEquals(searchSize, queryResultsList.size());
-    final double epsilon = 0.001;
-    for (int i = 0; i < searchSize; i++) {
-      SearchResponse.QueryResult firstQueryResult = queryResultsList.get(i).get(0);
-      assertEquals(vectorIds.get(i), firstQueryResult.getVectorId());
-      assertEquals(vectorIds.get(i), resultIdsList.get(i).get(0));
-    }
-
-    assertTrue(client.dropCollection(binaryCollectionName).ok());
-  }
-
-  @org.junit.jupiter.api.Test
-  void getCollectionInfo() {
-    GetCollectionInfoResponse getCollectionInfoResponse =
-        client.getCollectionInfo(randomCollectionName);
-    assertTrue(getCollectionInfoResponse.ok());
-    assertTrue(getCollectionInfoResponse.getCollectionMapping().isPresent());
-    assertEquals(
-        getCollectionInfoResponse.getCollectionMapping().get().getCollectionName(),
-        randomCollectionName);
-
-    String nonExistingCollectionName = generator.generate(10);
-    getCollectionInfoResponse = client.getCollectionInfo(nonExistingCollectionName);
-    assertFalse(getCollectionInfoResponse.ok());
-    assertFalse(getCollectionInfoResponse.getCollectionMapping().isPresent());
-  }
-
-  @org.junit.jupiter.api.Test
-  void listCollections() {
-    ListCollectionsResponse listCollectionsResponse = client.listCollections();
-    assertTrue(listCollectionsResponse.ok());
-    assertTrue(listCollectionsResponse.getCollectionNames().contains(randomCollectionName));
-  }
-
-  @org.junit.jupiter.api.Test
-  void serverStatus() {
-    Response serverStatusResponse = client.getServerStatus();
-    assertTrue(serverStatusResponse.ok());
-  }
-
-  @org.junit.jupiter.api.Test
-  void serverVersion() {
-    Response serverVersionResponse = client.getServerVersion();
-    assertTrue(serverVersionResponse.ok());
-  }
-
-  @org.junit.jupiter.api.Test
-  void countEntities() {
-    insert();
-    assertTrue(client.flush(randomCollectionName).ok());
-
-    CountEntitiesResponse countEntitiesResponse = client.countEntities(randomCollectionName);
-    assertTrue(countEntitiesResponse.ok());
-    assertEquals(size, countEntitiesResponse.getCollectionEntityCount());
-  }
-
-  @org.junit.jupiter.api.Test
-  void loadCollection() {
-    insert();
-    assertTrue(client.flush(randomCollectionName).ok());
-
-    Response loadCollectionResponse = client.loadCollection(randomCollectionName);
-    assertTrue(loadCollectionResponse.ok());
-  }
-
-  @org.junit.jupiter.api.Test
-  void getIndexInfo() {
-    createIndex();
-
-    GetIndexInfoResponse getIndexInfoResponse = client.getIndexInfo(randomCollectionName);
-    assertTrue(getIndexInfoResponse.ok());
-    assertTrue(getIndexInfoResponse.getIndex().isPresent());
-    assertEquals(getIndexInfoResponse.getIndex().get().getCollectionName(), randomCollectionName);
-    assertEquals(getIndexInfoResponse.getIndex().get().getIndexType(), IndexType.IVF_SQ8);
-  }
-
-  @org.junit.jupiter.api.Test
-  void dropIndex() {
-    Response dropIndexResponse = client.dropIndex(randomCollectionName);
-    assertTrue(dropIndexResponse.ok());
-  }
-
-  @org.junit.jupiter.api.Test
-  void getCollectionStats() {
-    insert();
-
-    assertTrue(client.flush(randomCollectionName).ok());
-
-    Response getCollectionStatsResponse = client.getCollectionStats(randomCollectionName);
-    assertTrue(getCollectionStatsResponse.ok());
-
-    String jsonString = getCollectionStatsResponse.getMessage();
-    JSONObject jsonInfo = new JSONObject(jsonString);
-    assertTrue(jsonInfo.getInt("row_count") == size);
-
-    JSONArray partitions = jsonInfo.getJSONArray("partitions");
-    JSONObject partitionInfo = partitions.getJSONObject(0);
-    assertEquals(partitionInfo.getString("tag"), "_default");
-    assertEquals(partitionInfo.getInt("row_count"), size);
-
-    JSONArray segments = partitionInfo.getJSONArray("segments");
-    JSONObject segmentInfo = segments.getJSONObject(0);
-    assertEquals(segmentInfo.getString("index_name"), "IDMAP");
-    assertEquals(segmentInfo.getInt("row_count"), size);
-  }
-
-  @org.junit.jupiter.api.Test
-  void getEntityByID() {
-    List<List<Float>> vectors = generateFloatVectors(size, dimension);
-    InsertParam insertParam =
-        new InsertParam.Builder(randomCollectionName).withFloatVectors(vectors).build();
-    InsertResponse insertResponse = client.insert(insertParam);
-    assertTrue(insertResponse.ok());
-    List<Long> vectorIds = insertResponse.getVectorIds();
-    assertEquals(size, vectorIds.size());
-
-    assertTrue(client.flush(randomCollectionName).ok());
-
-    GetEntityByIDResponse getEntityByIDResponse =
-        client.getEntityByID(randomCollectionName, vectorIds.subList(0, 100));
-    assertTrue(getEntityByIDResponse.ok());
-    ByteBuffer bb = getEntityByIDResponse.getBinaryVectors().get(0);
-    assertTrue(bb == null || bb.remaining() == 0);
-
-    assertArrayEquals(
-        getEntityByIDResponse.getFloatVectors().get(0).toArray(), vectors.get(0).toArray());
-  }
-
-  @org.junit.jupiter.api.Test
-  void getVectorIds() {
-    insert();
-
-    assertTrue(client.flush(randomCollectionName).ok());
-
-    Response getCollectionStatsResponse = client.getCollectionStats(randomCollectionName);
-    assertTrue(getCollectionStatsResponse.ok());
-
-    JSONObject jsonInfo = new JSONObject(getCollectionStatsResponse.getMessage());
-    JSONObject segmentInfo =
-        jsonInfo
-            .getJSONArray("partitions")
-            .getJSONObject(0)
-            .getJSONArray("segments")
-            .getJSONObject(0);
-
-    ListIDInSegmentResponse listIDInSegmentResponse =
-        client.listIDInSegment(randomCollectionName, segmentInfo.getString("name"));
-    assertTrue(listIDInSegmentResponse.ok());
-    assertFalse(listIDInSegmentResponse.getIds().isEmpty());
-  }
-
-  @org.junit.jupiter.api.Test
-  void deleteEntityByID() {
-    List<List<Float>> vectors = generateFloatVectors(size, dimension);
-    InsertParam insertParam =
-        new InsertParam.Builder(randomCollectionName).withFloatVectors(vectors).build();
-    InsertResponse insertResponse = client.insert(insertParam);
-    assertTrue(insertResponse.ok());
-    List<Long> vectorIds = insertResponse.getVectorIds();
-    assertEquals(size, vectorIds.size());
-
-    assertTrue(client.flush(randomCollectionName).ok());
-
-    assertTrue(client.deleteEntityByID(randomCollectionName, vectorIds.subList(0, 100)).ok());
-    assertTrue(client.flush(randomCollectionName).ok());
-    assertEquals(client.countEntities(randomCollectionName).getCollectionEntityCount(), size - 100);
-  }
-
-  @org.junit.jupiter.api.Test
-  void flush() {
-    assertTrue(client.flush(randomCollectionName).ok());
-  }
-
-  @org.junit.jupiter.api.Test
-  void flushAsync() throws ExecutionException, InterruptedException {
-    assertTrue(client.flushAsync(randomCollectionName).get().ok());
-  }
-
-  @org.junit.jupiter.api.Test
-  void compact() {
-    List<List<Float>> vectors = generateFloatVectors(size, dimension);
-    InsertParam insertParam =
-        new InsertParam.Builder(randomCollectionName).withFloatVectors(vectors).build();
-    InsertResponse insertResponse = client.insert(insertParam);
-    assertTrue(insertResponse.ok());
-    List<Long> vectorIds = insertResponse.getVectorIds();
-    assertEquals(size, vectorIds.size());
-
-    assertTrue(client.flush(randomCollectionName).ok());
-
-    Response getCollectionStatsResponse = client.getCollectionStats(randomCollectionName);
-    assertTrue(getCollectionStatsResponse.ok());
-
-    JSONObject jsonInfo = new JSONObject(getCollectionStatsResponse.getMessage());
-    JSONObject segmentInfo =
-        jsonInfo
-            .getJSONArray("partitions")
-            .getJSONObject(0)
-            .getJSONArray("segments")
-            .getJSONObject(0);
-
-    long previousSegmentSize = segmentInfo.getLong("data_size");
-
-    assertTrue(
-        client.deleteEntityByID(randomCollectionName, vectorIds.subList(0, (int) size / 2)).ok());
-    assertTrue(client.flush(randomCollectionName).ok());
-    assertTrue(client.compact(randomCollectionName).ok());
-
-    getCollectionStatsResponse = client.getCollectionStats(randomCollectionName);
-    assertTrue(getCollectionStatsResponse.ok());
-    jsonInfo = new JSONObject(getCollectionStatsResponse.getMessage());
-    segmentInfo =
-        jsonInfo
-            .getJSONArray("partitions")
-            .getJSONObject(0)
-            .getJSONArray("segments")
-            .getJSONObject(0);
-
-    long currentSegmentSize = segmentInfo.getLong("data_size");
-    assertTrue(currentSegmentSize < previousSegmentSize);
-  }
-
-  @org.junit.jupiter.api.Test
-  void compactAsync() throws ExecutionException, InterruptedException {
-    List<List<Float>> vectors = generateFloatVectors(size, dimension);
-    InsertParam insertParam =
-        new InsertParam.Builder(randomCollectionName).withFloatVectors(vectors).build();
-    InsertResponse insertResponse = client.insert(insertParam);
-    assertTrue(insertResponse.ok());
-    List<Long> vectorIds = insertResponse.getVectorIds();
-    assertEquals(size, vectorIds.size());
-
-    assertTrue(client.flush(randomCollectionName).ok());
-
-    Response getCollectionStatsResponse = client.getCollectionStats(randomCollectionName);
-    assertTrue(getCollectionStatsResponse.ok());
-
-    JSONObject jsonInfo = new JSONObject(getCollectionStatsResponse.getMessage());
-    JSONObject segmentInfo =
-        jsonInfo
-            .getJSONArray("partitions")
-            .getJSONObject(0)
-            .getJSONArray("segments")
-            .getJSONObject(0);
-
-    long previousSegmentSize = segmentInfo.getLong("data_size");
-
-    assertTrue(
-        client.deleteEntityByID(randomCollectionName, vectorIds.subList(0, (int) size / 2)).ok());
-    assertTrue(client.flush(randomCollectionName).ok());
-    assertTrue(client.compactAsync(randomCollectionName).get().ok());
-
-    getCollectionStatsResponse = client.getCollectionStats(randomCollectionName);
-    assertTrue(getCollectionStatsResponse.ok());
-    jsonInfo = new JSONObject(getCollectionStatsResponse.getMessage());
-    segmentInfo =
-        jsonInfo
-            .getJSONArray("partitions")
-            .getJSONObject(0)
-            .getJSONArray("segments")
-            .getJSONObject(0);
-    long currentSegmentSize = segmentInfo.getLong("data_size");
-
-    assertTrue(currentSegmentSize < previousSegmentSize);
-  }
-}