com.vip.saturn.job.console.service.impl.RegistryCenterServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.vip.saturn.job.console.service.impl.RegistryCenterServiceImpl.java

Source

/**
 * Copyright 2016 vip.com.
 * <p>
 * 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.
 * </p>
 */

package com.vip.saturn.job.console.service.impl;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import com.vip.saturn.job.console.utils.ExecutorNodePath;
import com.vip.saturn.job.integrate.service.ReportAlarmService;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.curator.framework.CuratorFramework;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Strings;
import com.vip.saturn.job.console.SaturnEnvProperties;
import com.vip.saturn.job.console.domain.RegistryCenterClient;
import com.vip.saturn.job.console.domain.RegistryCenterConfiguration;
import com.vip.saturn.job.console.domain.RequestResult;
import com.vip.saturn.job.console.domain.ZkCluster;
import com.vip.saturn.job.console.repository.zookeeper.CuratorRepository;
import com.vip.saturn.job.console.service.InitRegistryCenterService;
import com.vip.saturn.job.console.service.RegistryCenterService;
import com.vip.saturn.job.console.utils.LocalHostService;
import com.vip.saturn.job.sharding.NamespaceShardingManager;

@Service
public class RegistryCenterServiceImpl implements RegistryCenterService {

    protected static Logger log = LoggerFactory.getLogger(RegistryCenterServiceImpl.class);

    @Resource
    private CuratorRepository curatorRepository;

    @Resource
    private ReportAlarmService reportAlarmService;

    public static ConcurrentHashMap<String /** nns */
            , RegistryCenterClient> NNS_CURATOR_CLIENT_MAP = new ConcurrentHashMap<>();

    /** ??values? **/
    public static LinkedHashMap<String/** zkAddr **/
            , ZkCluster> ZKADDR_TO_ZKCLUSTER_MAP = new LinkedHashMap<>();

    private final AtomicBoolean refreshingRegCenter = new AtomicBoolean(false);

    private ConcurrentHashMap<String /** nns **/
            , NamespaceShardingManager> namespaceShardingListenerManagerMap = new ConcurrentHashMap<String, NamespaceShardingManager>();

    @PostConstruct
    public void init() throws Exception {
        refreshAll();
    }

    private String generateShardingLeadershipHostValue() {
        return LocalHostService.cachedIpAddress + "-" + UUID.randomUUID().toString();
    }

    private void refreshNamespaceShardingListenerManagerMap() {
        Collection<ZkCluster> zkClusters = RegistryCenterServiceImpl.ZKADDR_TO_ZKCLUSTER_MAP.values();
        for (ZkCluster zkCluster : zkClusters) {
            for (RegistryCenterConfiguration conf : zkCluster.getRegCenterConfList()) {
                String nns = conf.getNameAndNamespace();
                if (!namespaceShardingListenerManagerMap.containsKey(nns)) {
                    // client ?????
                    try {
                        CuratorFramework client = connect(conf.getNameAndNamespace()).getCuratorClient();
                        NamespaceShardingManager newObj = new NamespaceShardingManager(client, conf.getNamespace(),
                                generateShardingLeadershipHostValue(), reportAlarmService);
                        if (namespaceShardingListenerManagerMap.putIfAbsent(nns, newObj) == null) {
                            log.info("start NamespaceShardingManager {}", nns);
                            newObj.start();
                            log.info("done starting NamespaceShardingManager {}", nns);
                        }
                    } catch (Exception e) {
                        log.error(e.getMessage(), e);
                    }
                }
            }
        }
        // 
        Iterator<Entry<String, NamespaceShardingManager>> iterator = namespaceShardingListenerManagerMap.entrySet()
                .iterator();
        while (iterator.hasNext()) {
            Entry<String, NamespaceShardingManager> next = iterator.next();
            String nns = next.getKey();
            NamespaceShardingManager namespaceShardingManager = next.getValue();
            boolean find = false;
            for (ZkCluster zkCluster : zkClusters) {
                for (RegistryCenterConfiguration conf : zkCluster.getRegCenterConfList()) {
                    if (conf.getNameAndNamespace().equals(nns)) {
                        find = true;
                        break;
                    }
                }
                if (find) {
                    break;
                }
            }
            // zk?stop?
            /*if(!find) {
               namespaceShardingManager.stop();
               iterator.remove();
               // clear NNS_CURATOR_CLIENT_MAP
               RegistryCenterClient registryCenterClient = NNS_CURATOR_CLIENT_MAP.remove(nns);
               if (registryCenterClient != null) {
                  log.info("close zk client in NNS_CURATOR_CLIENT_MAP, nns: {}");
                  CloseableUtils.closeQuietly(registryCenterClient.getCuratorClient());
               }
            }*/
        }
    }

