Browse Source

Add alterCollection interface (#461)

Signed-off-by: groot <yihua.mo@zilliz.com>
groot 2 years ago
parent
commit
66d88d269b

+ 36 - 0
src/main/java/io/milvus/client/AbstractMilvusGrpcClient.java

@@ -644,6 +644,42 @@ public abstract class AbstractMilvusGrpcClient implements MilvusClient {
         }
         }
     }
     }
 
 
+    @Override
+    public R<RpcStatus> alterCollection(AlterCollectionParam requestParam) {
+        if (!clientIsReady()) {
+            return R.failed(new ClientNotConnectedException("Client rpc channel is not ready"));
+        }
+
+        logInfo(requestParam.toString());
+
+        try {
+            AlterCollectionRequest.Builder alterCollRequestBuilder = AlterCollectionRequest.newBuilder();
+            List<KeyValuePair> propertiesList = assembleKvPair(requestParam.getProperties());
+            if (CollectionUtils.isNotEmpty(propertiesList)) {
+                propertiesList.forEach(alterCollRequestBuilder::addProperties);
+            }
+
+            AlterCollectionRequest alterCollectionRequest = alterCollRequestBuilder
+                    .setCollectionName(requestParam.getCollectionName())
+                    .build();
+
+            Status response = blockingStub().alterCollection(alterCollectionRequest);
+
+            if (response.getErrorCode() == ErrorCode.Success) {
+                logDebug("AlterCollectionRequest successfully!");
+                return R.success(new RpcStatus(RpcStatus.SUCCESS_MSG));
+            } else {
+                return failedStatus("AlterCollectionRequest", response);
+            }
+        } catch (StatusRuntimeException e) {
+            logError("AlterCollectionRequest RPC failed:\n{}", e.getStatus().toString());
+            return R.failed(e);
+        } catch (Exception e) {
+            logError("AlterCollectionRequest failed:\n{}", e.getMessage());
+            return R.failed(e);
+        }
+    }
+
     /**
     /**
      * Flush insert buffer into storage. To make sure the buffer persisted successfully, it calls
      * Flush insert buffer into storage. To make sure the buffer persisted successfully, it calls
      * GetFlushState() to check related segments state.
      * GetFlushState() to check related segments state.

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

@@ -130,6 +130,15 @@ public interface MilvusClient {
      */
      */
     R<ShowCollectionsResponse> showCollections(ShowCollectionsParam requestParam);
     R<ShowCollectionsResponse> showCollections(ShowCollectionsParam requestParam);
 
 
+    /**
+     * Alter collection.
+     * Currently, only support setting collection TTL with key `collection.ttl.seconds`
+     *
+     * @param requestParam {@link AlterCollectionParam}
+     * @return {status:result code, data:RpcStatus{msg: result message}}
+     */
+    R<RpcStatus> alterCollection(AlterCollectionParam requestParam);
+
     /**
     /**
      * Flushes inserted data in buffer into storage.
      * Flushes inserted data in buffer into storage.
      *
      *

+ 5 - 0
src/main/java/io/milvus/client/MilvusMultiServiceClient.java

@@ -161,6 +161,11 @@ public class MilvusMultiServiceClient implements MilvusClient {
         return this.clusterFactory.getMaster().getClient().showCollections(requestParam);
         return this.clusterFactory.getMaster().getClient().showCollections(requestParam);
     }
     }
 
 
+    @Override
+    public R<RpcStatus> alterCollection(AlterCollectionParam requestParam) {
+        return this.clusterFactory.getMaster().getClient().alterCollection(requestParam);
+    }
+
     @Override
     @Override
     public R<FlushResponse> flush(FlushParam requestParam) {
     public R<FlushResponse> flush(FlushParam requestParam) {
         List<R<FlushResponse>> response = this.clusterFactory.getAvailableServerSettings().parallelStream()
         List<R<FlushResponse>> response = this.clusterFactory.getAvailableServerSettings().parallelStream()

+ 3 - 0
src/main/java/io/milvus/param/Constant.java

@@ -43,6 +43,9 @@ public class Constant {
     public static final String DEFAULT_INDEX_NAME = "";
     public static final String DEFAULT_INDEX_NAME = "";
     public final static String OFFSET = "offset";
     public final static String OFFSET = "offset";
 
 
+    // constant values for general
+    public static final String TTL_SECONDS = "collection.ttl.seconds";
+
     // max value for waiting loading collection/partition interval, unit: millisecond
     // max value for waiting loading collection/partition interval, unit: millisecond
     public static final Long MAX_WAITING_LOADING_INTERVAL = 2000L;
     public static final Long MAX_WAITING_LOADING_INTERVAL = 2000L;
 
 

+ 120 - 0
src/main/java/io/milvus/param/collection/AlterCollectionParam.java

@@ -0,0 +1,120 @@
+/*
+ * 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.param.collection;
+
+import io.milvus.exception.ParamException;
+import io.milvus.param.Constant;
+import io.milvus.param.IndexType;
+import io.milvus.param.MetricType;
+import io.milvus.param.ParamUtils;
+import lombok.Getter;
+import lombok.NonNull;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Parameters for <code>alterCollection</code> interface.
+ */
+@Getter
+public class AlterCollectionParam {
+    private final String collectionName;
+    private final Map<String, String> properties = new HashMap<>();
+
+    private AlterCollectionParam(@NonNull Builder builder) {
+        this.collectionName = builder.collectionName;
+        if (builder.ttlSeconds >= 0) {
+            this.properties.put(Constant.TTL_SECONDS, Integer.toString(builder.ttlSeconds));
+        }
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link AlterCollectionParam} class.
+     */
+    public static final class Builder {
+        private String collectionName;
+
+        // The ttlSeconds value should be 0 or greater.
+        // In server side, the default value is 0, which means TTL is disabled.
+        // Here we set ttlSeconds = -1 to avoid being overwritten with unconscious
+        private Integer ttlSeconds = -1;
+
+
+        private Builder() {
+        }
+
+        /**
+         * Set the collection name. Collection name cannot be empty or null.
+         *
+         * @param collectionName collection name
+         * @return <code>Builder</code>
+         */
+        public Builder withCollectionName(@NonNull String collectionName) {
+            this.collectionName = collectionName;
+            return this;
+        }
+
+        /**
+         * Collection time to live (TTL) is the expiration time of data in a collection.
+         * Expired data in the collection will be cleaned up and will not be involved in searches or queries.
+         * Specify TTL in the unit of seconds.
+         *
+         * @param ttlSeconds TTL seconds, value should be 0 or greater
+         * @return <code>Builder</code>
+         */
+        public Builder withTTL(@NonNull Integer ttlSeconds) {
+            if (ttlSeconds < 0) {
+                throw new ParamException("The ttlSeconds value should be 0 or greater");
+            }
+            this.ttlSeconds = ttlSeconds;
+            return this;
+        }
+
+        /**
+         * Verifies parameters and creates a new {@link AlterCollectionParam} instance.
+         *
+         * @return {@link AlterCollectionParam}
+         */
+        public AlterCollectionParam build() throws ParamException {
+            ParamUtils.CheckNullEmptyString(collectionName, "Collection name");
+
+            return new AlterCollectionParam(this);
+        }
+    }
+
+    /**
+     * Constructs a <code>String</code> by {@link AlterCollectionParam} instance.
+     *
+     * @return <code>String</code>
+     */
+    @Override
+    public String toString() {
+        return "AlterCollectionParam{" +
+                "collectionName='" + collectionName + '\'' +
+                ", properties='" + properties.toString() + '\'' +
+                '}';
+    }
+}

