view src/nabble/model/Init.java @ 6:c4ed473452d4

better https support
author Franklin Schmidt <fschmidt@gmail.com>
date Mon, 22 Jul 2019 05:37:46 -0400
parents abe0694e9849
children
line wrap: on
line source

package nabble.model;

import fschmidt.util.java.BasicRMIClientSocketFactory;
import fschmidt.util.java.BasicRMIServerSocketFactory;
import luan.LuanException;
import luan.Luan;
import luan.LuanTable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;


public final class Init {

	private static final Logger logger = LoggerFactory.getLogger(Init.class);

	private static final Map initMap;

	private static final Thread shutdownThread = new Thread(new Runnable(){public void run() {
		logger.info("begin shutdown");
		Batch.shutdown();
		logger.info("batch shutdown done");
		for( Runnable r : shutdownHooks ) {
			r.run();
		}
		logger.info("shutdownHooks done");
		if( modelHomeStarted ) {
			Executors.shutdown();
			logger.info("Executors shutdown done");
		}
		if( luceneStarted ) {
			Lucene.shutdown();
			logger.info("Lucene shutdown done");
		}
		if( dailyNumberStarted ) {
			DailyNumber.shutdown();
		}
		logger.info("end shutdown");
		cachingfilter.CachingFilter.shutdown();
		logger.info("CachingFilter shutdown done");
	}});


	static volatile boolean luceneStarted = false;
	static volatile boolean modelHomeStarted = false;
	static volatile boolean dailyNumberStarted = false;
	static {
		setCustomProperties();

//		ClassLoader cl = Init.class.getClassLoader();
//		interp.setClassLoader(cl);
//		Thread.currentThread().setContextClassLoader(cl);
		try {
			Luan luan = new Luan();
			LuanTable mod = (LuanTable)luan.eval("return require 'file:conf/Init.luan'");
			initMap = mod.asMap();
			Runtime.getRuntime().addShutdownHook(shutdownThread);
		} catch(LuanException e) {
			logger.error(e.getLuanStackTraceString());
			System.exit(-1);
			throw new RuntimeException();  // for compiler
		} catch(Throwable e) {
			logger.error("",e);
			System.exit(-1);
			throw new RuntimeException();  // for compiler
		}
	}

	private static List<Runnable> shutdownHooks = new ArrayList<Runnable>();

	public static void addShutdownHook(Runnable r) {
		shutdownHooks.add(r);
	}

	private static void setCustomProperties() {
		// InetAddress cache should last 30 seconds only.
		System.setProperty("networkaddress.cache.ttl", "30");
	}

	public static Object get(String var) {
		return initMap.get(var);
	}

	public static Integer getInteger(String var) {
		Number n = (Number)get(var);
		if( n==null )
			return null;
		int i = n.intValue();
		if( i != n.doubleValue() )
			throw new RuntimeException("init var '"+var+"' isn't an integer");
		return i;
	}

	public static Float getFloat(String var) {
		Number n = (Number)get(var);
		return n==null ? null : n.floatValue();
	}

	public static Set getSet(String var) {
		return (Set)get(var);
	}

	public static <T> T get(String var,T defaultVal) {
		if( defaultVal instanceof Integer ) {
			@SuppressWarnings("unchecked")
			T obj = (T)getInteger(var);
			return obj!=null ? obj : defaultVal;
		}
		if( defaultVal instanceof Float ) {
			@SuppressWarnings("unchecked")
			T obj = (T)getFloat(var);
			return obj!=null ? obj : defaultVal;
		}
		if( defaultVal instanceof Set ) {
			@SuppressWarnings("unchecked")
			T obj = (T)getSet(var);
			return obj!=null ? obj : defaultVal;
		}
		if( defaultVal != null ) {
			Class defaultCls = defaultVal.getClass();
			if( defaultCls.isArray() && !defaultCls.getComponentType().isPrimitive() ) {
				Object obj = get(var);
				if( obj instanceof LuanTable ) {
					LuanTable t = (LuanTable)obj;
					if( t.isList() ) {
						@SuppressWarnings("unchecked")
						T rtn = (T)t.asList().toArray((Object[])defaultVal);
						return rtn;
					}
				}
			}
		}
		@SuppressWarnings("unchecked")
		T obj = (T)get(var);
		return obj!=null ? obj : defaultVal;
	}

	public static String scheme(String domain) {
		String sslDir = (String)get("ssl_dir");
		return sslDir!=null && new File(sslDir+domain).exists() ? "https" : "http";
	}

	public static final boolean hasDaemons = nabble.utils.Jetty.isJetty;

	public static final String tempDir = (String)Init.get("home_dir")+"local/temp/"; // General purpose folder

	public static final int quotedLinesToHide = Init.get("quotedLinesToHide",10);


	private static final RMIClientSocketFactory rmiClientSocketFactory = new BasicRMIClientSocketFactory();
	private static RMIServerSocketFactory rmiServerSocketFactory;
	public static final String localRmiServer = (String)get("localRmiServer");
	private static Registry registry;

	static {
		if( localRmiServer!=null && Init.hasDaemons ) {
			try {
				String[] a = localRmiServer.split(":");
				String rmiHost = a[0];
				String rmiPort = a[1];
				System.setProperty("java.rmi.server.hostname", rmiHost);
				rmiServerSocketFactory = new InternalRMIServerSocketFactory(InetAddress.getByName(rmiHost));
				logger.info("Starting rmi server on port "+rmiPort);
				registry = LocateRegistry.createRegistry(Integer.parseInt(rmiPort), rmiClientSocketFactory, rmiServerSocketFactory);
				nabble.model.export.ImportServerImpl.bind();
			} catch (Exception e) {
				logger.error("",e);
				System.exit(-1);
			}
		}
	}

	public static void rmiBind(String name,Remote obj) {
		try {
			registry.bind(name,rmiExport(obj));
		} catch (Exception e) {
			logger.error("rmiBind failed, exiting",e);
			System.exit(-1);
		}
	}

	public static <T extends Remote> T rmiExport(T obj) throws RemoteException {
		@SuppressWarnings("unchecked")
		T t = (T)UnicastRemoteObject.exportObject( obj,0, rmiClientSocketFactory, rmiServerSocketFactory);
		return t;
	}

	private static class InternalRMIServerSocketFactory extends BasicRMIServerSocketFactory {
		private final InetAddress host;

		InternalRMIServerSocketFactory(InetAddress host) {
			this.host = host;
		}

		public ServerSocket createServerSocket(int port) throws IOException {
			return new ServerSocket(port, 0, host);
		}
	}

	public static void nop() {}

	private Init() {}  // never
}