    private void refreshRegistryCenterFromJsonFile() throws IOException {
        ArrayList<RegistryCenterConfiguration> list = new ArrayList<>();
        String json = FileUtils.readFileToString(new File(SaturnEnvProperties.REG_CENTER_JSON_FILE),
                StandardCharsets.UTF_8);
        list = (ArrayList<RegistryCenterConfiguration>) JSON.parseArray(json, RegistryCenterConfiguration.class);
        LinkedHashMap<String/** zkAddr **/
                , ZkCluster> newClusterMap = new LinkedHashMap<>();
        for (RegistryCenterConfiguration conf : list) {
            try {
                conf.initNameAndNamespace(conf.getNameAndNamespace());
                if (conf.getZkAlias() == null) {
                    conf.setZkAlias(conf.getZkAddressList());
                }
                if (conf.getBootstrapKey() == null) {
                    conf.setBootstrapKey(conf.getZkAddressList());
                }
                ZkCluster cluster = newClusterMap.get(conf.getZkAddressList());
                if (cluster == null) {
                    CuratorFramework curatorFramework = curatorRepository.connect(conf.getZkAddressList(), "",
                            conf.getDigest());
                    cluster = new ZkCluster(conf.getZkAlias(), conf.getZkAddressList(), curatorFramework);
                    newClusterMap.put(conf.getZkAddressList(), cluster);
                } else if (cluster.getCuratorFramework() == null) {
                    if (cluster.getCuratorFramework() != null
                            && !cluster.getCuratorFramework().getZookeeperClient().isConnected()) {
                        cluster.getCuratorFramework().close();
                    }
                    CuratorFramework curatorFramework = curatorRepository.connect(conf.getZkAddressList(), "",
                            conf.getDigest());
                    cluster.setCuratorFramework(curatorFramework);
                }
                if (cluster.getCuratorFramework() == null) {
                    throw new IllegalArgumentException();
                }
                cluster.setOffline(false);
                conf.setVersion(getVersion(conf.getNamespace(), cluster.getCuratorFramework()));
                cluster.getRegCenterConfList().add(conf);
            } catch (Exception e) {
                log.error("found an offline zkCluster: {}", conf);
                log.error(e.getMessage(), e);
                ZkCluster cluster = new ZkCluster(conf.getZkAlias(), conf.getZkAddressList(), null);
                cluster.setOffline(true);
                newClusterMap.put(conf.getZkAddressList(), cluster);
            }
        }
        shutdownZkClientInZkClusterMap();
        ZKADDR_TO_ZKCLUSTER_MAP = newClusterMap;
    }

