Search and download functionalities are using the official Maven repository.

com.codeloom.ketty.ConfigurableServer Maven / Gradle / Ivy

package com.codeloom.ketty;

import java.io.File;
import java.net.*;
import java.util.Enumeration;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
import com.codeloom.resource.ResourceFactory;
import com.codeloom.settings.CommandLine;
import com.codeloom.settings.PropertiesConstants;
import com.codeloom.settings.Settings;
import com.codeloom.util.BaseException;
import com.codeloom.util.Factory;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.resource.URLResourceFactory;
import org.eclipse.jetty.xml.XmlConfiguration;
import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ConfigurableServer implements KettyServer {
	protected static final Logger LOG = LoggerFactory.getLogger(ConfigurableServer.class);
	protected static final String LOGBACK_DEFAULT = "${ketty.home}/conf/logback.app.xml";

	protected Server jettyServer = null;
	protected void resetLogger(){
		ILoggerFactory factory = LoggerFactory.getILoggerFactory();
		LOG.info("Current logger factory is {}",factory);
		if (factory instanceof LoggerContext) {
			// 采用了logback实现
			String conf = PropertiesConstants.getString(Settings.get(),
					"logback.conf", LOGBACK_DEFAULT);
			try {
				LOG.info("Reset logback with file:{}",conf);
				LoggerContext lc = (LoggerContext) factory;
				JoranConfigurator configurator = new JoranConfigurator();
				configurator.setContext(lc);
				lc.reset();
				configurator.doConfigure(conf);
			} catch (JoranException e) {
				LOG.error("Failed to reset logback.",e);
			}
		}
	}

	@Override
	public void start(String[] args) throws Exception {
		Settings settings = Settings.get();

		// 确定ketty.home环境变量
		String kettyHome = PropertiesConstants.getString(settings,"home","${ketty.home}");
		if (StringUtils.isEmpty(kettyHome)){
			kettyHome = System.getenv("KETTY_HOME");
			if (StringUtils.isEmpty(kettyHome)){
				throw new BaseException("Can not find ketty home.Check parameter:ketty.home or home");
			}
		}
		PropertiesConstants.setString(settings,"ketty.home",kettyHome);

		// 从CommandLine拷贝环境变量
		settings.copyFrom(new CommandLine(args));

		// 通过一些列的配置文件来初始化
		String configFile = PropertiesConstants.getString(settings,"ketty.config",
				"file:///${ketty.home}/conf/ketty.xml");
		if (StringUtils.isNotEmpty(configFile)){
			settings.addSettings(configFile);
		}

		String contextPath = PropertiesConstants.getString(settings,"context", "${server.context}");
		if (StringUtils.isEmpty(contextPath)){
			contextPath = kettyHome + File.separatorChar + "webapps" + File.separatorChar + "ROOT";
		}
		
		String port = PropertiesConstants.getString(settings,"port", "9000");
		if (!isPortAvailable(port)){
			throw new BaseException("Port is not available:" + port);
		}

		String app = PropertiesConstants.getString(settings,"app", "${server.app}");
		if (StringUtils.isEmpty(app)){
			throw new BaseException("Can not find app.Check parameter:app or server.app");
		}
		
		String contextRoot = PropertiesConstants.getString(settings,"contextRoot", "${server.contextRoot}");
		if (StringUtils.isEmpty(contextRoot)){
			contextRoot = PropertiesConstants.getString(settings,"vroot." + app,"/");
		}

		long mem = PropertiesConstants.getLong(settings, "mem", 0);
		if (mem <= 0){
			mem = Runtime.getRuntime().maxMemory() / 1000 / 1000;
		}

		long cores = PropertiesConstants.getLong(settings, "vcores", 0);
		if (cores <= 0){
			cores = Runtime.getRuntime().availableProcessors();
		}

		//保证temp和logs目录存在
		String temp = PropertiesConstants.getString(settings,"ketty.temp.home","${ketty.home}/temp");
		String logs = PropertiesConstants.getString(settings,"ketty.logs.home", "${ketty.home}/logs");
		makeSureDirectoryExist(temp);
		makeSureDirectoryExist(logs);

		String jettyConfig = PropertiesConstants.getString(settings,"ketty.start", "file:///${ketty.home}/conf/start.xml");
		
		String niName = PropertiesConstants.getString(settings, "ketty.ip.nic", "eth0");

		try {
			String ip = getHostIp(niName);
			System.setProperty("server.ip", ip);
			System.setProperty("server.port", port);
			System.setProperty("server.mem", String.valueOf(mem));
			System.setProperty("server.app", app);
			System.setProperty("server.cores", String.valueOf(cores));
			System.setProperty("server.context",contextPath);
			System.setProperty("server.root", contextRoot);
			System.setProperty("ketty.home", kettyHome);

			String hostIp = System.getenv("KETTY_HOST");
			if (StringUtils.isNotEmpty(hostIp) && !hostIp.equals(ip)){
				//可能运行在容器中
				System.setProperty("host.ip",hostIp);
				System.setProperty("host.port",ip);
				System.setProperty("host.app",app);
			}else {
				System.setProperty("host.ip",ip);
				System.setProperty("host.port",port);
				System.setProperty("host.app",app);
			}

			ResourceFactory rf = Settings.getResourceFactory();
			URL url = rf.createURL(jettyConfig, null);
			if (url == null){
				throw new BaseException("Failed to load the start script:"+jettyConfig);
			}

			URLResourceFactory f = new URLResourceFactory();

			LOG.info("Use xml configuration to start server");
			LOG.info("URL = {}",jettyConfig);
			XmlConfiguration xmlConfig = new XmlConfiguration(f.newResource(url));
			jettyServer = (Server)xmlConfig.configure();
	        jettyServer.start();
		}catch(Exception ex){
			LOG.error("Failed to start jetty server",ex);
		}
	}

	private void makeSureDirectoryExist(String path) {
		if (StringUtils.isNotEmpty(path)){
			File file = new File(path);
			if (!file.exists()){
				LOG.info("Dir {} does not exist. Creating.",path);
				file.mkdirs();
			}
		}
	}
	public void join() throws Exception {
		if (jettyServer != null){
			resetLogger();
			jettyServer.join();
		}
	}	
	
	public void stop() throws Exception {
		if (jettyServer != null){
			jettyServer.stop();
		}
	}

	public static boolean isPortAvailable(String port){
		try {
			int p = Integer.parseInt(port);
			ServerSocket socket = new ServerSocket(p);
			socket.close();
			return true;
		}catch (Exception ex){
			return false;
		}
	}

	public static int getAvailablePort(int fromPort,int toPort){
		ServerSocket socket = null;
		for (int port = fromPort ; port < toPort ; port ++){
			try {
				socket = new ServerSocket(port);
				socket.close();
				LOG.info("Port is available,port = {}",port);
				return port;
			}catch (Exception ex){
				LOG.info("Port is bound,try another.port = {}",port);
			}
		}
		return 0;
	}

	public static String getHostIp(String name){
		// get ip from env : KETTY_IP
		String ip = System.getenv("KETTY_IP");
		if (StringUtils.isNotEmpty(ip)){
			return ip;
		}
		try {
			InetAddress addr = InetAddress.getLocalHost();
			return addr.getHostAddress();
		}catch (Exception ex){
			LOG.error("Can not get ip from Local Host");
		}
		if (StringUtils.isNotEmpty(name)){
			ip = getIpByInterface(name);
			if (StringUtils.isNotEmpty(ip)){
				return ip;
			}
		}
		
		LOG.info("Try to get ip from network interface.");
		Enumeration interfaces = null;
		try {
			interfaces = NetworkInterface.getNetworkInterfaces();  
		}catch (Exception ex){
			return "127.0.0.1";
		}
        while (interfaces.hasMoreElements()) {  
            NetworkInterface ni = interfaces.nextElement();  
            Enumeration addrs = ni.getInetAddresses();
            while (addrs.hasMoreElements()){
            	InetAddress inetAddr = addrs.nextElement();
            	if (!inetAddr.isLoopbackAddress()){
            		return inetAddr.getHostAddress();
            	}
            }
        }
        return "127.0.0.1";
	}
	
	public static String getIpByInterface(String name){
		NetworkInterface ni;
		try {
			ni = NetworkInterface.getByName(name);
	        Enumeration addrs = ni.getInetAddresses();
	        while (addrs.hasMoreElements()){
	        	InetAddress inetAddr = addrs.nextElement();
				if (!inetAddr.isLoopbackAddress()
						&& !inetAddr.isAnyLocalAddress()
						&& !inetAddr.isLinkLocalAddress()
						&& !inetAddr.isMulticastAddress()) {
					return inetAddr.getHostAddress();
				}
	        }
		} catch (SocketException e) {
			LOG.error("Can not get ip by interface name.");
		}
        return null;
	}
	
	public static void main(String [] args){
		KettyServer server = new ConfigurableServer();
		try {
			server.start(args);
			server.join();
		}catch (Exception ex){
			LOG.error("Failed to start ketty server.",ex);
		}
	}	
}




© 2015 - 2026 Weber Informatics LLC | Privacy Policy