Browse Source

Implement resource group interfaces (#695)

Signed-off-by: yhmo <yihua.mo@zilliz.com>
groot 1 year ago
parent
commit
ed8b668ead

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

@@ -44,6 +44,7 @@ import io.milvus.param.highlevel.dml.*;
 import io.milvus.param.highlevel.dml.response.*;
 import io.milvus.param.index.*;
 import io.milvus.param.partition.*;
+import io.milvus.param.resourcegroup.*;
 import io.milvus.param.role.*;
 import io.milvus.response.*;
 import lombok.NonNull;
@@ -567,6 +568,7 @@ public abstract class AbstractMilvusGrpcClient implements MilvusClient {
             LoadCollectionRequest.Builder builder = LoadCollectionRequest.newBuilder()
                     .setCollectionName(requestParam.getCollectionName())
                     .setReplicaNumber(requestParam.getReplicaNumber())
+                    .addAllResourceGroups(requestParam.getResourceGroups())
                     .setRefresh(requestParam.isRefresh());
             if (StringUtils.isNotEmpty(requestParam.getDatabaseName())) {
                 builder.setDbName(requestParam.getDatabaseName());
@@ -999,6 +1001,7 @@ public abstract class AbstractMilvusGrpcClient implements MilvusClient {
                     .setCollectionName(requestParam.getCollectionName())
                     .setReplicaNumber(requestParam.getReplicaNumber())
                     .addAllPartitionNames(requestParam.getPartitionNames())
+                    .addAllResourceGroups(requestParam.getResourceGroups())
                     .setRefresh(requestParam.isRefresh());
             if (StringUtils.isNotEmpty(requestParam.getDatabaseName())) {
                 builder.setDbName(requestParam.getDatabaseName());
@@ -2817,6 +2820,7 @@ public abstract class AbstractMilvusGrpcClient implements MilvusClient {
         }
     }
 
+    @Override
     public R<CheckHealthResponse> checkHealth() {
         if (!clientIsReady()) {
             return R.failed(new ClientNotConnectedException("Client rpc channel is not ready"));
@@ -2837,6 +2841,7 @@ public abstract class AbstractMilvusGrpcClient implements MilvusClient {
         }
     }
 
+    @Override
     public R<GetVersionResponse> getVersion() {
         if (!clientIsReady()) {
             return R.failed(new ClientNotConnectedException("Client rpc channel is not ready"));
@@ -2857,6 +2862,198 @@ public abstract class AbstractMilvusGrpcClient implements MilvusClient {
         }
     }
 
+    @Override
+    public R<RpcStatus> createResourceGroup(CreateResourceGroupParam requestParam) {
+        if (!clientIsReady()) {
+            return R.failed(new ClientNotConnectedException("Client rpc channel is not ready"));
+        }
+
+        logInfo(requestParam.toString());
+
+        try {
+            CreateResourceGroupRequest request = CreateResourceGroupRequest.newBuilder()
+                    .setResourceGroup(requestParam.getGroupName())
+                    .build();
+
+            Status response = blockingStub().createResourceGroup(request);
+            if (response.getErrorCode() != ErrorCode.Success) {
+                return failedStatus("CreateResourceGroup", response);
+            }
+            logDebug("CreateResourceGroup successfully! Resource group name:{}",
+                    requestParam.getGroupName());
+            return R.success(new RpcStatus(RpcStatus.SUCCESS_MSG));
+        } catch (StatusRuntimeException e) {
+            logError("CreateResourceGroup RPC failed! Resource group name:{}",
+                    requestParam.getGroupName(), e);
+            return R.failed(e);
+        } catch (Exception e) {
+            logError("CreateResourceGroup failed! Resource group name:{}",
+                    requestParam.getGroupName(), e);
+            return R.failed(e);
+        }
+    }
+
+    @Override
+    public R<RpcStatus> dropResourceGroup(DropResourceGroupParam requestParam) {
+        if (!clientIsReady()) {
+            return R.failed(new ClientNotConnectedException("Client rpc channel is not ready"));
+        }
+
+        logInfo(requestParam.toString());
+
+        try {
+            DropResourceGroupRequest request = DropResourceGroupRequest.newBuilder()
+                    .setResourceGroup(requestParam.getGroupName())
+                    .build();
+
+            Status response = blockingStub().dropResourceGroup(request);
+            if (response.getErrorCode() != ErrorCode.Success) {
+                return failedStatus("DropResourceGroup", response);
+            }
+            logDebug("DropResourceGroup successfully! Resource group name:{}",
+                    requestParam.getGroupName());
+            return R.success(new RpcStatus(RpcStatus.SUCCESS_MSG));
+        } catch (StatusRuntimeException e) {
+            logError("DropResourceGroup RPC failed! Resource group name:{}",
+                    requestParam.getGroupName(), e);
+            return R.failed(e);
+        } catch (Exception e) {
+            logError("DropResourceGroup failed! Resource group name:{}",
+                    requestParam.getGroupName(), e);
+            return R.failed(e);
+        }
+    }
+
+    @Override
+    public R<ListResourceGroupsResponse> listResourceGroups(ListResourceGroupsParam requestParam) {
+        if (!clientIsReady()) {
+            return R.failed(new ClientNotConnectedException("Client rpc channel is not ready"));
+        }
+
+        logInfo(requestParam.toString());
+
+        try {
+            ListResourceGroupsRequest request = ListResourceGroupsRequest.newBuilder()
+                    .build();
+
+            ListResourceGroupsResponse response = blockingStub().listResourceGroups(request);
+            if (response.getStatus().getErrorCode() != ErrorCode.Success) {
+                return failedStatus("ListResourceGroups", response.getStatus());
+            }
+            logDebug("ListResourceGroups successfully!");
+            return R.success(response);
+        } catch (StatusRuntimeException e) {
+            logError("ListResourceGroups RPC failed!", e);
+            return R.failed(e);
+        } catch (Exception e) {
+            logError("ListResourceGroups failed!", e);
+            return R.failed(e);
+        }
+    }
+
+    @Override
+    public R<DescribeResourceGroupResponse> describeResourceGroup(DescribeResourceGroupParam requestParam) {
+        if (!clientIsReady()) {
+            return R.failed(new ClientNotConnectedException("Client rpc channel is not ready"));
+        }
+
+        logInfo(requestParam.toString());
+
+        try {
+            DescribeResourceGroupRequest request = DescribeResourceGroupRequest.newBuilder()
+                    .setResourceGroup(requestParam.getGroupName())
+                    .build();
+
+            DescribeResourceGroupResponse response = blockingStub().describeResourceGroup(request);
+            if (response.getStatus().getErrorCode() != ErrorCode.Success) {
+                return failedStatus("DescribeResourceGroup", response.getStatus());
+            }
+            logDebug("DescribeResourceGroup successfully! Resource group name:{}",
+                    requestParam.getGroupName());
+            return R.success(response);
+        } catch (StatusRuntimeException e) {
+            logError("DescribeResourceGroup RPC failed! Resource group name:{}",
+                    requestParam.getGroupName(), e);
+            return R.failed(e);
+        } catch (Exception e) {
+            logError("DescribeResourceGroup failed! Resource group name:{}",
+                    requestParam.getGroupName(), e);
+            return R.failed(e);
+        }
+    }
+
+    @Override
+    public R<RpcStatus> transferNode(TransferNodeParam requestParam) {
+        if (!clientIsReady()) {
+            return R.failed(new ClientNotConnectedException("Client rpc channel is not ready"));
+        }
+
+        logInfo(requestParam.toString());
+
+        try {
+            TransferNodeRequest request = TransferNodeRequest.newBuilder()
+                    .setSourceResourceGroup(requestParam.getSourceGroupName())
+                    .setTargetResourceGroup(requestParam.getTargetGroupName())
+                    .setNumNode(requestParam.getNodeNumber())
+                    .build();
+
+            Status response = blockingStub().transferNode(request);
+            if (response.getErrorCode() != ErrorCode.Success) {
+                return failedStatus("TransferNode", response);
+            }
+            logDebug("TransferNode successfully! Source group:{}, target group:{}, nodes number:{}",
+                    requestParam.getSourceGroupName(), requestParam.getTargetGroupName(), requestParam.getNodeNumber());
+            return R.success(new RpcStatus(RpcStatus.SUCCESS_MSG));
+        } catch (StatusRuntimeException e) {
+            logError("TransferNode RPC failed! Source group:{}, target group:{}, nodes number:{}",
+                    requestParam.getSourceGroupName(), requestParam.getTargetGroupName(), requestParam.getNodeNumber(), e);
+            return R.failed(e);
+        } catch (Exception e) {
+            logError("TransferNode failed! Source group:{}, target group:{}, nodes number:{}",
+                    requestParam.getSourceGroupName(), requestParam.getTargetGroupName(), requestParam.getNodeNumber(), e);
+            return R.failed(e);
+        }
+    }
+
+    @Override
+    public R<RpcStatus> transferReplica(TransferReplicaParam requestParam) {
+        if (!clientIsReady()) {
+            return R.failed(new ClientNotConnectedException("Client rpc channel is not ready"));
+        }
+
+        logInfo(requestParam.toString());
+
+        try {
+            TransferReplicaRequest request = TransferReplicaRequest.newBuilder()
+                    .setSourceResourceGroup(requestParam.getSourceGroupName())
+                    .setTargetResourceGroup(requestParam.getTargetGroupName())
+                    .setCollectionName(requestParam.getCollectionName())
+                    .setDbName(requestParam.getDatabaseName())
+                    .setNumReplica(requestParam.getReplicaNumber())
+                    .build();
+
+            Status response = blockingStub().transferReplica(request);
+            if (response.getErrorCode() != ErrorCode.Success) {
+                return failedStatus("TransferReplica", response);
+            }
+            logDebug("TransferReplica successfully! Source group:{}, target group:{}, replica number:{}",
+                    requestParam.getSourceGroupName(), requestParam.getTargetGroupName(),
+                    requestParam.getReplicaNumber());
+            return R.success(new RpcStatus(RpcStatus.SUCCESS_MSG));
+        } catch (StatusRuntimeException e) {
+            logError("TransferReplica RPC failed! Source group:{}, target group:{}, replica number:{}",
+                    requestParam.getSourceGroupName(), requestParam.getTargetGroupName(),
+                    requestParam.getReplicaNumber(), e);
+            return R.failed(e);
+        } catch (Exception e) {
+            logError("TransferReplica failed! Source group:{}, target group:{}, replica number:{}",
+                    requestParam.getSourceGroupName(), requestParam.getTargetGroupName(),
+                    requestParam.getReplicaNumber(), e);
+            return R.failed(e);
+        }
+    }
+
+
     ///////////////////// High Level API//////////////////////
     @Override
     public R<RpcStatus> createCollection(CreateSimpleCollectionParam requestParam) {

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

@@ -38,6 +38,7 @@ import io.milvus.param.highlevel.dml.response.*;
 import io.milvus.param.index.*;
 import io.milvus.param.partition.*;
 import io.milvus.param.role.*;
+import io.milvus.param.resourcegroup.*;
 
 import java.util.concurrent.TimeUnit;
 
@@ -679,6 +680,53 @@ public interface MilvusClient {
      */
     R<GetLoadStateResponse> getLoadState(GetLoadStateParam requestParam);
 
+    /**
+     * Create a resource group.
+     *
+     * @param requestParam {@link CreateResourceGroupParam}
+     * @return {status:result code, data:RpcStatus{msg: result message}}
+     */
+    R<RpcStatus> createResourceGroup(CreateResourceGroupParam requestParam);
+
+    /**
+     * Drop a resource group.
+     *
+     * @param requestParam {@link DropResourceGroupParam}
+     * @return {status:result code, data:RpcStatus{msg: result message}}
+     */
+    R<RpcStatus> dropResourceGroup(DropResourceGroupParam requestParam);
+
+    /**
+     * List resource groups.
+     *
+     * @param requestParam {@link ListResourceGroupsParam}
+     * @return {status:result code, data:ListResourceGroupsResponse{status}}
+     */
+    R<ListResourceGroupsResponse> listResourceGroups(ListResourceGroupsParam requestParam);
+
+    /**
+     * Describe a resource group.
+     *
+     * @param requestParam {@link DescribeResourceGroupParam}
+     * @return {status:result code, data:DescribeResourceGroupResponse{status}}
+     */
+    R<DescribeResourceGroupResponse> describeResourceGroup(DescribeResourceGroupParam requestParam);
+
+    /**
+     * Transfer a query node from source resource group to target resource_group.
+     *
+     * @param requestParam {@link TransferNodeParam}
+     * @return {status:result code, data:RpcStatus{msg: result message}}
+     */
+    R<RpcStatus> transferNode(TransferNodeParam requestParam);
+
+    /**
+     * Transfer a replica from source resource group to target resource_group.
+     *
+     * @param requestParam {@link TransferReplicaParam}
+     * @return {status:result code, data:RpcStatus{msg: result message}}
+     */
+    R<RpcStatus> transferReplica(TransferReplicaParam requestParam);
 
 
     ///////////////////// High Level API//////////////////////

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

@@ -37,6 +37,7 @@ import io.milvus.param.highlevel.dml.*;
 import io.milvus.param.highlevel.dml.response.*;
 import io.milvus.param.index.*;
 import io.milvus.param.partition.*;
+import io.milvus.param.resourcegroup.*;
 import io.milvus.param.role.*;
 import lombok.NonNull;
 import org.apache.commons.collections4.CollectionUtils;
@@ -567,6 +568,36 @@ public class MilvusMultiServiceClient implements MilvusClient {
         return this.clusterFactory.getMaster().getClient().getLoadState(requestParam);
     }
 
+    @Override
+    public R<RpcStatus> createResourceGroup(CreateResourceGroupParam requestParam) {
+        return this.clusterFactory.getMaster().getClient().createResourceGroup(requestParam);
+    }
+
+    @Override
+    public R<RpcStatus> dropResourceGroup(DropResourceGroupParam requestParam) {
+        return this.clusterFactory.getMaster().getClient().dropResourceGroup(requestParam);
+    }
+
+    @Override
+    public R<ListResourceGroupsResponse> listResourceGroups(ListResourceGroupsParam requestParam) {
+        return this.clusterFactory.getMaster().getClient().listResourceGroups(requestParam);
+    }
+
+    @Override
+    public R<DescribeResourceGroupResponse> describeResourceGroup(DescribeResourceGroupParam requestParam) {
+        return this.clusterFactory.getMaster().getClient().describeResourceGroup(requestParam);
+    }
+
+    @Override
+    public R<RpcStatus> transferNode(TransferNodeParam requestParam) {
+        return this.clusterFactory.getMaster().getClient().transferNode(requestParam);
+    }
+
+    @Override
+    public R<RpcStatus> transferReplica(TransferReplicaParam requestParam) {
+        return this.clusterFactory.getMaster().getClient().transferReplica(requestParam);
+    }
+
     ///////////////////// High Level API//////////////////////
 
 

+ 29 - 0
src/main/java/io/milvus/client/MilvusServiceClient.java

@@ -50,6 +50,7 @@ import io.milvus.param.highlevel.dml.*;
 import io.milvus.param.highlevel.dml.response.*;
 import io.milvus.param.index.*;
 import io.milvus.param.partition.*;
+import io.milvus.param.resourcegroup.*;
 import io.milvus.param.role.*;
 import lombok.NonNull;
 import org.apache.commons.lang3.StringUtils;
@@ -624,7 +625,35 @@ public class MilvusServiceClient extends AbstractMilvusGrpcClient {
         return retry(()-> super.getLoadState(requestParam));
     }
 
+    @Override
+    public R<RpcStatus> createResourceGroup(CreateResourceGroupParam requestParam) {
+        return retry(()-> super.createResourceGroup(requestParam));
+    }
+
+    @Override
+    public R<RpcStatus> dropResourceGroup(DropResourceGroupParam requestParam) {
+        return retry(()-> super.dropResourceGroup(requestParam));
+    }
+
+    @Override
+    public R<ListResourceGroupsResponse> listResourceGroups(ListResourceGroupsParam requestParam) {
+        return retry(()-> super.listResourceGroups(requestParam));
+    }
 
+    @Override
+    public R<DescribeResourceGroupResponse> describeResourceGroup(DescribeResourceGroupParam requestParam) {
+        return retry(()-> super.describeResourceGroup(requestParam));
+    }
+
+    @Override
+    public R<RpcStatus> transferNode(TransferNodeParam requestParam) {
+        return retry(()-> super.transferNode(requestParam));
+    }
+
+    @Override
+    public R<RpcStatus> transferReplica(TransferReplicaParam requestParam) {
+        return retry(()-> super.transferReplica(requestParam));
+    }
 
     @Override
     public R<RpcStatus> createCollection(CreateSimpleCollectionParam requestParam) {

+ 26 - 1
src/main/java/io/milvus/param/collection/LoadCollectionParam.java

@@ -27,6 +27,8 @@ import lombok.Getter;
 import lombok.NonNull;
 import lombok.ToString;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -42,6 +44,7 @@ public class LoadCollectionParam {
     private final long syncLoadWaitingTimeout;
     private final int replicaNumber;
     private final boolean refresh;
+    private final List<String> resourceGroups;
 
     public LoadCollectionParam(@NonNull Builder builder) {
         this.databaseName = builder.databaseName;
@@ -51,6 +54,7 @@ public class LoadCollectionParam {
         this.syncLoadWaitingTimeout = builder.syncLoadWaitingTimeout;
         this.replicaNumber = builder.replicaNumber;
         this.refresh = builder.refresh;
+        this.resourceGroups = builder.resourceGroups;
     }
 
     public static Builder newBuilder() {
@@ -88,6 +92,11 @@ public class LoadCollectionParam {
         //   the server will look for new segments that are not loaded yet and tries to load them up.
         private Boolean refresh = Boolean.FALSE;
 
+        // resourceGroups:
+        //   Specify the target resource groups to load the replicas.
+        //   If not specified, the replicas will be loaded into the default resource group.
+        private List<String> resourceGroups = new ArrayList<>();
+
         private Builder() {
         }
 
@@ -154,7 +163,7 @@ public class LoadCollectionParam {
         }
 
         /**
-         * Specify replica number to load
+         * Specify replica number to load, replica number must be greater than 0, default value is 1
          *
          * @param replicaNumber replica number
          * @return <code>Builder</code>
@@ -179,6 +188,18 @@ public class LoadCollectionParam {
             return this;
         }
 
+        /**
+         * Specify the target resource groups to load the replicas.
+         * If not specified, the replicas will be loaded into the default resource group.
+         *
+         * @param resourceGroups a <code>List</code> of {@link String}
+         * @return <code>Builder</code>
+         */
+        public Builder withResourceGroups(@NonNull List<String> resourceGroups) {
+            this.resourceGroups.addAll(resourceGroups);
+            return this;
+        }
+
         /**
          * Verifies parameters and creates a new {@link LoadCollectionParam} instance.
          *
@@ -203,6 +224,10 @@ public class LoadCollectionParam {
                 }
             }
 
+            if (replicaNumber <= 0) {
+                throw new ParamException("Replica number must be greater than zero");
+            }
+
             return new LoadCollectionParam(this);
         }
     }

+ 19 - 1
src/main/java/io/milvus/param/partition/LoadPartitionsParam.java

@@ -23,7 +23,6 @@ import io.milvus.exception.ParamException;
 import io.milvus.param.Constant;
 import io.milvus.param.ParamUtils;
 
-import io.milvus.param.collection.LoadCollectionParam;
 import lombok.Getter;
 import lombok.NonNull;
 import java.util.ArrayList;
@@ -43,6 +42,7 @@ public class LoadPartitionsParam {
     private final long syncLoadWaitingTimeout;
     private final int replicaNumber;
     private final boolean refresh;
+    private final List<String> resourceGroups;
 
     private LoadPartitionsParam(@NonNull Builder builder) {
         this.databaseName = builder.databaseName;
@@ -53,6 +53,7 @@ public class LoadPartitionsParam {
         this.syncLoadWaitingTimeout = builder.syncLoadWaitingTimeout;
         this.replicaNumber = builder.replicaNumber;
         this.refresh = builder.refresh;
+        this.resourceGroups = builder.resourceGroups;
     }
 
     public static Builder newBuilder() {
@@ -91,6 +92,11 @@ public class LoadPartitionsParam {
         //   the server will look for new segments that are not loaded yet and tries to load them up.
         private Boolean refresh = Boolean.FALSE;
 
+        // resourceGroups:
+        //   Specify the target resource groups to load the replicas.
+        //   If not specified, the replicas will be loaded into the default resource group.
+        private List<String> resourceGroups = new ArrayList<>();
+
         private Builder() {
         }
 
@@ -206,6 +212,18 @@ public class LoadPartitionsParam {
             return this;
         }
 
+        /**
+         * Specify the target resource groups to load the replicas.
+         * If not specified, the replicas will be loaded into the default resource group.
+         *
+         * @param resourceGroups a <code>List</code> of {@link String}
+         * @return <code>Builder</code>
+         */
+        public Builder withResourceGroups(@NonNull List<String> resourceGroups) {
+            this.resourceGroups.addAll(resourceGroups);
+            return this;
+        }
+
         /**
          * Verifies parameters and creates a new {@link LoadPartitionsParam} instance.
          *

+ 83 - 0
src/main/java/io/milvus/param/resourcegroup/CreateResourceGroupParam.java

@@ -0,0 +1,83 @@
+/*
+ * 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.resourcegroup;
+
+import io.milvus.exception.ParamException;
+import io.milvus.param.ParamUtils;
+import lombok.Getter;
+import lombok.NonNull;
+
+@Getter
+public class CreateResourceGroupParam {
+    private final String groupName;
+
+    private CreateResourceGroupParam(@NonNull Builder builder) {
+        this.groupName = builder.groupName;
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link CreateResourceGroupParam} class.
+     */
+    public static final class Builder {
+        private String groupName;
+
+        private Builder() {
+        }
+
+        /**
+         * Sets the group name. group name cannot be empty or null.
+         *
+         * @param groupName group name
+         * @return <code>Builder</code>
+         */
+        public Builder withGroupName(@NonNull String groupName) {
+            this.groupName = groupName;
+            return this;
+        }
+
+        /**
+         * Verifies parameters and creates a new {@link CreateResourceGroupParam} instance.
+         *
+         * @return {@link CreateResourceGroupParam}
+         */
+        public CreateResourceGroupParam build() throws ParamException {
+            ParamUtils.CheckNullEmptyString(groupName, "Group name");
+
+            return new CreateResourceGroupParam(this);
+        }
+    }
+
+    /**
+     * Constructs a <code>String</code> by {@link CreateResourceGroupParam} instance.
+     *
+     * @return <code>String</code>
+     */
+    @Override
+    public String toString() {
+        return "CreateResourceGroupParam{" +
+                "groupName='" + groupName +
+                '}';
+    }
+}

+ 83 - 0
src/main/java/io/milvus/param/resourcegroup/DescribeResourceGroupParam.java

@@ -0,0 +1,83 @@
+/*
+ * 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.resourcegroup;
+
+import io.milvus.exception.ParamException;
+import io.milvus.param.ParamUtils;
+import lombok.Getter;
+import lombok.NonNull;
+
+@Getter
+public class DescribeResourceGroupParam {
+    private final String groupName;
+
+    private DescribeResourceGroupParam(@NonNull Builder builder) {
+        this.groupName = builder.groupName;
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link DescribeResourceGroupParam} class.
+     */
+    public static final class Builder {
+        private String groupName;
+
+        private Builder() {
+        }
+
+        /**
+         * Sets the group name. group name cannot be empty or null.
+         *
+         * @param groupName group name
+         * @return <code>Builder</code>
+         */
+        public Builder withGroupName(@NonNull String groupName) {
+            this.groupName = groupName;
+            return this;
+        }
+
+        /**
+         * Verifies parameters and creates a new {@link DescribeResourceGroupParam} instance.
+         *
+         * @return {@link DescribeResourceGroupParam}
+         */
+        public DescribeResourceGroupParam build() throws ParamException {
+            ParamUtils.CheckNullEmptyString(groupName, "Group name");
+
+            return new DescribeResourceGroupParam(this);
+        }
+    }
+
+    /**
+     * Constructs a <code>String</code> by {@link DescribeResourceGroupParam} instance.
+     *
+     * @return <code>String</code>
+     */
+    @Override
+    public String toString() {
+        return "DescribeResourceGroupParam{" +
+                "groupName='" + groupName +
+                '}';
+    }
+}

+ 83 - 0
src/main/java/io/milvus/param/resourcegroup/DropResourceGroupParam.java

@@ -0,0 +1,83 @@
+/*
+ * 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.resourcegroup;
+
+import io.milvus.exception.ParamException;
+import io.milvus.param.ParamUtils;
+import lombok.Getter;
+import lombok.NonNull;
+
+@Getter
+public class DropResourceGroupParam {
+    private final String groupName;
+
+    private DropResourceGroupParam(@NonNull Builder builder) {
+        this.groupName = builder.groupName;
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link DropResourceGroupParam} class.
+     */
+    public static final class Builder {
+        private String groupName;
+
+        private Builder() {
+        }
+
+        /**
+         * Sets the group name. group name cannot be empty or null.
+         *
+         * @param groupName group name
+         * @return <code>Builder</code>
+         */
+        public Builder withGroupName(@NonNull String groupName) {
+            this.groupName = groupName;
+            return this;
+        }
+
+        /**
+         * Verifies parameters and creates a new {@link DropResourceGroupParam} instance.
+         *
+         * @return {@link DropResourceGroupParam}
+         */
+        public DropResourceGroupParam build() throws ParamException {
+            ParamUtils.CheckNullEmptyString(groupName, "Group name");
+
+            return new DropResourceGroupParam(this);
+        }
+    }
+
+    /**
+     * Constructs a <code>String</code> by {@link DropResourceGroupParam} instance.
+     *
+     * @return <code>String</code>
+     */
+    @Override
+    public String toString() {
+        return "DropResourceGroupParam{" +
+                "groupName='" + groupName +
+                '}';
+    }
+}

+ 53 - 0
src/main/java/io/milvus/param/resourcegroup/ListResourceGroupsParam.java

@@ -0,0 +1,53 @@
+/*
+ * 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.resourcegroup;
+
+import io.milvus.exception.ParamException;
+import lombok.Getter;
+import lombok.NonNull;
+
+@Getter
+public class ListResourceGroupsParam {
+    private ListResourceGroupsParam(@NonNull Builder builder) {
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link ListResourceGroupsParam} class.
+     */
+    public static final class Builder {
+
+        private Builder() {
+        }
+
+        /**
+         * Verifies parameters and creates a new {@link ListResourceGroupsParam} instance.
+         *
+         * @return {@link ListResourceGroupsParam}
+         */
+        public ListResourceGroupsParam build() throws ParamException {
+            return new ListResourceGroupsParam(this);
+        }
+    }
+}

+ 114 - 0
src/main/java/io/milvus/param/resourcegroup/TransferNodeParam.java

@@ -0,0 +1,114 @@
+/*
+ * 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.resourcegroup;
+
+import io.milvus.exception.ParamException;
+import io.milvus.param.ParamUtils;
+import lombok.Getter;
+import lombok.NonNull;
+
+@Getter
+public class TransferNodeParam {
+    private final String sourceGroupName;
+    private final String targetGroupName;
+    private final int nodeNumber;
+
+    private TransferNodeParam(@NonNull Builder builder) {
+        this.sourceGroupName = builder.sourceGroupName;
+        this.targetGroupName = builder.targetGroupName;
+        this.nodeNumber = builder.nodeNumber;
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link TransferNodeParam} class.
+     */
+    public static final class Builder {
+        private String sourceGroupName;
+        private String targetGroupName;
+        private Integer nodeNumber;
+
+        private Builder() {
+        }
+
+        /**
+         * Sets the source group name. group name cannot be empty or null.
+         *
+         * @param groupName source group name
+         * @return <code>Builder</code>
+         */
+        public Builder withSourceGroupName(@NonNull String groupName) {
+            this.sourceGroupName = groupName;
+            return this;
+        }
+
+        /**
+         * Sets the target group name. group name cannot be empty or null.
+         *
+         * @param groupName target group name
+         * @return <code>Builder</code>
+         */
+        public Builder withTargetGroupName(@NonNull String groupName) {
+            this.targetGroupName = groupName;
+            return this;
+        }
+
+        /**
+         * Specify query nodes to transfer to another resource group
+         *
+         * @param nodeNumber number of query nodes
+         * @return <code>Builder</code>
+         */
+        public Builder withNodeNumber(@NonNull Integer nodeNumber) {
+            this.nodeNumber = nodeNumber;
+            return this;
+        }
+
+        /**
+         * Verifies parameters and creates a new {@link TransferNodeParam} instance.
+         *
+         * @return {@link TransferNodeParam}
+         */
+        public TransferNodeParam build() throws ParamException {
+            ParamUtils.CheckNullEmptyString(sourceGroupName, "Source group name");
+            ParamUtils.CheckNullEmptyString(targetGroupName, "Target group name");
+
+            return new TransferNodeParam(this);
+        }
+    }
+
+    /**
+     * Constructs a <code>String</code> by {@link TransferNodeParam} instance.
+     *
+     * @return <code>String</code>
+     */
+    @Override
+    public String toString() {
+        return "TransferNodeParam{" +
+                "sourceGroupName='" + sourceGroupName + '\'' +
+                "targetGroupName='" + targetGroupName + '\'' +
+                "nodeNumber='" + nodeNumber +
+                '}';
+    }
+}

+ 149 - 0
src/main/java/io/milvus/param/resourcegroup/TransferReplicaParam.java

@@ -0,0 +1,149 @@
+/*
+ * 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.resourcegroup;
+
+import io.milvus.exception.ParamException;
+import io.milvus.param.ParamUtils;
+import lombok.Getter;
+import lombok.NonNull;
+
+@Getter
+public class TransferReplicaParam {
+    private final String sourceGroupName;
+    private final String targetGroupName;
+    private final String collectionName;
+    private final String databaseName;
+    private final long replicaNumber;
+
+    private TransferReplicaParam(@NonNull Builder builder) {
+        this.sourceGroupName = builder.sourceGroupName;
+        this.targetGroupName = builder.targetGroupName;
+        this.collectionName = builder.collectionName;
+        this.databaseName = builder.databaseName;
+        this.replicaNumber = builder.replicaNumber;
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link TransferReplicaParam} class.
+     */
+    public static final class Builder {
+        private String sourceGroupName;
+        private String targetGroupName;
+        private String collectionName;
+        private String databaseName;
+        private Long replicaNumber = 0L;
+
+        private Builder() {
+        }
+
+        /**
+         * Sets the source group name. group name cannot be empty or null.
+         *
+         * @param groupName source group name
+         * @return <code>Builder</code>
+         */
+        public Builder withSourceGroupName(@NonNull String groupName) {
+            this.sourceGroupName = groupName;
+            return this;
+        }
+
+        /**
+         * Sets the target group name. group name cannot be empty or null.
+         *
+         * @param groupName target group name
+         * @return <code>Builder</code>
+         */
+        public Builder withTargetGroupName(@NonNull String groupName) {
+            this.targetGroupName = groupName;
+            return this;
+        }
+
+        /**
+         * Sets 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;
+        }
+
+        /**
+         * Sets the database name. database name can be nil.
+         *
+         * @param databaseName database name
+         * @return <code>Builder</code>
+         */
+        public Builder withDatabaseName(String databaseName) {
+            this.databaseName = databaseName;
+            return this;
+        }
+
+        /**
+         * Specify number of replicas to transfer
+         *
+         * @param replicaNumber number of replicas to transfer
+         * @return <code>Builder</code>
+         */
+        public Builder withReplicaNumber(@NonNull Long replicaNumber) {
+            this.replicaNumber = replicaNumber;
+            return this;
+        }
+
+        /**
+         * Verifies parameters and creates a new {@link TransferReplicaParam} instance.
+         *
+         * @return {@link TransferReplicaParam}
+         */
+        public TransferReplicaParam build() throws ParamException {
+            ParamUtils.CheckNullEmptyString(sourceGroupName, "Source group name");
+            ParamUtils.CheckNullEmptyString(targetGroupName, "Target group name");
+            ParamUtils.CheckNullEmptyString(collectionName, "Collection name");
+
+            if (replicaNumber <= 0) {
+                throw new ParamException("Replica number must be specified and greater than zero");
+            }
+
+            return new TransferReplicaParam(this);
+        }
+    }
+
+    /**
+     * Constructs a <code>String</code> by {@link TransferReplicaParam} instance.
+     *
+     * @return <code>String</code>
+     */
+    @Override
+    public String toString() {
+        return "TransferReplicaParam{" +
+                "sourceGroupName='" + sourceGroupName + '\'' +
+                "targetGroupName='" + targetGroupName + '\'' +
+                "collectionName='" + collectionName + '\'' +
+                "databaseName='" + databaseName + '\'' +
+                "replicaNumber='" + replicaNumber +
+                '}';
+    }
+}