All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.generallycloud.baseio.container.ApplicationContext Maven / Gradle / Ivy

/*
 * Copyright 2015-2017 GenerallyCloud.com
 *  
 * 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.
 */
package com.generallycloud.baseio.container;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import com.generallycloud.baseio.AbstractLifeCycle;
import com.generallycloud.baseio.LifeCycleUtil;
import com.generallycloud.baseio.common.FileUtil;
import com.generallycloud.baseio.common.Logger;
import com.generallycloud.baseio.common.LoggerFactory;
import com.generallycloud.baseio.common.LoggerUtil;
import com.generallycloud.baseio.common.StringUtil;
import com.generallycloud.baseio.component.ExceptionCaughtHandle;
import com.generallycloud.baseio.component.LoggerExceptionCaughtHandle;
import com.generallycloud.baseio.component.SocketChannelContext;
import com.generallycloud.baseio.component.SocketSessionEventListener;
import com.generallycloud.baseio.container.authority.AuthorityLoginCenter;
import com.generallycloud.baseio.container.authority.RoleManager;
import com.generallycloud.baseio.container.configuration.ApplicationConfiguration;
import com.generallycloud.baseio.container.configuration.ApplicationConfigurationLoader;
import com.generallycloud.baseio.container.configuration.FileSystemACLoader;
import com.generallycloud.baseio.container.implementation.SystemRedeployServlet;
import com.generallycloud.baseio.container.implementation.SystemStopServerServlet;
import com.generallycloud.baseio.container.service.FutureAcceptor;
import com.generallycloud.baseio.container.service.FutureAcceptorFilter;
import com.generallycloud.baseio.container.service.FutureAcceptorService;
import com.generallycloud.baseio.container.service.FutureAcceptorServiceFilter;
import com.generallycloud.baseio.container.service.FutureAcceptorServiceLoader;

public class ApplicationContext extends AbstractLifeCycle {

	private static ApplicationContext instance;

	public static ApplicationContext getInstance() {
		return instance;
	}

	private boolean						redeploying;
	private String							appLocalAddres;
	private String							rootLocalAddres;
	private URLDynamicClassLoader				classLoader	;
	private ApplicationConfiguration			configuration;
	private SocketChannelContext				channelContext;
	private Charset						encoding;
	private Set 					blackIPs;
	private FutureAcceptorService				appRedeployService;
	private FutureAcceptor					filterService	;
	private ApplicationExtLoader				applicationExtLoader;
	private ApplicationConfigurationLoader		acLoader;
	private AtomicInteger					pluginIndex;
	private ExceptionCaughtHandle				exceptionCaughtHandle;
	private Logger							logger		= LoggerFactory.getLogger(getClass());
	private LoginCenter						loginCenter	= new AuthorityLoginCenter();
	private List			pluginFilters	= new ArrayList();
	private Map	pluginServlets	= new HashMap();
	private RoleManager						roleManager	= new RoleManager();
	private FutureAcceptorServiceLoader		acceptorServiceLoader;
	private FutureAcceptorServiceFilter		futureAcceptorServiceFilter;
	private Map	services		= new LinkedHashMap();

	public ApplicationContext(String rootLocalAddres) {
		this(rootLocalAddres,null);
	}
	
	public ApplicationContext(ApplicationConfiguration configuration) {
		this(FileUtil.getCurrentPath(),configuration);
	}
	
	public ApplicationContext(String rootLocalAddres,ApplicationConfiguration configuration) {
		this.rootLocalAddres = rootLocalAddres;
		this.configuration = configuration;
	}

	@Override
	protected void doStart() throws Exception {

		if (channelContext == null) {
			throw new IllegalArgumentException("null nio context");
		}
		
		if (StringUtil.isNullOrBlank(rootLocalAddres)) {
			throw new IllegalArgumentException("rootLocalAddres");
		}
		
		if (futureAcceptorServiceFilter == null) {
			this.futureAcceptorServiceFilter = new FutureAcceptorServiceFilter();
		}

		if (appRedeployService == null) {
			appRedeployService = new SystemRedeployServlet();
		}
		
		if (acLoader == null) {
			acLoader = new FileSystemACLoader();
		}
		
		if (exceptionCaughtHandle == null) {
			exceptionCaughtHandle = new LoggerExceptionCaughtHandle();
		}
		
		instance = this;
		
		this.rootLocalAddres = FileUtil.getPrettyPath(rootLocalAddres);

		this.encoding = channelContext.getEncoding();

		this.clearPluginFilters();

		this.clearPluginServlets();

		this.filterService = new FutureAcceptor(this, futureAcceptorServiceFilter);
		
		this.appLocalAddres = FileUtil.getPrettyPath(getRootLocalAddres() + "app");
		
		LoggerUtil.prettyNIOServerLog(logger, "application path      :{ {} }", appLocalAddres);

		this.initializeApplicationContext();
		
		this.channelContext.setSessionAttachmentSize(filterService.getPluginContexts().length);
	}
	
	private void initializeApplicationContext() throws Exception{
		
		this.pluginIndex = new AtomicInteger();
		
		this.classLoader = new URLDynamicClassLoader(getClass().getClassLoader());
		
		this.classLoader.scan(getRootLocalAddres()+"conf");
		
		this.configuration = acLoader.loadConfiguration(classLoader);

		LifeCycleUtil.start(filterService);

		this.roleManager.initialize(this, null);
		this.loginCenter.initialize(this, null);
		
		this.acceptorServiceLoader = filterService.getFutureAcceptorServiceLoader();
		this.acceptorServiceLoader.listen(services);
	}
	
