All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.journalkeeper.core.server.Server Maven / Gradle / Ivy

There is a newer version: 0.1.11
Show newest version
/**
 * Licensed 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.journalkeeper.core.server;

import io.journalkeeper.base.Serializer;
import io.journalkeeper.core.api.JournalEntryParser;
import io.journalkeeper.core.api.RaftServer;
import io.journalkeeper.core.api.StateFactory;
import io.journalkeeper.monitor.MonitorCollector;
import io.journalkeeper.monitor.ServerMonitorInfo;
import io.journalkeeper.rpc.RpcAccessPointFactory;
import io.journalkeeper.rpc.client.*;
import io.journalkeeper.rpc.server.AsyncAppendEntriesRequest;
import io.journalkeeper.rpc.server.AsyncAppendEntriesResponse;
import io.journalkeeper.rpc.server.DisableLeaderWriteRequest;
import io.journalkeeper.rpc.server.DisableLeaderWriteResponse;
import io.journalkeeper.rpc.server.GetServerEntriesRequest;
import io.journalkeeper.rpc.server.GetServerEntriesResponse;
import io.journalkeeper.rpc.server.GetServerStateRequest;
import io.journalkeeper.rpc.server.GetServerStateResponse;
import io.journalkeeper.rpc.server.InstallSnapshotRequest;
import io.journalkeeper.rpc.server.InstallSnapshotResponse;
import io.journalkeeper.rpc.server.RequestVoteRequest;
import io.journalkeeper.rpc.server.RequestVoteResponse;
import io.journalkeeper.rpc.server.ServerRpc;
import io.journalkeeper.rpc.server.ServerRpcAccessPoint;
import io.journalkeeper.utils.event.EventWatcher;
import io.journalkeeper.utils.spi.ServiceSupport;
import io.journalkeeper.utils.state.StateServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.URI;
import java.util.Collection;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledExecutorService;

/**
 * @author LiYue
 * Date: 2019-09-03
 */
