浏览代码

Add keepalive and idleTimeout settings & add ok() in other types of Response

Zhiru Zhu 5 年之前
父节点
当前提交
2d946e0617

+ 16 - 0
CHANGELOG.md

@@ -1,5 +1,21 @@
 # Changelog     
 
+## milvus-sdk-java 0.3.0 (TBD)
+
+### Bug
+---
+
+### Improvement
+---
+- \#56 - Add keepalive and idleTimeout settings
+- \#57 - add ok() in other types of Response
+
+### Feature
+---
+
+### Task
+---
+
 ## milvus-sdk-java 0.2.2 (2018-11-4)
 
 ### Bug

+ 1 - 1
examples/pom.xml

@@ -48,7 +48,7 @@
         <dependency>
             <groupId>io.milvus</groupId>
             <artifactId>milvus-sdk-java</artifactId>
-            <version>0.2.2</version>
+            <version>0.3.0-SNAPSHOT</version>
         </dependency>
     </dependencies>
 

+ 1 - 1
pom.xml

@@ -25,7 +25,7 @@
 
     <groupId>io.milvus</groupId>
     <artifactId>milvus-sdk-java</artifactId>
-    <version>0.2.2</version>
+    <version>0.3.0-SNAPSHOT</version>
     <packaging>jar</packaging>
 
     <name>io.milvus:milvus-sdk-java</name>

+ 144 - 14
src/main/java/io/milvus/client/ConnectParam.java

@@ -20,17 +20,26 @@
 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 String port;
