use of com.shulie.instrument.simulator.core.CoreModule in project LinkAgent by shulieTech.
the class ModuleHttpServlet method doMethod.
private void doMethod(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
// 获取请求路径
final String path = req.getPathInfo();
// 如果心跳则直接回复,不经过命令
if (heartbeatPath.equals(path)) {
doHeartbeat(req, resp);
return;
}
if (shutdownPath.equals(path)) {
doShutdown(req, resp);
return;
}
/**
* 如果在销毁中,则忽略除心跳外的所有一切请求
*/
if (isDestroying) {
return;
}
// 获取模块ID
final String moduleId = parseModuleId(path);
if (StringUtils.isBlank(moduleId)) {
logger.warn("SIMULATOR: path={} is not matched any module.", path);
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
// 获取模块
final CoreModule coreModule = coreModuleManager.get(moduleId);
if (null == coreModule) {
logger.warn("SIMULATOR: path={} is matched module {}, but not existed.", path, moduleId);
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
// 匹配对应的方法
final Method method = matchingModuleMethod(path, moduleId, coreModule.getModule().getClass());
if (null == method) {
logger.warn("SIMULATOR: path={} is not matched any method in module {}", path, moduleId);
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
} else {
if (logger.isDebugEnabled()) {
logger.debug("SIMULATOR: path={} is matched method {} in module {}", path, method.getName(), moduleId);
}
}
// 自动释放I/O资源
final List<Closeable> autoCloseResources = coreModule.append(new ReleaseResource<List<Closeable>>(new ArrayList<Closeable>()) {
@Override
public void release() {
final List<Closeable> list = get();
if (CollectionUtils.isEmpty(list)) {
return;
}
for (final Closeable closeable : list) {
if (closeable instanceof Flushable) {
try {
((Flushable) closeable).flush();
} catch (Exception cause) {
logger.warn("SIMULATOR: path={} flush I/O occur error!", path, cause);
}
}
try {
closeable.close();
} catch (IOException e) {
}
}
}
});
// 生成方法调用参数
final Object[] parameterObjectArray = generateParameterObjectArray(method, req, resp);
final boolean isAccessible = method.isAccessible();
final ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
try {
method.setAccessible(true);
// 将当前的 ClassLoader置成是模块的 ClassLoader,处理模块执行时的类加载问题
Thread.currentThread().setContextClassLoader(coreModule.getClassLoaderFactory().getDefaultClassLoader());
Object value = method.invoke(coreModule.getModule(), parameterObjectArray);
if (logger.isDebugEnabled()) {
logger.debug("SIMULATOR: path={} invoke module {} method {} success.", path, moduleId, method.getName());
}
// do response之前
Thread.currentThread().setContextClassLoader(currentClassLoader);
doResponse(value, req, resp);
} catch (IllegalAccessException iae) {
logger.warn("SIMULATOR: path={} invoke module {} method {} occur access denied.", path, moduleId, method.getName(), iae);
throw new ServletException(iae);
} catch (InvocationTargetException ite) {
logger.warn("SIMULATOR: path={} invoke module {} method {} occur error.", path, moduleId, method.getName(), ite.getTargetException());
final Throwable targetCause = ite.getTargetException();
if (targetCause instanceof ServletException) {
throw (ServletException) targetCause;
}
if (targetCause instanceof IOException) {
throw (IOException) targetCause;
}
throw new ServletException(targetCause);
} finally {
Thread.currentThread().setContextClassLoader(currentClassLoader);
method.setAccessible(isAccessible);
coreModule.release(autoCloseResources);
}
}
use of com.shulie.instrument.simulator.core.CoreModule in project LinkAgent by shulieTech.
the class DefaultModuleManager method active.
@Override
public void active(String moduleId) throws ModuleException {
final CoreModule coreModule = coreModuleManager.getThrowsExceptionIfNull(moduleId);
coreModuleManager.active(coreModule);
}
use of com.shulie.instrument.simulator.core.CoreModule in project LinkAgent by shulieTech.
the class DefaultCoreModuleManager method unloadInOrder.
/**
* unload module in order
*
* @param coreModule
* @param modules
*/
private void unloadInOrder(CoreModule coreModule, List<CoreModule> modules) {
if (!coreModule.isLoaded()) {
return;
}
Iterator<CoreModule> it = modules.iterator();
while (it.hasNext()) {
CoreModule module = it.next();
// ignore if moduleSpec is null or dependencies is null
if (!module.isLoaded() || !module.getModuleSpec().getDependencies().contains(coreModule.getModuleId())) {
continue;
}
unloadInOrder(module, modules);
}
try {
unload(coreModule, true, false);
} catch (ModuleException cause) {
// 强制卸载不可能出错,这里不对外继续抛出任何异常
logger.warn("SIMULATOR: force unloading module occur error! module={};", coreModule.getModuleId(), cause);
}
}
use of com.shulie.instrument.simulator.core.CoreModule in project LinkAgent by shulieTech.
the class DefaultCoreModuleManager method softFlush.
/**
* 软刷新
* 找出有变动的模块文件,有且仅有改变这些文件所对应的模块
*/
private void softFlush() {
if (isInfoEnabled) {
logger.info("SIMULATOR: soft-flushing modules:{}", loadedModuleMap.keySet());
}
final File systemModuleLibDir = new File(config.getSystemModuleLibPath());
try {
final ArrayList<File> appendJarFiles = new ArrayList<File>();
final ArrayList<CoreModule> removeCoreModules = new ArrayList<CoreModule>();
final ArrayList<Long> checksumCRC32s = new ArrayList<Long>();
// 1. 找出所有有变动的文件(add/remove)
for (final File jarFile : this.moduleLoader.loadModuleLibs(config.getAppName(), config.getUserModulePaths())) {
final long checksumCRC32;
try {
checksumCRC32 = FileUtils.checksumCRC32(jarFile);
} catch (IOException cause) {
logger.warn("SIMULATOR: soft-flushing module: compute module-jar CRC32 occur error. module-jar={};", jarFile, cause);
continue;
}
checksumCRC32s.add(checksumCRC32);
// 如果CRC32已经在已加载的模块集合中存在,则说明这个文件没有变动,忽略
if (isChecksumCRC32Existed(checksumCRC32)) {
if (isInfoEnabled) {
logger.info("SIMULATOR: soft-flushing module: module-jar is not changed, ignored. module-jar={};CRC32={};", jarFile, checksumCRC32);
}
continue;
}
if (isInfoEnabled) {
logger.info("SIMULATOR: soft-flushing module: module-jar is changed, will be flush. module-jar={};CRC32={};", jarFile, checksumCRC32);
}
appendJarFiles.add(jarFile);
}
// 2. 找出所有待卸载的已加载用户模块
for (final CoreModule coreModule : loadedModuleMap.values()) {
final ClassLoaderFactory classLoaderFactory = coreModule.getClassLoaderFactory();
// 如果是系统模块目录则跳过
if (isOptimisticDirectoryContainsFile(systemModuleLibDir, coreModule.getJarFile())) {
if (isDebugEnabled) {
logger.debug("SIMULATOR: soft-flushing module: module-jar is in system-lib, will be ignored. module-jar={};system-lib={};", coreModule.getJarFile(), systemModuleLibDir);
}
continue;
}
// 如果CRC32已经在这次待加载的集合中,则说明这个文件没有变动,忽略
if (checksumCRC32s.contains(classLoaderFactory.getChecksumCRC32())) {
if (isInfoEnabled) {
logger.info("SIMULATOR: soft-flushing module: module-jar already loaded, ignored. module-jar={};CRC32={};", coreModule.getJarFile(), classLoaderFactory.getChecksumCRC32());
}
continue;
}
if (isInfoEnabled) {
logger.info("SIMULATOR: soft-flushing module: module-jar is changed, module will be reload/remove. module={};module-jar={};", coreModule.getModuleId(), coreModule.getJarFile());
}
removeCoreModules.add(coreModule);
}
// 3. 删除remove
for (final CoreModule coreModule : removeCoreModules) {
unload(coreModule, true);
}
// 3. 加载所有用户自定义模块
List<ModuleSpec> userModuleSpecs = ModuleSpecUtils.loadModuleSpecs(appendJarFiles, false);
loadModules(userModuleSpecs, "soft-flush");
} catch (Throwable cause) {
logger.warn("SIMULATOR: soft-flushing modules: occur error.", cause);
}
}
use of com.shulie.instrument.simulator.core.CoreModule in project LinkAgent by shulieTech.
the class DefaultCoreModuleManager method load.
/**
* 加载并注册模块
* <p>1. 如果模块已经存在则返回已经加载过的模块</p>
* <p>2. 如果模块不存在,则进行常规加载</p>
* <p>3. 如果模块初始化失败,则抛出异常</p>
*
* @param module 模块对象
* @param moduleJarFile 模块所在JAR文件
* @param classLoaderFactory 负责加载模块的ClassLoader工厂
* @throws ModuleException 加载模块失败
*/
private synchronized void load(final ModuleSpec moduleSpec, final ExtensionModule module, final File moduleJarFile, final ClassLoaderFactory classLoaderFactory) throws ModuleException {
if (loadedModuleMap.containsKey(moduleSpec.getModuleId())) {
if (isDebugEnabled) {
logger.debug("SIMULATOR: module already loaded. module={};", moduleSpec);
}
return;
}
if (isInfoEnabled) {
logger.info("SIMULATOR: loading module, module={};class={};module-jar={};", moduleSpec, module.getClass().getName(), moduleJarFile);
}
// 初始化模块信息
final CoreModule coreModule = new CoreModule(moduleSpec, moduleJarFile, classLoaderFactory, module, this);
/**
* 注入CoreModule需要的资源
*/
injectCoreModule(coreModule);
// 注入@Resource资源
injectResource(coreModule.getModule(), coreModule);
callAndFireModuleLifeCycle(coreModule, MODULE_LOAD);
// 设置为已经加载
coreModule.markLoaded(true);
// 如果模块标记了加载时自动激活,则需要在加载完成之后激活模块
markActiveOnLoadIfNecessary(coreModule);
// 注册到模块列表中
loadedModuleMap.put(moduleSpec.getModuleId(), coreModule);
// 通知生命周期,模块加载完成
callAndFireModuleLifeCycle(coreModule, MODULE_LOAD_COMPLETED);
}
Aggregations