	private void destroyApplicationContext(){
		
		LifeCycleUtil.stop(filterService);
		
		InitializeUtil.destroy(loginCenter, this,null);
		InitializeUtil.destroy(roleManager, this,null);

		clearPluginFilters();

		clearPluginServlets();

		classLoader.unloadClassLoader();
	}

	public void addSessionEventListener(SocketSessionEventListener listener) {
		channelContext.addSessionEventListener(listener);
	}

	@Override
	protected void doStop() throws Exception {
		destroyApplicationContext();
		instance = null;
	}

	public String getAppLocalAddress() {
		return appLocalAddres;
	}

	public DynamicClassLoader getClassLoader() {
		return classLoader;
	}

	public ApplicationConfiguration getConfiguration() {
		return configuration;
	}

	public SocketChannelContext getChannelContext() {
		return channelContext;
	}

	public Charset getEncoding() {
		return encoding;
	}

	protected FutureAcceptor getFilterService() {
		return filterService;
	}

	public LoginCenter getLoginCenter() {
		return loginCenter;
	}

	@SuppressWarnings("rawtypes")
	public PluginContext getPluginContext(Class clazz) {

		PluginContext[] pluginContexts = filterService.getPluginContexts();

		for (PluginContext context : pluginContexts) {

			if (context == null) {
				continue;
			}

			if (context.getClass().isAssignableFrom(clazz)) {
				return context;
			}
		}
		return null;
	}

	public List getPluginFilters() {
		return pluginFilters;
	}

	public Map getPluginServlets() {
		return pluginServlets;
	}

	public RoleManager getRoleManager() {
		return roleManager;
	}

	private void clearPluginServlets() {
		pluginServlets.clear();
		putPluginServices(getAppRedeployService());
		putPluginServices(new SystemStopServerServlet());

	}

	private void putPluginServices(FutureAcceptorService service) {
		pluginServlets.put(service.getServiceName(), service);
	}

	private void clearPluginFilters() {
		pluginFilters.clear();
	}

	// FIXME 考虑部署失败后如何再次部署
	// FIXME redeploy roleManager
	// FIXME redeploy loginCenter
	// FIXME keep http session
	public synchronized boolean redeploy() {

		LoggerUtil.prettyNIOServerLog(logger, "//**********************  开始卸载服务  **********************//");

		redeploying = true;
		
		destroyApplicationContext();

		LoggerUtil.prettyNIOServerLog(logger, "//**********************  卸载服务完成  **********************//\n");

		try {

			// FIXME 重新加载configuration
			LoggerUtil.prettyNIOServerLog(logger, "//**********************  开始加载服务  **********************//");

			initializeApplicationContext();
			
			redeploying = false;
			
			LoggerUtil.prettyNIOServerLog(logger, "//**********************  加载服务完成  **********************//\n");

			return true;

		} catch (Exception e) {

			classLoader.unloadClassLoader();
			
			redeploying = false;

			LoggerUtil.prettyNIOServerLog(logger, "//**********************  加载服务失败  **********************//\n");

			logger.info(e.getMessage(), e);

			return false;
		}
		
	}

	public void setChannelContext(SocketChannelContext context) {
		this.channelContext = context;
	}

	public void setLoginCenter(LoginCenter loginCenter) {

		if (loginCenter == null) {
			throw new IllegalArgumentException("null");
		}

		if (this.loginCenter.getClass() != AuthorityLoginCenter.class) {
			// FIXME 这里是否只能设置一次
			// throw new IllegalArgumentException("already setted");
		}

		this.loginCenter = loginCenter;
	}

	public void listen(String serviceName, FutureAcceptorService service) {

		if (isRunning()) {
			throw new IllegalStateException("listen before start");
		}

		this.services.put(serviceName, service);
	}

	public FutureAcceptorService getAppRedeployService() {
		return appRedeployService;
	}

	public void setAppRedeployService(FutureAcceptorService appRedeployService) {
		this.appRedeployService = appRedeployService;
	}

	public void setServiceFilter(FutureAcceptorServiceFilter serviceFilter) {
		this.futureAcceptorServiceFilter = serviceFilter;
	}

	public ApplicationExtLoader getApplicationExtLoader() {
		return applicationExtLoader;
	}

	public void setApplicationExtLoader(ApplicationExtLoader applicationExtLoader) {
		this.applicationExtLoader = applicationExtLoader;
	}
	
	public String getRootLocalAddres() {
		return rootLocalAddres;
	}
	
	public void setApplicationConfigurationLoader(ApplicationConfigurationLoader acLoader) {
		this.acLoader = acLoader;
	}
	
	/**
	 * @return the pluginIndex
	 */
	public AtomicInteger getPluginIndex() {
		return pluginIndex;
	}
	
	/**
	 * @return the redeploying
	 */
	public boolean isRedeploying() {
		return redeploying;
	}

	public ExceptionCaughtHandle getExceptionCaughtHandle() {
		return exceptionCaughtHandle;
	}

	public void setExceptionCaughtHandle(ExceptionCaughtHandle exceptionCaughtHandle) {
		this.exceptionCaughtHandle = exceptionCaughtHandle;
	}

	public Set getBlackIPs() {
		return blackIPs;
	}

	public void setBlackIPs(Set blackIPs) {
		this.blackIPs = blackIPs;
	}
	
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy