Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.iqiny.silly.spring.SpringSillyConfigContent Maven / Gradle / Ivy
/*
* Copyright iqiny.com
*
* https://gitee.com/iqiny/silly
*
* project name:silly-spring
* project description:top silly project pom.xml file
*/
package com.iqiny.silly.spring;
import com.iqiny.silly.common.SillyConstant;
import com.iqiny.silly.common.exception.SillyException;
import com.iqiny.silly.common.util.SillyAssert;
import com.iqiny.silly.common.util.SillyObjectUtil;
import com.iqiny.silly.common.util.SillyReflectUtil;
import com.iqiny.silly.core.base.*;
import com.iqiny.silly.core.base.core.SillyEntity;
import com.iqiny.silly.core.base.core.SillyRootData;
import com.iqiny.silly.core.common.SillyCoreUtil;
import com.iqiny.silly.core.common.SillyExecutorUtil;
import com.iqiny.silly.core.config.BaseSillyConfigContent;
import com.iqiny.silly.core.config.SillyCategoryConfig;
import com.iqiny.silly.core.config.property.SillyProcessProperty;
import com.iqiny.silly.core.config.property.SillyPropertyHandle;
import com.iqiny.silly.core.data.SillyCategoryJsonData;
import com.iqiny.silly.core.engine.SillyEngineService;
import com.iqiny.silly.core.group.SillyTaskCategoryGroup;
import com.iqiny.silly.core.resume.SillyResumeService;
import com.iqiny.silly.core.savehandle.SillyOnceSourceData;
import com.iqiny.silly.core.service.SillyReadService;
import com.iqiny.silly.core.service.SillyWriteService;
import com.iqiny.silly.core.service.crud.SillyCrudService;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.util.ResourceUtils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import static org.springframework.util.StringUtils.tokenizeToStringArray;
@SuppressWarnings("all")
public class SpringSillyConfigContent extends BaseSillyConfigContent {
private final static Log log = LogFactory.getLog(SpringSillyConfigContent.class);
protected static final ResourcePatternResolver RESOURCE_PATTERN_RESOLVER = new PathMatchingResourcePatternResolver();
protected String processPattern;
protected Class extends SillyEngineService> defaultEngineServiceClazz;
protected Class extends SillyWriteService> defaultWriteServiceClazz;
protected Class extends SillyReadService> defaultReadServiceClazz;
protected Class extends SillyResumeService> defaultResumeServiceClazz;
protected Class extends SillyOnceSourceData> nodeSourceDataClazz;
protected Class extends SillyProcessProperty> processPropertyClazz;
protected Class extends SillyPropertyHandle> propertyHandleClazz;
protected Class extends SillyRootData> rootDataClazz;
protected Class extends SillyTaskCategoryGroup> defaultTaskCategoryGroupClazz;
private String[] categories;
private boolean loadCategoryFlag = false;
public SpringSillyConfigContent(SillyProperties sillyProperties, SillyContext sillyContext) {
super(sillyProperties, sillyContext);
}
@Override
protected void preInit() {
log.info("SpringSillyConfigContent " + this.getClass().getName() + " 初始化开始");
SillyAssert.notNull(sillyProperties, "sillyProperties 配置属性不可为空");
this.processPattern = sillyProperties.getProcessPattern();
this.defaultEngineServiceClazz = sillyProperties.getDefaultEngineServiceClazz();
this.defaultWriteServiceClazz = sillyProperties.getDefaultWriteServiceClazz();
this.defaultReadServiceClazz = sillyProperties.getDefaultReadServiceClazz();
this.defaultResumeServiceClazz = sillyProperties.getDefaultResumeServiceClazz();
this.processPropertyClazz = sillyProperties.getProcessPropertyClazz();
this.propertyHandleClazz = sillyProperties.getPropertyHandleClazz();
this.defaultTaskCategoryGroupClazz = sillyProperties.getDefaultTaskCategoryGroupClazz();
this.nodeSourceDataClazz = sillyProperties.getDefaultNodeSourceDataClazz();
this.categories = sillyProperties.getCategories();
}
@Override
protected void initFiled() {
this.loadCategoryFlag = false;
super.initFiled();
}
@Override
protected synchronized void loadCategorySet() {
if (loadCategoryFlag) {
return;
}
loadCategoryFlag = true;
if (categories != null) {
for (String category : categories) {
addCategorySet(category);
}
}
}
@Override
protected void initBaseSillyFactoryList() {
throw new SillyException("initBaseSillyFactoryList 此方法未实现");
}
@Override
protected SillyCrudService registerSillyCRUDService(Class extends SillyEntity> entityClazz) {
String sillyCRDUServiceBeanName = SillyContext.getSillyCRDUServiceBeanName(entityClazz);
Class extends SillyCrudService> crudServiceClazz = sillyProperties.getDefaultCrudServiceClazz();
return sillyContext.registerBean(
sillyCRDUServiceBeanName,
crudServiceClazz,
bdb -> {
SillyAssert.isTrue(bdb instanceof BeanDefinitionBuilder, "bdb类型错误" + bdb.getClass());
((BeanDefinitionBuilder) bdb).addPropertyValue("entityClazz", entityClazz);
});
}
@Override
protected void hookSillyProcessPropertyList() {
SillyExecutorUtil.lockObjExecute(SillyCategory.DEFAULT_CATEGORY, this, config -> {
refreshProcessResource();
return null;
});
}
/**
* 加载/刷新傻瓜流程配置资源
*/
public void refreshProcessResource() {
// 加载文件形式的业务JSON数据配置(将文件配置转存到数据库)
List resources = getCategoryResources();
List jsonPropertys = new ArrayList<>();
for (Resource resource : resources) {
final SillyProcessProperty property = loadSillyProcessProperty(resource);
if (property != null) {
jsonPropertys.add(property);
}
}
if (jsonDataClazz == null) {
// 加载文件形式的JSON数据配置
for (SillyProcessProperty property : jsonPropertys) {
addSillyProcessProperty(property);
}
} else {
// 加载数据库形式的JSON数据配置
final SillyCrudService sillyJsonSerivce = sillyContext.getSillyCrudService(jsonDataClazz);
SillyAssert.notNull(sillyJsonSerivce, "SillyCategoryJsonData 对象CRUD服务未找到,请完成配置");
final SillyCategoryJsonData jsonData = SillyReflectUtil.newInstance(sillyJsonSerivce.getEntityClazz());
jsonData.setStatus(SillyConstant.SillyNodeStatus.STATUS_CURRENT);
final List categoryJsonList = sillyJsonSerivce.selectList(jsonData);
for (SillyCategoryJsonData sillyCategoryJsonData : categoryJsonList) {
final SillyProcessProperty sillyProcessProperty = doCreateSillyProperty(sillyCategoryJsonData.getCategory(), sillyCategoryJsonData.getJsonData());
addSillyProcessProperty(sillyProcessProperty);
}
}
}
protected SillyProcessProperty loadSillyProcessProperty(Resource resource) {
if (resource == null || !resource.isReadable()) {
log.warn(resource == null ? "无数据" : resource.getFilename() + "不可读取,将跳过加载");
return null;
}
try (
InputStream inputStream = resource.getInputStream();
StringWriter writer = new StringWriter();
) {
// 生成jar后必须以流的形式读取
IOUtils.copy(inputStream, writer, StandardCharsets.UTF_8.name());
String json = writer.toString();
String fileName = resource.getFilename();
SillyProcessProperty sillyProcessProperty = doCreateSillyProperty(fileName.substring(0, fileName.lastIndexOf(".")), json);
final String category = sillyProcessProperty.getCategory();
if (jsonDataClazz == null) {
// 不进行数据存储,仅读取文件
return sillyProcessProperty;
} else {
// 查询数据库中是否存在相同业务且KEY值相同的数据
final SillyCrudService sillyJsonSerivce = sillyContext.getSillyCrudService(jsonDataClazz);
SillyAssert.notNull(sillyJsonSerivce, "SillyCategoryJsonData 对象CRUD服务未找到,请完成配置");
final SillyCategoryJsonData jsonData = SillyReflectUtil.newInstance(sillyJsonSerivce.getEntityClazz());
jsonData.setCategory(category);
final String md5key = DigestUtils.md5Hex(json);
jsonData.setJsonKey(md5key);
// 若存在,则跳过
final long count = sillyJsonSerivce.selectCount(jsonData);
if (count == 0) {
// 若不存在则将数据库数据状态设置为历史
final SillyCategoryJsonData whereJsonData = SillyReflectUtil.newInstance(sillyJsonSerivce.getEntityClazz());
whereJsonData.setCategory(category);
final SillyCategoryJsonData setJsonData = SillyReflectUtil.newInstance(sillyJsonSerivce.getEntityClazz());
setJsonData.setCategory(category);
setJsonData.setStatus(SillyConstant.SillyNodeStatus.STATUS_HISTORY);
sillyJsonSerivce.update(setJsonData, whereJsonData);
// 再将当前数据存档
jsonData.setJsonData(json);
jsonData.setStatus(SillyConstant.SillyNodeStatus.STATUS_CURRENT);
sillyJsonSerivce.insert(jsonData);
log.info("成功更新流程配置文件到数据库:" + category);
}
}
} catch (IOException e) {
log.warn(e.getMessage(), e);
}
return null;
}
protected SillyProcessProperty doCreateSillyProperty(String category, String json) {
// 按定义顺序生成
Class extends SillyProcessProperty> sillyProcessPropertyClass = getProcessPropertyClazz(category);
SillyProcessProperty processProperty = SillyObjectUtil.toObject(json, sillyProcessPropertyClass);
SillyAssert.notEmpty(processProperty.getCategory(), category + " category不可为空");
return processProperty;
}
@Override
protected void initComplete() {
log.info(this.getClass().getName() + " 初始化完成");
log.info("转换器:" + sillyConvertorList.size() + "个,对象工厂:" + sillyFactoryList.size() + "个," +
"读取服务:" + sillyReadServiceList.size() + "个,写入服务:" + sillyWriteServiceList.size() + "个," +
"流程属性:" + sillyProcessPropertyList.size() + "个");
log.info("成功注册" + sillyTaskGroupHandle.allSillyTaskGroup().size() + " 个任务组对象");
log.info("成功注册" + sillyTaskGroupHandle.allCategoryGroup().size() + " 个类型任务组对象");
log.info("已成功加载分类数量:" + allCategorySet().size() + " 种");
log.info("已成功加载分类:" + allCategorySet() + "");
}
public Class extends SillyProcessProperty> getProcessPropertyClazz(String category) {
SillyFactory sillyFactory = getSillyFactory(category);
if (sillyFactory != null) {
return sillyFactory.sillyProcessPropertyClass();
}
return processPropertyClazz;
}
@Override
protected Class extends SillyOnceSourceData> getNodeSourceDataClazz(String category) {
return nodeSourceDataClazz;
}
@Override
public Class extends SillyPropertyHandle> getPropertyHandleClazz(String category) {
return propertyHandleClazz;
}
@Override
public Class extends SillyRootData> getSillyRootDataClazz(String category) {
return rootDataClazz;
}
@Override
public SillyReadService getSillyReadService(String category) {
SillyReadService readService = SillyCoreUtil.consistentOne(category, sillyReadServiceList);
if (readService == null) {
readService = getSillyContext(category).registerBean(
SillyContext.getSillyReadServiceBeanName(category),
defaultReadServiceClazz,
bdb -> {
SillyAssert.isTrue(bdb instanceof BeanDefinitionBuilder, "bdb类型错误" + bdb.getClass());
((BeanDefinitionBuilder) bdb).addPropertyValue("category", category);
});
addSillyReadService(readService);
}
return readService;
}
@Override
public SillyWriteService getSillyWriteService(String category) {
SillyWriteService writeService = SillyCoreUtil.consistentOne(category, sillyWriteServiceList);
if (writeService == null) {
writeService = getSillyContext(category).registerBean(
SillyContext.getSillyWriteServiceBeanName(category),
defaultWriteServiceClazz,
bdb -> {
SillyAssert.isTrue(bdb instanceof BeanDefinitionBuilder, "bdb类型错误" + bdb.getClass());
((BeanDefinitionBuilder) bdb).addPropertyValue("category", category);
});
addSillyWriteService(writeService);
}
return writeService;
}
@Override
public SillyEngineService getSillyEngineService(String category) {
SillyEngineService service = SillyCoreUtil.availableOne(category, sillyEngineServiceList);
if (service == null) {
service = getSillyContext(category).registerBean(
SillyContext.getSillyEngineServiceBeanName(category),
defaultEngineServiceClazz,
bdb -> {
SillyAssert.isTrue(bdb instanceof BeanDefinitionBuilder, "bdb类型错误" + bdb.getClass());
((BeanDefinitionBuilder) bdb).addPropertyValue("category", category);
});
addSillyEngineService(service);
}
return service;
}
@Override
public SillyTaskCategoryGroup getSillyTaskCategoryGroup(String category
, String variableName, String groupName, String userVariableName) {
return getSillyContext(category).getBeanOrRegister(
SillyContext.getSillyTaskCategoryGroupBeanName(category, variableName, groupName),
defaultTaskCategoryGroupClazz,
bdb -> {
SillyAssert.isTrue(bdb instanceof BeanDefinitionBuilder, "bdb类型错误" + bdb.getClass());
((BeanDefinitionBuilder) bdb).addPropertyValue("category", category);
((BeanDefinitionBuilder) bdb).addPropertyValue("variableName", variableName);
((BeanDefinitionBuilder) bdb).addPropertyValue("groupName", groupName);
((BeanDefinitionBuilder) bdb).addPropertyValue("userVariableName", userVariableName);
});
}
@Override
public SillyResumeService getSillyResumeService(String category) {
SillyResumeService resumeService = SillyCoreUtil.consistentOne(category, sillyResumeServiceList);
if (resumeService == null) {
resumeService = getSillyContext(category).registerBean(
SillyContext.getSillyResumeServiceBeanName(category),
defaultResumeServiceClazz,
bdb -> {
SillyAssert.isTrue(bdb instanceof BeanDefinitionBuilder, "bdb类型错误" + bdb.getClass());
((BeanDefinitionBuilder) bdb).addPropertyValue("category", category);
});
addSillyResumeService(resumeService);
}
return resumeService;
}
@Override
public void init() {
// 初始化 配置
initSillyConfig();
// 初始化其余
initSillyInitializable();
}
protected void initSillyConfig() {
// 开始初始化配置
super.init();
log.info("SillyConfig:" + getClass().getName() + " 初始化完成");
}
protected void initSillyInitializable() {
// 开始初始化配置
final List beanList = sillyContext.getBeanList(SillyInitializable.class);
for (SillyInitializable sillyInitializable : beanList) {
// 不对sillyConfig重新初始化!
if (!(sillyInitializable instanceof SillyCategoryConfig)) {
// try catch 预防未知的异常导致项目无法启动(如:RPC执行init() 服务丢失/超时)
try {
sillyInitializable.init();
} catch (Exception e) {
if (e instanceof SillyException) {
throw e;
}
log.warn(sillyInitializable.getClass().getSimpleName() + "初始化异常:" + e.getMessage(), e);
}
if (log.isDebugEnabled()) {
log.debug("SillyInitializable:" + sillyInitializable.getClass().getName() + " 初始化完成");
}
}
}
}
protected boolean threadRefreshFlag = false;
protected synchronized void initSillyAutoRefresh() {
boolean autoRefresh = sillyProperties.autoRefresh();
if (!autoRefresh || threadRefreshFlag) {
return;
}
threadRefreshFlag = true;
// 线程实时刷新
new Thread(() -> {
// 上次加载刷新时间戳
Long beforeRefreshTime = System.currentTimeMillis();
Set fileSet = new LinkedHashSet<>();
List categoryResources = getCategoryResources();
for (Resource categoryResource : categoryResources) {
try {
if (ResourceUtils.isJarURL(categoryResource.getURL())) {
String key = new UrlResource(ResourceUtils.extractJarFileURL(categoryResource.getURL()))
.getFile().getPath();
fileSet.add(key);
} else {
fileSet.add(categoryResource.getFile().getPath());
}
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
try {
// 项目启动后延时 10秒加载配置刷新
Thread.sleep(10 * 1000);
} catch (InterruptedException interruptedException) {
interruptedException.printStackTrace();
}
log.warn("========== 自动热刷新 SillyConfig 线程已开启(生产环境请勿开启) ==========");
do {
try {
boolean hasModified = false;
for (String filePath : fileSet) {
File file = new File(filePath);
long lastModified = file.lastModified();
if (file.isFile() && lastModified > beforeRefreshTime) {
hasModified = true;
}
}
if (hasModified) {
super.refresh();
beforeRefreshTime = System.currentTimeMillis();
}
} catch (Exception exception) {
exception.printStackTrace();
}
try {
// 间隔 3秒 监控刷新
Thread.sleep(3 * 1000);
} catch (InterruptedException interruptedException) {
interruptedException.printStackTrace();
}
} while (true);
}, "silly Config-Refresh").start();
}
protected List getCategoryResources() {
String[] packagePatternArray = tokenizeToStringArray(processPattern,
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
List resourceList = new ArrayList<>();
try {
for (String packagePattern : packagePatternArray) {
Resource[] resources = RESOURCE_PATTERN_RESOLVER.getResources(packagePattern);
for (Resource resource : resources) {
resourceList.add(resource);
}
}
} catch (IOException e) {
log.warn(e.getMessage(), e);
}
return resourceList;
}
}