com.sm.store.server.ClusterStoreServer.java Source code

Java tutorial

Introduction

Here is the source code for com.sm.store.server.ClusterStoreServer.java

Source

/*
 *
 *
 * Copyright 2012-2015 Viant.
 *
 * 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 com.sm.store.server;

import com.sm.Service;
import com.sm.localstore.impl.HessianSerializer;
import com.sm.replica.client.ReplicaClient;
import com.sm.replica.server.ReplicaServer;
import com.sm.storage.Serializer;
import com.sm.store.Delta;
import com.sm.store.StoreConfig;
import com.sm.store.cluster.ClusterServerConfig;
import com.sm.transport.netty.TCPServer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import voldemort.annotations.jmx.JmxManaged;
import voldemort.annotations.jmx.JmxOperation;
import voldemort.store.cachestore.impl.CacheStore;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import static com.sm.store.cluster.Utils.*;
import static com.sm.store.utils.ClassBuilder.*;

@JmxManaged(description = "ClusterStoreServer")
public class ClusterStoreServer implements Service {
    protected static final Log logger = LogFactory.getLog(ClusterStoreServer.class);

    private TCPServer server;
    private ClusterServerHandler handler;
    protected ClusterStoreCallBack callBack;
    protected Serializer serializer;
    protected ReplicaServer replicaServer = null;
    protected ConcurrentMap<String, RemoteStore> storeMaps;
    protected Service.State state;
    protected ClusterServerConfig serverConfig;
    protected int clusterNo;

    public ClusterStoreServer(ClusterServerConfig serverConfig, Serializer serializer) {
        this.serverConfig = serverConfig;
        if (serializer == null)
            this.serializer = new HessianSerializer();
        else
            this.serializer = serializer;
        init();
    }

    //    public ClusterStoreServer(RemoteConfig remoteConfig){
    //        throw new IllegalAccessError("constructor for remoteConfig");
    //    }

    protected void init() {
        clusterNo = serverConfig.getClusterNo();
        logger.info("start Cluster Server " + serverConfig.findClusterNodes(clusterNo).toString() + " for "
                + serverConfig.getStoreConfigList().size() + " store");
        state = State.Starting;
        storeMaps = new ConcurrentHashMap<String, RemoteStore>();
        for (StoreConfig each : serverConfig.getStoreConfigList()) {
            logger.info("start store " + each.toString());
            ClusterStore store = new ClusterStore(each.getFileName(), buildSerializer(each.getSerializer()),
                    serverConfig.getDataPath() + "/" + each.getDataPath(), each.isDelay(), each.getBlockSize(),
                    each.getMode(), each.isSorted(), serverConfig.findClusterNodes(clusterNo));
            if (each.isDelay()) {
                logger.info("writeThread " + each.getDelayThread());
                store.startWriteThread(each.getDelayThread());
            }
            logger.info("start replica client in cluster path " + each.getLogPath());
            //pass localUrl to start replicate thread to all other nodes in the same cluster
            store.startReplica(each.getLogPath(), serverConfig.getHost() + ":" + serverConfig.getPort());
            //start replica url that was defined in each store
            if (each.getReplicaUrl() != null && each.getReplicaUrl().size() > 0) {
                logger.info("start replica client defined in stores.xml size " + each.getReplicaUrl().size());
                store.startWriteLogThread(each.getLogPath(), each.getReplicaUrl());
            }
            //add support replica client timeout
            List<ReplicaClient> clientList = store.getReplicaClientList();
            for (ReplicaClient client : clientList) {
                client.setTimeout(each.getReplicaTimeout());
            }
            //add support of persist client and persist replica URL
            if (each.getPstReplicaUrl() != null && each.getPstReplicaUrl().size() > 0) {
                //useLRU property to represent blockValue flag ; but only for luster store
                if (each.isUseLRU()) {
                    logger.info("useLRU is true, will send blockValue to true and bypass Delta");
                    store.setBlockValue(each.isUseLRU());
                } else {
                    logger.info("check for delta interface");
                    if (store.getDelta() == null) {
                        logger.info("inject UnisonDelta..");
                        //store.setDelta(new UnisonDelta(null));
                        store.setDelta((Delta) createInstance(UNISON_DELTA));
                    }
                }
                logger.info("start persist replica client for " + each.getStore());
                store.startPstReplica("log", each.getPstReplicaUrl());
                //add support replica client timeout
                List<ReplicaClient> clist = store.getReplicaClientList();
                for (ReplicaClient client : clist) {
                    client.setTimeout(each.getReplicaTimeout());
                }
            }
            //call remote store to start customerize replication outside of cluster
            //store.startReplica(each.getLogPath(), each.getReplicaUrl());
            storeMaps.put(each.getStore(), store);
            //setup trigger from storeConfig
            store.setupTrigger2Cache(each);
        }
        startAdminStore();
        callBack = new ClusterStoreCallBack(storeMaps, serializer, serverConfig.findClusterNodes(clusterNo));
        handler = new ClusterServerHandler(callBack, serverConfig.getMaxThread(), serverConfig.getMaxQueue(),
                serializer);
        // setup the server handler login freqency
        ((ClusterServerHandler) handler).setFreq(serverConfig.getFreq());
    }

    protected void startAdminStore() {
        logger.info("load admin store ...");
        AdminClusterStore adminStore = new AdminClusterStore(ADMIN_FILENAME, serializer, serverConfig.getDataPath(),
                false, null, 0, serverConfig.findClusterNodes(clusterNo));
        // put clusterNodesList and storeConfigList into adminStore
        //setServerConfig will trigger setList()
        adminStore.setServerConfig(serverConfig);
        //adminStore.setList(serverConfig.getClusterNodesList(), serverConfig.getStoreConfigList());
        storeMaps.put(ADMIN_STORE, adminStore);
    }

    public ClusterStore getStore(String store) {
        return (ClusterStore) storeMaps.get(store);
    }

    public void hookShutdown() {
        Runtime.getRuntime().addShutdownHook(new Thread(new Shutdown()));
    }

    public List<String> getAllStoreNames() {
        Set<String> sets = storeMaps.keySet();
        ArrayList<String> list = new ArrayList<String>(sets);
        return list;
    }

    protected Map<String, CacheStore> buildMap(Map<String, RemoteStore> storeMap) {
        Map<String, CacheStore> cacheMap = new ConcurrentHashMap<String, CacheStore>();
        Iterator<String> it = storeMap.keySet().iterator();
        while (it.hasNext()) {
            String name = it.next();
            RemoteStore store = storeMap.get(name);
            cacheMap.put(name, store.getStore());
        }
        return cacheMap;
    }

    public void shutdown() {
        // turn on shutdown flag
        logger.warn("Server entered shutdown serverState, waiting for 2 seconds at "
                + new Date(System.currentTimeMillis()).toString());
        //serverState = State.Shutdown;
        try {
            Thread.sleep(1000L * 2);
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
        }

        logger.warn("Server enter shutdown serverState unbind acceptor ");
        if (server != null)
            server.getChannel().unbind();
        if (replicaServer != null) {
            logger.warn("shut down replica server " + replicaServer.toString());
            replicaServer.shutdown();
        }
        Iterator<Map.Entry<String, RemoteStore>> iterator = storeMaps.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, RemoteStore> it = iterator.next();
            logger.info("Close Store " + it.getKey().toString());
            it.getValue().close();
        }

    }

    @JmxOperation(description = "stopClusterServer")
    public void stopServer() {
        server.shutdown();
        server = null;
    }

    @JmxOperation(description = "stopReplicaServer")
    public void stopReplicaServer() {
        replicaServer.shutdown();
        replicaServer = null;
    }

    @JmxOperation(description = "startReplicaServer")
    public void startReplicaServer() {
        if (replicaServer != null) {
            logger.warn("replica server is up for port " + serverConfig.getReplicaPort());
        } else {
            logger.info("start replica server port " + serverConfig.getReplicaPort());
            replicaServer = new ReplicaServer(serverConfig.getReplicaPort(), buildMap(storeMaps));
        }
    }

    public void start() {
        startServer();
        state = State.Start;
    }

    @Override
    public void stop() {
        state = State.Shutdown;
        stopServer();
    }

    @Override
    public State getStatus() {
        return state;
    }

    @JmxOperation(description = "startClusterServer")
    public void startServer() {
        if (server != null) {
            logger.warn("server is up for port " + serverConfig.getPort());
        } else {
            logger.info("start cluster server port " + serverConfig.getPort());
            server = TCPServer.start(serverConfig.getPort(), handler);
            //callBack.setServer( server);
        }
    }

    public ConcurrentMap<String, RemoteStore> getStoreMaps() {
        return storeMaps;
    }

    public ReplicaServer getReplicaServer() {
        return replicaServer;
    }

    public TCPServer getServer() {
        return server;
    }

    public ClusterServerHandler getHandler() {
        return handler;
    }

    public ClusterStoreCallBack getCallBack() {
        return callBack;
    }

    public State getState() {
        return state;
    }

    public int getClusterNo() {
        return clusterNo;
    }

    public ClusterServerConfig getServerConfig() {
        return serverConfig;
    }

    class Shutdown implements Runnable {

        public Shutdown() {
        }

        public void run() {
            shutdown();
        }
    }

}