    private String getVersion(String namespace, CuratorFramework curatorFramework) {
        try {
            List<String> versionList = new ArrayList<>();
            String executorsPath = "/" + namespace + ExecutorNodePath.getExecutorNodePath();
            if (curatorFramework.checkExists().forPath(executorsPath) != null) {
                List<String> executors = curatorFramework.getChildren().forPath(executorsPath);
                if (executors != null && !executors.isEmpty()) {
                    for (String exe : executors) {
                        String versionPath = executorsPath + "/" + exe + "/version";
                        if (curatorFramework.checkExists().forPath(versionPath) != null) {
                            byte[] bs = curatorFramework.getData().forPath(versionPath);
                            if (bs != null) {
                                String version = new String(bs, "UTF-8");
                                if (version != null && !version.trim().isEmpty()) {
                                    String tmp = version.trim();
                                    if (!versionList.contains(tmp)) {
                                        versionList.add(tmp);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            Collections.sort(versionList);
            String versionStr = "";
            for (int i = 0; i < versionList.size(); i++) {
                String version = versionList.get(i);
                versionStr = versionStr + version;
                if (i < versionList.size() - 1) {
                    versionStr = versionStr + ", ";
                }
            }
            return versionStr;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return "";
        }
    }

    private static void shutdownZkClientInZkClusterMap() {
        Collection<ZkCluster> zkClusters = ZKADDR_TO_ZKCLUSTER_MAP.values();
        for (ZkCluster zkCluster : zkClusters) {
            if (zkCluster.getCuratorFramework() != null) {
                try {
                    log.info("shutdown zkclient in ZK_CLUSTER_MAP: {}", zkCluster);
                    zkCluster.getCuratorFramework().close();
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
            }
        }
    }

    private void refreshTreeData() {
        Collection<ZkCluster> zkClusters = RegistryCenterServiceImpl.ZKADDR_TO_ZKCLUSTER_MAP.values();
        for (ZkCluster zkCluster : zkClusters) {
            InitRegistryCenterService.initTreeJson(zkCluster.getRegCenterConfList(), zkCluster.getZkAddr());
        }
    }

    @Override
    public RegistryCenterClient connect(final String nameAndNameSpace) {
        RegistryCenterClient clientInCache = findInCache(nameAndNameSpace);
        if (null != clientInCache) {
            return clientInCache;
        }
        RegistryCenterConfiguration toBeConnectedConfig = findConfig(nameAndNameSpace);
        CuratorFramework client = curatorRepository.connect(toBeConnectedConfig.getZkAddressList(),
                toBeConnectedConfig.getNamespace(), toBeConnectedConfig.getDigest());

        RegistryCenterClient result = new RegistryCenterClient(nameAndNameSpace);

        if (null == client) {
            return result;
        }
        setRegistryCenterClient(result, client);
        return result;
    }

    @Override
    public RegistryCenterClient connectByNamespace(String namespace) {
        RegistryCenterClient result = new RegistryCenterClient();
        RegistryCenterConfiguration registryCenterConfiguration = findConfigByNamespace(namespace);
        if (registryCenterConfiguration == null) {
            return result;
        }
        RegistryCenterClient clientInCache = findInCache(registryCenterConfiguration.getNameAndNamespace());
        if (null != clientInCache) {
            return clientInCache;
        }
        CuratorFramework client = curatorRepository.connect(registryCenterConfiguration.getZkAddressList(),
                registryCenterConfiguration.getNamespace(), registryCenterConfiguration.getDigest());
        result.setNameAndNamespace(registryCenterConfiguration.getNameAndNamespace());
        if (null == client) {
            return result;
        }
        setRegistryCenterClient(result, client);
        return result;
    }

    private RegistryCenterClient findInCache(final String nameAndNameSpace) {
        if (NNS_CURATOR_CLIENT_MAP.containsKey(nameAndNameSpace)) {
            if (NNS_CURATOR_CLIENT_MAP.get(nameAndNameSpace).isConnected()) {
                return NNS_CURATOR_CLIENT_MAP.get(nameAndNameSpace);
            }
            NNS_CURATOR_CLIENT_MAP.remove(nameAndNameSpace);
        }
        return null;
    }

    private void setRegistryCenterClient(final RegistryCenterClient registryCenterClient,
            final CuratorFramework client) {
        registryCenterClient.setConnected(true);
        registryCenterClient.setCuratorClient(client);
        NNS_CURATOR_CLIENT_MAP.putIfAbsent(registryCenterClient.getNameAndNamespace(), registryCenterClient);
    }

    @Override
    public RegistryCenterConfiguration findConfig(String nameAndNamespace) {
        if (Strings.isNullOrEmpty(nameAndNamespace)) {
            return null;
        }
        Collection<ZkCluster> zkClusters = RegistryCenterServiceImpl.ZKADDR_TO_ZKCLUSTER_MAP.values();
        for (ZkCluster zkCluster : zkClusters) {
            for (RegistryCenterConfiguration each : zkCluster.getRegCenterConfList()) {
                if (each != null && nameAndNamespace.equals(each.getNameAndNamespace())) {
                    return each;
                }
            }
        }
        return null;
    }

    @Override
    public RegistryCenterConfiguration findConfigByNamespace(String namespace) {
        if (Strings.isNullOrEmpty(namespace)) {
            return null;
        }
        Collection<ZkCluster> zkClusters = RegistryCenterServiceImpl.ZKADDR_TO_ZKCLUSTER_MAP.values();
        for (ZkCluster zkCluster : zkClusters) {
            for (RegistryCenterConfiguration each : zkCluster.getRegCenterConfList()) {
                if (each != null && namespace.equals(each.getNamespace())) {
                    return each;
                }
            }
        }
        return null;
    }

    @Override
    public RequestResult refreshRegCenter() {
        RequestResult result = new RequestResult();
        if (refreshingRegCenter.compareAndSet(false, true)) {
            try {
                refreshAll();
                result.setSuccess(true);
            } catch (Throwable t) {
                log.error(t.getMessage(), t);
                result.setSuccess(false);
                result.setMessage(ExceptionUtils.getMessage(t));
            } finally {
                refreshingRegCenter.set(false);
            }
        } else {
            result.setSuccess(false);
            result.setMessage("refreshing, try it later!");
        }
        return result;
    }

    private void refreshAll() throws IOException {
        refreshRegistryCenterFromJsonFile();
        refreshNamespaceShardingListenerManagerMap();
        refreshTreeData();
    }

    public static RegistryCenterClient getCuratorByNameAndNamespace(String nameAndNamespace) {
        return NNS_CURATOR_CLIENT_MAP.get(nameAndNamespace);
    }

    /** 
     * @see com.vip.saturn.job.console.service.RegistryCenterService#findShardingManagerByNamespace(java.lang.String)
     */
    @Override
    public NamespaceShardingManager findShardingManagerByNamespace(String namespace) {
        return null;
    }

}