+ 39 - 0
src/test/java/io/milvus/client/MilvusServiceClientTest.java

@@ -674,6 +674,45 @@ class MilvusServiceClientTest {
         testFuncByName("showCollections", param);
         testFuncByName("showCollections", param);
     }
     }
 
 
+    @Test
+    void alterCollectionParam() {
+        AlterCollectionParam param = AlterCollectionParam.newBuilder()
+                .withCollectionName("collection1")
+                .build();
+        assertEquals("collection1", param.getCollectionName());
+        assertTrue(param.getProperties().isEmpty());
+
+        param = AlterCollectionParam.newBuilder()
+                .withCollectionName("collection1")
+                .withTTL(100)
+                .build();
+        assertTrue(param.getProperties().containsKey(Constant.TTL_SECONDS));
+        assertEquals("100", param.getProperties().get(Constant.TTL_SECONDS));
+
+        assertThrows(ParamException.class, () ->
+                AlterCollectionParam.newBuilder()
+                        .withCollectionName("")
+                        .build()
+        );
+
+        assertThrows(ParamException.class, () ->
+                AlterCollectionParam.newBuilder()
+                        .withCollectionName("collection1")
+                        .withTTL(-5)
+                        .build()
+        );
+    }
+
+    @Test
+    void alterCollection() {
+        AlterCollectionParam param = AlterCollectionParam.newBuilder()
+                .withCollectionName("collection1")
+                .withTTL(100)
+                .build();
+
+        testFuncByName("alterCollection", param);
+    }
+
     @Test
     @Test
     void flushParam() {
     void flushParam() {
         // test throw exception with illegal input
         // test throw exception with illegal input

+ 10 - 0
src/test/java/io/milvus/server/MockMilvusServerImpl.java

@@ -34,6 +34,7 @@ public class MockMilvusServerImpl extends MilvusServiceGrpc.MilvusServiceImplBas
     private io.milvus.grpc.Status respLoadCollection;
     private io.milvus.grpc.Status respLoadCollection;
     private io.milvus.grpc.Status respReleaseCollection;
     private io.milvus.grpc.Status respReleaseCollection;
     private io.milvus.grpc.ShowCollectionsResponse respShowCollections;
     private io.milvus.grpc.ShowCollectionsResponse respShowCollections;
+    private io.milvus.grpc.Status respAlterCollection;
     private io.milvus.grpc.Status respCreatePartition;
     private io.milvus.grpc.Status respCreatePartition;
     private io.milvus.grpc.Status respDropPartition;
     private io.milvus.grpc.Status respDropPartition;
     private io.milvus.grpc.BoolResponse respHasPartition;
     private io.milvus.grpc.BoolResponse respHasPartition;
@@ -180,6 +181,15 @@ public class MockMilvusServerImpl extends MilvusServiceGrpc.MilvusServiceImplBas
         responseObserver.onCompleted();
         responseObserver.onCompleted();
     }
     }
 
 
+    @Override
+    public void alterCollection(io.milvus.grpc.AlterCollectionRequest request,
+                                io.grpc.stub.StreamObserver<io.milvus.grpc.Status> responseObserver) {
+        logger.info("MockServer receive alterCollection() call");
+
+        responseObserver.onNext(respAlterCollection);
+        responseObserver.onCompleted();
+    }
+
     public void setShowCollectionsResponse(io.milvus.grpc.ShowCollectionsResponse resp) {
     public void setShowCollectionsResponse(io.milvus.grpc.ShowCollectionsResponse resp) {
         respShowCollections = resp;
         respShowCollections = resp;
     }
     }