public class Server
        implements ServerRpc, RaftServer {
    private static final Logger logger = LoggerFactory.getLogger(Server.class);

    private AbstractServer server;
    private StateServer rpcServer = null;
    private ServerState serverState = ServerState.CREATED;
    private final RpcAccessPointFactory rpcAccessPointFactory;

    private final Serializer entrySerializer;
    private final Serializer entryResultSerializer;
    private final Serializer querySerializer;
    private final Serializer resultSerializer;
    private final ScheduledExecutorService scheduledExecutor;
    private final ExecutorService asyncExecutor;
    private final Properties properties;
    private final StateFactory stateFactory;
    private final JournalEntryParser journalEntryParser;
    private final ServerMonitorInfoProvider serverMonitorInfoProvider;
    private final Collection monitorCollectors;
    private ServerRpcAccessPoint serverRpcAccessPoint;



    public Server(Roll roll, StateFactory stateFactory, Serializer entrySerializer, Serializer entryResultSerializer,
                  Serializer querySerializer, Serializer resultSerializer, JournalEntryParser journalEntryParser,
                  ScheduledExecutorService scheduledExecutor, ExecutorService asyncExecutor, Properties properties) {

        rpcAccessPointFactory = ServiceSupport.load(RpcAccessPointFactory.class);
        this.entrySerializer = entrySerializer;
        this.entryResultSerializer = entryResultSerializer;
        this.querySerializer = querySerializer;
        this.resultSerializer = resultSerializer;
        this.scheduledExecutor = scheduledExecutor;
        this.asyncExecutor = asyncExecutor;
        this.stateFactory = stateFactory;
        this.properties = properties;
        this.serverRpcAccessPoint = rpcAccessPointFactory.createServerRpcAccessPoint(properties);
        this.journalEntryParser = journalEntryParser;
        this.server = createServer(roll);
        this.serverMonitorInfoProvider = new ServerMonitorInfoProvider(this);
        this.monitorCollectors = ServiceSupport.loadAll(MonitorCollector.class);
    }

    private AbstractServer createServer(Roll roll) {
        if (roll == Roll.VOTER) {
            return new Voter<>(stateFactory, entrySerializer, entryResultSerializer, querySerializer, resultSerializer,
                    journalEntryParser, scheduledExecutor, asyncExecutor, serverRpcAccessPoint, properties);
        }
        return new Observer<>(stateFactory, entrySerializer, entryResultSerializer, querySerializer, resultSerializer,
                journalEntryParser, scheduledExecutor, asyncExecutor, serverRpcAccessPoint, properties);
    }

    @Override
    public Roll roll() {
        return server.roll();
    }

    @Override
    public void init(URI uri, List voters, Set partitions, URI preferredLeader) throws IOException {
        server.init(uri, voters, partitions, preferredLeader);
    }

    @Override
    public boolean isInitialized() {
        return server.isInitialized();
    }

    @Override
    public void recover() throws IOException {
        server.recover();
    }

    @Override
    public URI serverUri() {
        return null == server ? null : server.serverUri();
    }

    @Override
    public CompletableFuture updateClusterState(UpdateClusterStateRequest request) {
        return server.updateClusterState(request);
    }

    @Override
    public CompletableFuture queryClusterState(QueryStateRequest request) {
        return server.queryClusterState(request);
    }

    @Override
    public CompletableFuture queryServerState(QueryStateRequest request) {
        return server.queryClusterState(request);
    }

    @Override
    public CompletableFuture lastApplied() {
        return server.lastApplied();
    }

    @Override
    public CompletableFuture querySnapshot(QueryStateRequest request) {
        return server.querySnapshot(request);
    }

    @Override
    public CompletableFuture getServers() {
        return server.getServers();
    }

    @Override
    public CompletableFuture getServerStatus() {
        return server.getServerStatus();
    }

    @Override
    public CompletableFuture addPullWatch() {
        return server.addPullWatch();
    }

    @Override
    public CompletableFuture removePullWatch(RemovePullWatchRequest request) {
        return server.removePullWatch(request);
    }

    @Override
    public CompletableFuture updateVoters(UpdateVotersRequest request) {
        return server.updateVoters(request);
    }

    @Override
    public CompletableFuture pullEvents(PullEventsRequest request) {
        return server.pullEvents(request);
    }

    @Override
    public CompletableFuture convertRoll(ConvertRollRequest request) {

        return CompletableFuture.supplyAsync(()-> {
            if(request.getRoll() != null && request.getRoll() != server.roll()) {
                try {
                    if(server.serverState() != ServerState.RUNNING) {
                        throw  new IllegalStateException("Server is not running, current state: " + server.serverState() + "!");
                    }
                    server.stop();
                    server = createServer(request.getRoll());
                    server.recover();
                    server.start();
                } catch (Throwable t) {
                    return new ConvertRollResponse(t);
                }
            }
            return new ConvertRollResponse();
        }, asyncExecutor);
    }

    @Override
    public CompletableFuture createTransaction(CreateTransactionRequest request) {
        return server.createTransaction(request);
    }

    @Override
    public CompletableFuture completeTransaction(CompleteTransactionRequest request) {
        return server.completeTransaction(request);
    }

    @Override
    public CompletableFuture getOpeningTransactions() {
        return server.getOpeningTransactions();
    }

    @Override
    public void watch(EventWatcher eventWatcher) {
        server.watch(eventWatcher);
    }

    @Override
    public void unWatch(EventWatcher eventWatcher) {
        server.unWatch(eventWatcher);
    }

    @Override
    public CompletableFuture asyncAppendEntries(AsyncAppendEntriesRequest request) {
        return server.asyncAppendEntries(request);
    }

    @Override
    public CompletableFuture requestVote(RequestVoteRequest request) {
        return server.requestVote(request);
    }

    @Override
    public CompletableFuture getServerEntries(GetServerEntriesRequest request) {
        return server.getServerEntries(request);
    }

    @Override
    public CompletableFuture getServerState(GetServerStateRequest request) {
        return server.getServerState(request);
    }

    @Override
    public CompletableFuture disableLeaderWrite(DisableLeaderWriteRequest request) {
        return server.disableLeaderWrite(request);
    }

    @Override
    public CompletableFuture installSnapshot(InstallSnapshotRequest request) {
        return server.installSnapshot(request);
    }

    private void addMonitorProviderToCollectors() {
        if(null != monitorCollectors) {
            for (MonitorCollector monitorCollector : monitorCollectors) {
                monitorCollector.addServer(serverMonitorInfoProvider);
            }
        }
    }
    private void removeMonitorProviderToCollectors() {
        if(null != monitorCollectors) {
            for (MonitorCollector monitorCollector : monitorCollectors) {
                monitorCollector.removeServer(serverMonitorInfoProvider);
            }
        }
    }

    @Override
    public void start() {
        addMonitorProviderToCollectors();
        if(this.serverState != ServerState.CREATED) {
            throw new IllegalStateException("Server can only start once!");
        }
        this.serverState = ServerState.STARTING;
        server.start();
        rpcServer = rpcAccessPointFactory.bindServerService(this);
        rpcServer.start();
        this.serverState = ServerState.RUNNING;

    }

    @Override
    public void stop() {
        this.serverState = ServerState.STOPPING;
        if(rpcServer != null) {
            rpcServer.stop();
        }
        server.stop();
        serverRpcAccessPoint.stop();
        this.serverState = ServerState.STOPPED;
        removeMonitorProviderToCollectors();
        logger.info("Server {} stopped.", serverUri());
    }

    @Override
    public ServerState serverState() {
        return server.serverState();
    }

    AbstractServer getServer() {
        return server;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy