package org.opencloudb;
import io.netty.bootstrap.Bootstrap;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.Timer;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.log4j.Logger;
import org.opencloudb.backend.BackendConnection;
import org.opencloudb.buffer.BufferPool;
import org.opencloudb.cache.CacheService;
import org.opencloudb.config.model.SystemConfig;
import org.opencloudb.interceptor.SQLInterceptor;
import org.opencloudb.net.FrontSession;
import org.opencloudb.route.MyCATSequnceProcessor;
import org.opencloudb.route.RouteService;
import org.opencloudb.util.ExecutorUtil;
import org.opencloudb.util.NameableExecutor;
import org.opencloudb.util.TimeUtil;
public class MycatSystem {
public static final String NAME = "MyCat";
private static final long LOG_WATCH_DELAY = 60000L;
private static final long TIME_UPDATE_PERIOD = 20L;
private static final MycatSystem INSTANCE = new MycatSystem();
private static final Logger LOGGER = Logger.getLogger("MycatServer");
private final RouteService routerService;
private final CacheService cacheService;
private Properties dnIndexProperties;
private volatile int nextProcessor;
private final AtomicBoolean isOnline = new AtomicBoolean(true);
private BufferPool bufferPool;
private boolean aio = false;
private final MycatPrivileges privileges;
private final ConcurrentMap<Long, FrontSession> frontSessions = new ConcurrentHashMap<Long, FrontSession>();
private final ConcurrentMap<Long, BackendConnection> backends = new ConcurrentHashMap<Long, BackendConnection>();;
private final MyCATSequnceProcessor sequnceProcessor = new MyCATSequnceProcessor();
public MyCATSequnceProcessor getSequnceProcessor() {
return sequnceProcessor;
}
public static final MycatSystem getInstance() {
return INSTANCE;
}
private final MycatConfig config;
private final Timer timer;
private final long startupTime;
private final Bootstrap soketConnetor = new Bootstrap();
private NameableExecutor businessExecutor = ExecutorUtil.create(
"BusinessExecutor", 10);
private final SQLInterceptor sqlInterceptor;
public MycatSystem() {
this.config = new MycatConfig();
this.timer = new Timer(NAME + "Timer", true);
cacheService = new CacheService();
routerService = new RouteService(cacheService);
this.startupTime = TimeUtil.currentTimeMillis();
privileges = new MycatPrivileges();
try {
sqlInterceptor = (SQLInterceptor) Class.forName(
config.getSystem().getSqlInterceptor()).newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
dnIndexProperties = loadDnIndexProps();
}
private Properties loadDnIndexProps() {
Properties prop = new Properties();
File file = new File(SystemConfig.getHomePath(), "conf"
+ File.separator + "dnindex.properties");
if (!file.exists()) {
return prop;
}
FileInputStream filein = null;
try {
filein = new FileInputStream(file);
prop.load(filein);
} catch (Exception e) {
LOGGER.warn("load DataNodeIndex err:" + e);
} finally {
if (filein != null) {
try {
filein.close();
} catch (IOException e) {
}
}
}
return prop;
}
public CacheService getCacheService() {
return cacheService;
}
public SQLInterceptor getSqlInterceptor() {
return sqlInterceptor;
}
public RouteService getRouterService() {
return routerService;
}
public boolean isOnline() {
return isOnline.get();
}
public void offline() {
isOnline.set(false);
}
/**
* save cur datanode index to properties file
*
* @param dataNode
* @param curIndex
*/
public synchronized void saveDataHostIndex(String dataHost, int curIndex) {
File file = new File(SystemConfig.getHomePath(), "conf"
+ File.separator + "dnindex.properties");
FileOutputStream fileOut = null;
try {
String oldIndex = dnIndexProperties.getProperty(dataHost);
String newIndex = String.valueOf(curIndex);
if (newIndex.equals(oldIndex)) {
return;
}
dnIndexProperties.setProperty(dataHost, newIndex);
LOGGER.info("save DataHost index " + dataHost + " cur index "
+ curIndex);
File parent = file.getParentFile();
if (parent != null && !parent.exists()) {
parent.mkdirs();
}
fileOut = new FileOutputStream(file);
dnIndexProperties.store(fileOut, "update");
} catch (Exception e) {
LOGGER.warn("saveDataNodeIndex err:", e);
} finally {
if (fileOut != null) {
try {
fileOut.close();
} catch (IOException e) {
}
}
}
}
public ConcurrentMap<Long, BackendConnection> getBackends() {
return backends;
}
public NameableExecutor getBusinessExecutor() {
return businessExecutor;
}
public MycatConfig getConfig() {
return config;
}
public Bootstrap getSoketConnetor() {
return soketConnetor;
}
public ConcurrentMap<Long, FrontSession> getFrontSessions() {
return frontSessions;
}
public MycatPrivileges getPrivileges() {
return privileges;
}
}