package com.github.wenweihu86.raft.admin; import com.baidu.brpc.client.BrpcProxy; import com.baidu.brpc.client.RpcClient; import com.baidu.brpc.client.RpcClientOptions; import com.baidu.brpc.client.instance.Endpoint; import com.github.wenweihu86.raft.proto.RaftProto; import com.github.wenweihu86.raft.service.RaftClientService; import com.googlecode.protobuf.format.JsonFormat; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.List; /** * 非线程安全 * Created by wenweihu86 on 2017/5/14. */ public class RaftClientServiceProxy implements RaftClientService { private static final Logger LOG = LoggerFactory.getLogger(RaftClientServiceProxy.class); private static final JsonFormat jsonFormat = new JsonFormat(); private List<RaftProto.Server> cluster; private RpcClient clusterRPCClient; private RaftClientService clusterRaftClientService; private RaftProto.Server leader; private RpcClient leaderRPCClient; private RaftClientService leaderRaftClientService; private RpcClientOptions rpcClientOptions = new RpcClientOptions(); // servers format is 10.1.1.1:8888,10.2.2.2:9999 public RaftClientServiceProxy(String ipPorts) { rpcClientOptions.setConnectTimeoutMillis(1000); // 1s rpcClientOptions.setReadTimeoutMillis(3600000); // 1hour rpcClientOptions.setWriteTimeoutMillis(1000); // 1s clusterRPCClient = new RpcClient(ipPorts, rpcClientOptions); clusterRaftClientService = BrpcProxy.getProxy(clusterRPCClient, RaftClientService.class); updateConfiguration(); } @Override public RaftProto.GetLeaderResponse getLeader(RaftProto.GetLeaderRequest request) { return clusterRaftClientService.getLeader(request); } @Override public RaftProto.GetConfigurationResponse getConfiguration(RaftProto.GetConfigurationRequest request) { return clusterRaftClientService.getConfiguration(request); } @Override public RaftProto.AddPeersResponse addPeers(RaftProto.AddPeersRequest request) { RaftProto.AddPeersResponse response = leaderRaftClientService.addPeers(request); if (response != null && response.getResCode() == RaftProto.ResCode.RES_CODE_NOT_LEADER) { updateConfiguration(); response = leaderRaftClientService.addPeers(request); } return response; } @Override public RaftProto.RemovePeersResponse removePeers(RaftProto.RemovePeersRequest request) { RaftProto.RemovePeersResponse response = leaderRaftClientService.removePeers(request); if (response != null && response.getResCode() == RaftProto.ResCode.RES_CODE_NOT_LEADER) { updateConfiguration(); response = leaderRaftClientService.removePeers(request); } return response; } public void stop() { if (leaderRPCClient != null) { leaderRPCClient.stop(); } if (clusterRPCClient != null) { clusterRPCClient.stop(); } } private boolean updateConfiguration() { RaftProto.GetConfigurationRequest request = RaftProto.GetConfigurationRequest.newBuilder().build(); RaftProto.GetConfigurationResponse response = clusterRaftClientService.getConfiguration(request); if (response != null && response.getResCode() == RaftProto.ResCode.RES_CODE_SUCCESS) { if (leaderRPCClient != null) { leaderRPCClient.stop(); } leader = response.getLeader(); leaderRPCClient = new RpcClient(convertEndPoint(leader.getEndpoint()), rpcClientOptions); leaderRaftClientService = BrpcProxy.getProxy(leaderRPCClient, RaftClientService.class); return true; } return false; } private Endpoint convertEndPoint(RaftProto.Endpoint endPoint) { return new Endpoint(endPoint.getHost(), endPoint.getPort()); } }