Java tutorial
/* * (C) 2007-2012 Alibaba Group Holding Limited. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * Authors: * leiwen <chrisredfield1985@126.com> , boyan <killme2008@gmail.com> */ package com.starit.diamond.client.processor; import java.io.File; import java.io.IOException; import java.net.InetAddress; import java.net.NetworkInterface; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.starit.diamond.common.Constants; import com.starit.diamond.configinfo.CacheData; import com.starit.diamond.io.FileSystem; import com.starit.diamond.io.Path; import com.starit.diamond.io.watch.StandardWatchEventKind; import com.starit.diamond.io.watch.WatchEvent; import com.starit.diamond.io.watch.WatchKey; import com.starit.diamond.io.watch.WatchService; import com.starit.diamond.utils.FileUtils; import com.starit.diamond.utils.JSONUtils; public class LocalConfigInfoProcessor { private static final Log log = LogFactory.getLog(LocalConfigInfoProcessor.class); private ScheduledExecutorService singleExecutor = Executors.newSingleThreadScheduledExecutor();; private volatile Map<String/* address */, Map<String/* dataId */, String/* group */>> localMap = null; private final Map<String/* filePath */, Long/* version */> existFiles = new HashMap<String, Long>(); private volatile boolean isRun; private final String localAddress = getHostAddress(); private String rootPath = null; static String getHostAddress() { String address = "127.0.0.1"; try { Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); while (en.hasMoreElements()) { NetworkInterface ni = en.nextElement(); Enumeration<InetAddress> ads = ni.getInetAddresses(); while (ads.hasMoreElements()) { InetAddress ip = ads.nextElement(); if (!ip.isLoopbackAddress() && ip.isSiteLocalAddress()) { return ip.getHostAddress(); } } } } catch (Exception e) { throw new RuntimeException("??", e); } return address; } boolean containThisHostConfig() { if (null == localMap) { return false; } return localMap.containsKey(this.localAddress); } boolean isQualified(String dataId, String group) { Map<String, String> map2 = localMap.get(this.localAddress); if (null == map2) { throw new RuntimeException("???"); } String qualifiedGroup = map2.get(dataId); if (group.equals(qualifiedGroup)) { return true; } return false; } /** * ?? * * @param cacheData * @param force * ???null * @return * @throws IOException */ public String getLocalConfigureInfomation(CacheData cacheData, boolean force) throws IOException { if (null == localMap) { if (cacheData.isUseLocalConfigInfo()) { cacheData.setLastModifiedHeader(Constants.NULL); cacheData.setMd5(Constants.NULL); cacheData.setLocalConfigInfoFile(null); cacheData.setLocalConfigInfoVersion(0L); cacheData.setUseLocalConfigInfo(false); } return null; } String realGroup = getGroupByAddress(cacheData.getDataId(), cacheData.getGroup()); String filePath = getFilePath(cacheData.getDataId(), realGroup); if (!existFiles.containsKey(filePath)) { if (cacheData.isUseLocalConfigInfo()) { cacheData.setLastModifiedHeader(Constants.NULL); cacheData.setMd5(Constants.NULL); cacheData.setLocalConfigInfoFile(null); cacheData.setLocalConfigInfoVersion(0L); cacheData.setUseLocalConfigInfo(false); } return null; } if (force) { log.info("???, dataId:" + cacheData.getDataId() + ", group:" + cacheData.getGroup()); String content = FileUtils.getFileContent(filePath); return content; } // ???null if (!filePath.equals(cacheData.getLocalConfigInfoFile()) || existFiles.get(filePath) != cacheData.getLocalConfigInfoVersion()) { String content = FileUtils.getFileContent(filePath); cacheData.setLocalConfigInfoFile(filePath); cacheData.setLocalConfigInfoVersion(existFiles.get(filePath)); cacheData.setUseLocalConfigInfo(true); if (log.isInfoEnabled()) { log.info("????, dataId:" + cacheData.getDataId() + ", group:" + cacheData.getGroup()); } return content; } else { cacheData.setUseLocalConfigInfo(true); if (log.isInfoEnabled()) { log.debug("????, dataId:" + cacheData.getDataId() + ", group:" + cacheData.getGroup()); } return null; } } public boolean containsNewLocalConfigureInfomation(CacheData cacheData) { if (null == localMap) { return false; } String realGroup = getGroupByAddress(cacheData.getDataId(), cacheData.getGroup()); String filePath = getFilePath(cacheData.getDataId(), realGroup); if (!existFiles.containsKey(filePath)) { return false; } if (!filePath.equals(cacheData.getLocalConfigInfoFile()) || existFiles.get(filePath) != cacheData.getLocalConfigInfoVersion()) { return true; } return false; } String getGroupByAddress(String dataId, String clientGroup) { Map<String, String> mappingGroups = localMap.get(this.localAddress); if (mappingGroups != null) { String mappingGroup = mappingGroups.get(dataId); if (mappingGroup != null) { return mappingGroup; } else { return defaultGroupOrClientGroup(clientGroup); } } else { return defaultGroupOrClientGroup(clientGroup); } } String defaultGroupOrClientGroup(String clientGroup) { if (clientGroup != null) return clientGroup; else return Constants.DEFAULT_GROUP; } String getFilePath(String dataId, String group) { StringBuilder filePathBuilder = new StringBuilder(); filePathBuilder.append(rootPath).append("/").append(Constants.BASE_DIR).append("/").append(group) .append("/").append(dataId); File file = new File(filePathBuilder.toString()); return file.getAbsolutePath(); } public synchronized void start(String rootPath) { if (this.isRun) { return; } this.rootPath = rootPath; this.isRun = true; if (this.singleExecutor == null || singleExecutor.isTerminated()) { singleExecutor = Executors.newSingleThreadScheduledExecutor(); } initDataDir(rootPath); startCheckLocalDir(rootPath); } private void initDataDir(String rootPath) { try { File flie = new File(rootPath); flie.mkdir(); } catch (Exception e) { } } public synchronized void stop() { if (!this.isRun) { return; } this.isRun = false; this.singleExecutor.shutdownNow(); this.singleExecutor = null; } private void startCheckLocalDir(final String filePath) { final WatchService watcher = FileSystem.getDefault().newWatchService(); Path path = new Path(new File(filePath)); // watcher.register(path, true, StandardWatchEventKind.ENTRY_CREATE, StandardWatchEventKind.ENTRY_DELETE, StandardWatchEventKind.ENTRY_MODIFY); // ?check checkAtFirst(watcher); singleExecutor.execute(new Runnable() { public void run() { log.debug(">>>>>>?<<<<<<"); // ? while (isRun) { // ? WatchKey key; try { key = watcher.take(); } catch (InterruptedException x) { continue; } // reset,?? if (!processEvents(key)) { log.error("reset unvalid,?"); break; } } log.debug(">>>>>><<<<<<"); watcher.close(); } }); } private void checkAtFirst(final WatchService watcher) { watcher.check(); WatchKey key = null; while ((key = watcher.poll()) != null) { processEvents(key); } } /** * ?? * * @param key * @return */ @SuppressWarnings({ "unchecked" }) private boolean processEvents(WatchKey key) { /** * ?? */ for (WatchEvent<?> event : key.pollEvents()) { // // WatchEvent.Kind<?> kind = event.kind(); // context?path WatchEvent<Path> ev = (WatchEvent<Path>) event; Path eventPath = ev.context(); String realPath = eventPath.getAbsolutePath(); if (ev.kind() == StandardWatchEventKind.ENTRY_CREATE || ev.kind() == StandardWatchEventKind.ENTRY_MODIFY) { String grandpaDir = null; try { grandpaDir = FileUtils.getGrandpaDir(realPath); } catch (Exception e1) { } if (!Constants.BASE_DIR.equals(grandpaDir) && Constants.MAP_FILE.equals(eventPath.getName())) { try { localMap = (Map<String, Map<String, String>>) JSONUtils .deserializeObject(FileUtils.getFileContent(realPath), Map.class); } catch (Exception e) { log.error("JSON???" + realPath, e); localMap = null; continue; } if (log.isInfoEnabled()) { log.info(Constants.MAP_FILE + "?"); log.info("MapFile" + localMap.get(localAddress)); } } else { if (!Constants.BASE_DIR.equals(grandpaDir)) { log.error(": " + realPath); continue; } existFiles.put(realPath, System.currentTimeMillis()); if (log.isInfoEnabled()) { log.info(realPath + ""); } } } else if (ev.kind() == StandardWatchEventKind.ENTRY_DELETE) { String grandpaDir = null; try { grandpaDir = FileUtils.getGrandpaDir(realPath); } catch (Exception e1) { } if (!Constants.BASE_DIR.equals(grandpaDir) && Constants.MAP_FILE.equals(eventPath.getName())) { /** * Constants.MAP_FILElocalMap, */ localMap = null; if (log.isInfoEnabled()) { log.info(Constants.MAP_FILE + ""); } } else { if (Constants.BASE_DIR.equals(grandpaDir)) { // existFiles.remove(realPath); if (log.isInfoEnabled()) { log.info(realPath + ""); } } else { // Set<String> keySet = new HashSet<String>(existFiles.keySet()); for (String filePath : keySet) { if (filePath.startsWith(realPath)) { existFiles.remove(filePath); if (log.isInfoEnabled()) { log.info(filePath + ""); } } } } } } } return key.reset(); } }