-  private final long timeout;
+  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.timeout = builder.timeout;
+    this.connectTimeoutNanos = builder.connectTimeoutNanos;
+    this.keepAliveTimeNanos = builder.keepAliveTimeNanos;
+    this.keepAliveTimeoutNanos = builder.keepAliveTimeoutNanos;
+    this.keepAliveWithoutCalls = builder.keepAliveWithoutCalls;
+    this.idleTimeoutNanos = builder.idleTimeoutNanos;
   }
 
   public String getHost() {
@@ -41,24 +50,61 @@ public class ConnectParam {
     return port;
   }
 
-  public long getTimeout() {
-    return timeout;
+  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);
   }
 
   @Override
   public String toString() {
-    return "ConnectParam{" + "host='" + host + '\'' + ", port='" + port + '\'' + '}';
+    return "ConnectParam {"
+        + "host='"
+        + host
+        + '\''
+        + ", port='"
+        + port
+        + '\''
+        + ", connectTimeoutNanos="
+        + connectTimeoutNanos
+        + ", keepAliveTimeNanos="
+        + keepAliveTimeNanos
+        + ", keepAliveTimeoutNanos="
+        + keepAliveTimeoutNanos
+        + ", keepAliveWithoutCalls="
+        + keepAliveWithoutCalls
+        + ", idleTimeoutNanos="
+        + idleTimeoutNanos
+        + '}';
   }
 
   /** Builder for <code>ConnectParam</code> */
   public static class Builder {
     // Optional parameters - initialized to default values
-    private String host = "127.0.0.1";
+    private String host = "localhost";
     private String port = "19530";
-    private long timeout = 10000; // ms
+    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. Default to "127.0.0.1".
+     * Optional. Defaults to "localhost".
      *
      * @param host server host
      * @return <code>Builder</code>
@@ -69,24 +115,108 @@ public class ConnectParam {
     }
 
     /**
-     * Optional. Default to "19530".
+     * Optional. Defaults to "19530".
      *
      * @param port server port
      * @return <code>Builder</code>
      */
-    public Builder withPort(@Nonnull String port) {
+    public Builder withPort(@Nonnull String port) throws IllegalArgumentException {
+      int portInt = Integer.parseInt(port);
+      if (portInt < 0 || portInt > 0xFFFF) {
+        throw new IllegalArgumentException("Port is out of range!");
+      }
       this.port = port;
       return this;
     }
 
     /**
-     * Optional. Default to 10000 ms
+     * 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. Defaults to 24
+     * hour.
      *
-     * @param timeout Timeout in ms for client to establish a connection to server
+     * @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 withTimeout(long timeout) {
-      this.timeout = timeout;
+    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;
     }
 

+ 4 - 0
src/main/java/io/milvus/client/DescribeIndexResponse.java

@@ -47,6 +47,10 @@ public class DescribeIndexResponse {
     return response;
   }
 
+  public boolean ok() {
+    return response.ok();
+  }
+
   @Override
   public String toString() {
     return String.format(

+ 4 - 0
src/main/java/io/milvus/client/DescribeTableResponse.java

@@ -48,6 +48,10 @@ public class DescribeTableResponse {
     return response;
   }
 
+  public boolean ok() {
+    return response.ok();
+  }
+
   @Override
   public String toString() {
     return String.format(

+ 4 - 0
src/main/java/io/milvus/client/GetTableRowCountResponse.java

@@ -40,6 +40,10 @@ public class GetTableRowCountResponse {
     return response;
   }
 
+  public boolean ok() {
+    return response.ok();
+  }
+
   @Override
   public String toString() {
     return String.format(

+ 4 - 0
src/main/java/io/milvus/client/HasTableResponse.java

@@ -39,6 +39,10 @@ public class HasTableResponse {
     return response;
   }
 
+  public boolean ok() {
+    return response.ok();
+  }
+
   @Override
   public String toString() {
     return String.format("HasTableResponse {%s, has table = %s}", response.toString(), hasTable);

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

@@ -41,6 +41,10 @@ public class InsertResponse {
     return response;
   }
 
+  public boolean ok() {
+    return response.ok();
+  }
+
   @Override
   public String toString() {
     return String.format(

+ 6 - 2
src/main/java/io/milvus/client/MilvusClient.java

@@ -22,7 +22,7 @@ package io.milvus.client;
 /** The Milvus Client Interface */
 public interface MilvusClient {
 
-  String clientVersion = "0.2.2";
+  String clientVersion = "0.3.0";
 
   /** @return the current Milvus client version */
   default String getClientVersion() {
@@ -39,7 +39,11 @@ public interface MilvusClient {
    * ConnectParam connectParam = new ConnectParam.Builder()
    *                                             .withHost("localhost")
    *                                             .withPort("19530")
-   *                                             .withTimeout(10000)
+   *                                             .withConnectTimeout(10, TimeUnit.SECONDS)
+   *                                             .withKeepAliveTime(Long.MAX_VALUE, TimeUnit.NANOSECONDS)
+   *                                             .withKeepAliveTimeout(20, TimeUnit.SECONDS)
+   *                                             .keepAliveWithoutCalls(false)
+   *                                             .withIdleTimeout(24, TimeUnit.HOURS)
    *                                             .build();
    * </code>
    * </pre>

+ 35 - 23
src/main/java/io/milvus/client/MilvusGrpcClient.java

@@ -55,22 +55,24 @@ public class MilvusGrpcClient implements MilvusClient {
     }
 
     try {
-      int port = Integer.parseInt(connectParam.getPort());
-      if (port < 0 || port > 0xFFFF) {
-        logSevere("Connect failed! Port {0} out of range", connectParam.getPort());
-        throw new ConnectFailedException("Port " + port + " out of range");
-      }
 
       channel =
-          ManagedChannelBuilder.forAddress(connectParam.getHost(), port)
+          ManagedChannelBuilder.forAddress(
+                  connectParam.getHost(), Integer.parseInt(connectParam.getPort()))
               .usePlaintext()
               .maxInboundMessageSize(Integer.MAX_VALUE)
+              .keepAliveTime(
+                  connectParam.getKeepAliveTime(TimeUnit.NANOSECONDS), TimeUnit.NANOSECONDS)
+              .keepAliveTimeout(
+                  connectParam.getKeepAliveTimeout(TimeUnit.NANOSECONDS), TimeUnit.SECONDS)
+              .keepAliveWithoutCalls(connectParam.isKeepAliveWithoutCalls())
+              .idleTimeout(connectParam.getIdleTimeout(TimeUnit.NANOSECONDS), TimeUnit.NANOSECONDS)
               .build();
 
       ConnectivityState connectivityState;
       connectivityState = channel.getState(true);
 
-      long timeout = connectParam.getTimeout();
+      long timeout = connectParam.getConnectTimeout(TimeUnit.MILLISECONDS);
       logInfo("Trying to connect...Timeout in {0} ms", timeout);
 
       final long checkFrequency = 100; // ms
@@ -107,7 +109,7 @@ public class MilvusGrpcClient implements MilvusClient {
 
   @Override
   public Response disconnect() throws InterruptedException {
-    if (!isConnected()) {
+    if (!channelIsReadyOrIdle()) {
       logWarning("You are not connected to Milvus server");
       return new Response(Response.Status.CLIENT_NOT_CONNECTED);
     } else {
@@ -129,7 +131,7 @@ public class MilvusGrpcClient implements MilvusClient {
   @Override
   public Response createTable(@Nonnull TableSchema tableSchema) {
 
-    if (!isConnected()) {
+    if (!channelIsReadyOrIdle()) {
       logWarning("You are not connected to Milvus server");
       return new Response(Response.Status.CLIENT_NOT_CONNECTED);
     }
@@ -168,7 +170,7 @@ public class MilvusGrpcClient implements MilvusClient {
   @Override
   public HasTableResponse hasTable(@Nonnull String tableName) {
 
-    if (!isConnected()) {
+    if (!channelIsReadyOrIdle()) {
       logWarning("You are not connected to Milvus server");
       return new HasTableResponse(new Response(Response.Status.CLIENT_NOT_CONNECTED), false);
     }
@@ -200,7 +202,7 @@ public class MilvusGrpcClient implements MilvusClient {
   @Override
   public Response dropTable(@Nonnull String tableName) {
 
-    if (!isConnected()) {
+    if (!channelIsReadyOrIdle()) {
       logWarning("You are not connected to Milvus server");
       return new Response(Response.Status.CLIENT_NOT_CONNECTED);
     }
@@ -229,7 +231,7 @@ public class MilvusGrpcClient implements MilvusClient {
   @Override
   public Response createIndex(@Nonnull CreateIndexParam createIndexParam) {
 
-    if (!isConnected()) {
+    if (!channelIsReadyOrIdle()) {
       logWarning("You are not connected to Milvus server");
       return new Response(Response.Status.CLIENT_NOT_CONNECTED);
     }
@@ -268,7 +270,7 @@ public class MilvusGrpcClient implements MilvusClient {
   @Override
   public InsertResponse insert(@Nonnull InsertParam insertParam) {
 
-    if (!isConnected()) {
+    if (!channelIsReadyOrIdle()) {
       logWarning("You are not connected to Milvus server");
       return new InsertResponse(
           new Response(Response.Status.CLIENT_NOT_CONNECTED), new ArrayList<>());
@@ -317,7 +319,7 @@ public class MilvusGrpcClient implements MilvusClient {
   @Override
   public SearchResponse search(@Nonnull SearchParam searchParam) {
 
-    if (!isConnected()) {
+    if (!channelIsReadyOrIdle()) {
       logWarning("You are not connected to Milvus server");
       return new SearchResponse(
           new Response(Response.Status.CLIENT_NOT_CONNECTED), new ArrayList<>());
@@ -365,7 +367,7 @@ public class MilvusGrpcClient implements MilvusClient {
   @Override
   public SearchResponse searchInFiles(@Nonnull SearchInFilesParam searchInFilesParam) {
 
-    if (!isConnected()) {
+    if (!channelIsReadyOrIdle()) {
       logWarning("You are not connected to Milvus server");
       return new SearchResponse(
           new Response(Response.Status.CLIENT_NOT_CONNECTED), new ArrayList<>());
@@ -422,7 +424,7 @@ public class MilvusGrpcClient implements MilvusClient {
   @Override
   public DescribeTableResponse describeTable(@Nonnull String tableName) {
 
-    if (!isConnected()) {
+    if (!channelIsReadyOrIdle()) {
       logWarning("You are not connected to Milvus server");
       return new DescribeTableResponse(new Response(Response.Status.CLIENT_NOT_CONNECTED), null);
     }
@@ -459,7 +461,7 @@ public class MilvusGrpcClient implements MilvusClient {
   @Override
   public ShowTablesResponse showTables() {
 
-    if (!isConnected()) {
+    if (!channelIsReadyOrIdle()) {
       logWarning("You are not connected to Milvus server");
       return new ShowTablesResponse(
           new Response(Response.Status.CLIENT_NOT_CONNECTED), new ArrayList<>());
@@ -493,7 +495,7 @@ public class MilvusGrpcClient implements MilvusClient {
   @Override
   public GetTableRowCountResponse getTableRowCount(@Nonnull String tableName) {
 
-    if (!isConnected()) {
+    if (!channelIsReadyOrIdle()) {
       logWarning("You are not connected to Milvus server");
       return new GetTableRowCountResponse(new Response(Response.Status.CLIENT_NOT_CONNECTED), 0);
     }
@@ -535,7 +537,7 @@ public class MilvusGrpcClient implements MilvusClient {
 
   private Response command(@Nonnull String command) {
 
-    if (!isConnected()) {
+    if (!channelIsReadyOrIdle()) {
       logWarning("You are not connected to Milvus server");
       return new Response(Response.Status.CLIENT_NOT_CONNECTED);
     }
@@ -564,7 +566,7 @@ public class MilvusGrpcClient implements MilvusClient {
   // TODO: make deleteByRange private for now
   private Response deleteByRange(@Nonnull String tableName, @Nonnull DateRange dateRange) {
 
-    if (!isConnected()) {
+    if (!channelIsReadyOrIdle()) {
       logWarning("You are not connected to Milvus server");
       return new Response(Response.Status.CLIENT_NOT_CONNECTED);
     }
@@ -599,7 +601,7 @@ public class MilvusGrpcClient implements MilvusClient {
   @Override
   public Response preloadTable(@Nonnull String tableName) {
 
-    if (!isConnected()) {
+    if (!channelIsReadyOrIdle()) {
       logWarning("You are not connected to Milvus server");
       return new Response(Response.Status.CLIENT_NOT_CONNECTED);
     }
@@ -628,7 +630,7 @@ public class MilvusGrpcClient implements MilvusClient {
   @Override
   public DescribeIndexResponse describeIndex(@Nonnull String tableName) {
 
-    if (!isConnected()) {
+    if (!channelIsReadyOrIdle()) {
       logWarning("You are not connected to Milvus server");
       return new DescribeIndexResponse(new Response(Response.Status.CLIENT_NOT_CONNECTED), null);
     }
@@ -665,7 +667,7 @@ public class MilvusGrpcClient implements MilvusClient {
   @Override
   public Response dropIndex(@Nonnull String tableName) {
 
-    if (!isConnected()) {
+    if (!channelIsReadyOrIdle()) {
       logWarning("You are not connected to Milvus server");
       return new Response(Response.Status.CLIENT_NOT_CONNECTED);
     }
@@ -747,6 +749,16 @@ public class MilvusGrpcClient implements MilvusClient {
     return queryResultsList;
   }
 
+  private boolean channelIsReadyOrIdle() {
+    if (channel == null) {
+      return false;
+    }
+    ConnectivityState connectivityState = channel.getState(false);
+    return connectivityState == ConnectivityState.READY
+        || connectivityState
+            == ConnectivityState.IDLE; // Since a new RPC would take the channel out of idle mode
+  }
+
   ///////////////////// Log Functions//////////////////////
 
   private void logInfo(String msg, Object... params) {

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

@@ -80,6 +80,10 @@ public class SearchResponse {
     return response;
   }
 
+  public boolean ok() {
+    return response.ok();
+  }
+
   @Override
   public String toString() {
     return String.format(

+ 4 - 0
src/main/java/io/milvus/client/ShowTablesResponse.java

@@ -42,6 +42,10 @@ public class ShowTablesResponse {
     return response;
   }
 
+  public boolean ok() {
+    return response.ok();
+  }
+
   @Override
   public String toString() {
     return String.format(

+ 31 - 12
src/test/java/io/milvus/client/MilvusGrpcClientTest.java

@@ -89,11 +89,16 @@ class MilvusClientTest {
   }
 
   @org.junit.jupiter.api.Test
-  void connectInvalidPort() {
+  void idleTest() throws InterruptedException, ConnectFailedException {
     MilvusClient client = new MilvusGrpcClient();
     ConnectParam connectParam =
-        new ConnectParam.Builder().withHost("localhost").withPort("66666").build();
-    assertThrows(ConnectFailedException.class, () -> client.connect(connectParam));
+        new ConnectParam.Builder().withHost("localhost").withIdleTimeout(1, TimeUnit.SECONDS).build();
+    client.connect(connectParam);
+    TimeUnit.SECONDS.sleep(2);
+    //Channel should be idle
+    assertFalse(client.isConnected());
+    //A new RPC would take the channel out of idle mode
+    assertTrue(client.showTables().ok());
   }
 
   @org.junit.jupiter.api.Test
@@ -120,7 +125,7 @@ class MilvusClientTest {
   @org.junit.jupiter.api.Test
   void hasTable() {
     HasTableResponse hasTableResponse = client.hasTable(randomTableName);
-    assertTrue(hasTableResponse.getResponse().ok());
+    assertTrue(hasTableResponse.ok());
   }
 
   @org.junit.jupiter.api.Test
@@ -145,7 +150,7 @@ class MilvusClientTest {
     List<List<Float>> vectors = generateVectors(size, dimension);
     InsertParam insertParam = new InsertParam.Builder(randomTableName, vectors).build();
     InsertResponse insertResponse = client.insert(insertParam);
-    assertTrue(insertResponse.getResponse().ok());
+    assertTrue(insertResponse.ok());
     assertEquals(size, insertResponse.getVectorIds().size());
   }
 
@@ -155,7 +160,7 @@ class MilvusClientTest {
     vectors = vectors.stream().map(MilvusClientTest::normalizeVector).collect(Collectors.toList());
     InsertParam insertParam = new InsertParam.Builder(randomTableName, vectors).build();
     InsertResponse insertResponse = client.insert(insertParam);
-    assertTrue(insertResponse.getResponse().ok());
+    assertTrue(insertResponse.ok());
     List<Long> vectorIds = insertResponse.getVectorIds();
     assertEquals(size, vectorIds.size());
 
@@ -182,7 +187,7 @@ class MilvusClientTest {
             .withDateRanges(queryRanges)
             .build();
     SearchResponse searchResponse = client.search(searchParam);
-    assertTrue(searchResponse.getResponse().ok());
+    assertTrue(searchResponse.ok());
     System.out.println(searchResponse);
     List<List<SearchResponse.QueryResult>> queryResultsList = searchResponse.getQueryResultsList();
     assertEquals(searchSize, queryResultsList.size());
@@ -201,19 +206,19 @@ class MilvusClientTest {
   @org.junit.jupiter.api.Test
   void describeTable() {
     DescribeTableResponse describeTableResponse = client.describeTable(randomTableName);
-    assertTrue(describeTableResponse.getResponse().ok());
+    assertTrue(describeTableResponse.ok());
     assertTrue(describeTableResponse.getTableSchema().isPresent());
 
     String nonExistingTableName = generator.generate(10);
     describeTableResponse = client.describeTable(nonExistingTableName);
-    assertFalse(describeTableResponse.getResponse().ok());
+    assertFalse(describeTableResponse.ok());
     assertFalse(describeTableResponse.getTableSchema().isPresent());
   }
 
   @org.junit.jupiter.api.Test
   void showTables() {
     ShowTablesResponse showTablesResponse = client.showTables();
-    assertTrue(showTablesResponse.getResponse().ok());
+    assertTrue(showTablesResponse.ok());
   }
 
   @org.junit.jupiter.api.Test
@@ -234,7 +239,7 @@ class MilvusClientTest {
     TimeUnit.SECONDS.sleep(1);
 
     GetTableRowCountResponse getTableRowCountResponse = client.getTableRowCount(randomTableName);
-    assertTrue(getTableRowCountResponse.getResponse().ok());
+    assertTrue(getTableRowCountResponse.ok());
     assertEquals(size, getTableRowCountResponse.getTableRowCount());
   }
 
@@ -247,7 +252,7 @@ class MilvusClientTest {
   @org.junit.jupiter.api.Test
   void describeIndex() {
     DescribeIndexResponse describeIndexResponse = client.describeIndex(randomTableName);
-    assertTrue(describeIndexResponse.getResponse().ok());
+    assertTrue(describeIndexResponse.ok());
     assertTrue(describeIndexResponse.getIndex().isPresent());
   }
 
@@ -256,4 +261,18 @@ class MilvusClientTest {
     Response dropIndexResponse = client.dropIndex(randomTableName);
     assertTrue(dropIndexResponse.ok());
   }
+
+  @org.junit.jupiter.api.Test
+  void issue58() {
+    Index index = new Index.Builder().withIndexType(IndexType.IVF_SQ8).withNList(16384).build();
+    CreateIndexParam createIndexParam =
+        new CreateIndexParam.Builder(randomTableName).withIndex(index).build();
+    Response createIndexResponse = client.createIndex(createIndexParam);
+
+    DescribeIndexResponse describeIndexResponse = client.describeIndex(randomTableName);
+
+    Response dropIndexResponse = client.dropIndex(randomTableName);
+
+    describeIndexResponse = client.describeIndex(randomTableName);
+  }
 }