@Override
    protected Message processRequest0(final CliRequestContext ctx, final ResetLearnersRequest request,
                                      final RpcRequestClosure done) {
        final List<PeerId> oldLearners = ctx.node.listLearners();
        final List<PeerId> newLearners = new ArrayList<>(request.getLearnersCount());

        for (final String peerStr : request.getLearnersList()) {
            final PeerId peer = new PeerId();
            if (!peer.parse(peerStr)) {
                return RpcFactoryHelper
                    .responseFactory()
                    .newResponse(defaultResp(), RaftError.EINVAL, "Fail to parse peer id %s", peerStr);
            }
            newLearners.add(peer);
        }

        LOG.info("Receive ResetLearnersRequest to {} from {}, resetting into {}.", ctx.node.getNodeId(),
            done.getRpcCtx().getRemoteAddress(), newLearners);
        ctx.node.resetLearners(newLearners, status -> {
            if (!status.isOk()) {
                done.run(status);
            } else {
                final LearnersOpResponse.Builder rb = LearnersOpResponse.newBuilder();

                for (final PeerId peer : oldLearners) {
                    rb.addOldLearners(peer.toString());
                }

                for (final PeerId peer : newLearners) {
                    rb.addNewLearners(peer.toString());
                }

                done.sendResponse(rb.build());
            }
        });

        return null;
    }
ResetLearners request processor.

@author boyan (boyan@alibaba-inc.com)
jraft-core/src/main/java/com/alipay/sofa/jraft/rpc/impl/cli/ResetLearnersRequestProcessor.java