public CompletableFuture<Response> commit(final String group, final Message data,
            final CompletableFuture<Response> future) {
        LoggerUtils.printIfDebugEnabled(Loggers.RAFT, "data requested this time : {}", data);
        final RaftGroupTuple tuple = findTupleByGroup(group);
        if (tuple == null) {
            future.completeExceptionally(new IllegalArgumentException("No corresponding Raft Group found : " + group));
            return future;
        }
        
        FailoverClosureImpl closure = new FailoverClosureImpl(future);
        
        final Node node = tuple.node;
        if (node.isLeader()) {
            // The leader node directly applies this request
            applyOperation(node, data, closure);
        } else {
            // Forward to Leader for request processing
            invokeToLeader(group, data, rpcRequestTimeoutMs, closure);
        }
        return future;
    }
@Test
    void testCommit() throws NoSuchFieldException, IllegalAccessException, TimeoutException, InterruptedException {
        WriteRequest.Builder writeRequestBuilder = WriteRequest.newBuilder();
        WriteRequest writeRequest = writeRequestBuilder.build();
        
        // No group is set, and make sure that an IllegalArgumentException will be thrown.
        CompletableFuture<Response> future = server.commit(groupId, writeRequest, this.future);
        verify(future).completeExceptionally(any(IllegalArgumentException.class));
        
        // Set an group.
        Collection<RequestProcessor4CP> processors = Collections.singletonList(mockProcessor4CP);
        server.createMultiRaftGroup(processors);
        
        Field cliClientServiceField = JRaftServer.class.getDeclaredField("cliClientService");
        cliClientServiceField.setAccessible(true);
        cliClientServiceField.set(server, cliClientServiceMock);
        
        // Make the node leader and verify the invokeToLeader is never called.
        NodeImpl node = (NodeImpl) server.findNodeByGroup(groupId);
        Field stateField = NodeImpl.class.getDeclaredField("state");
        stateField.setAccessible(true);
        stateField.set(node, State.STATE_LEADER);
        
        server.commit(groupId, writeRequest, future);
        verify(cliClientServiceMock, never()).getRpcClient();
        
        // make the node follower and verify the invokeToLeader is called.
        node = (NodeImpl) server.findNodeByGroup(groupId);
        stateField.setAccessible(true);
        stateField.set(node, State.STATE_FOLLOWER);
        
        RouteTable.getInstance().updateLeader(groupId, peerId1);
        server.commit(groupId, writeRequest, future);
        verify(cliClientServiceMock).getRpcClient();
    }