提交 24d85d59 编写于 作者: Z zhourui

修改dd rd 默认配置,附件错误不中断.

上级 9114652e
......@@ -22,8 +22,8 @@ public class DumpRestoreData extends ConfigObject {
public static final String RESTOREOVERRIDE_CLEAN = "clean";
public static final String RESTOREOVERRIDE_SKIPEXISTED = "skipExisted";
public static final Boolean DEFAULT_REDISTRIBUTE = true;
public static final Boolean DEFAULT_EXCEPTIONINVALIDSTORAGE = true;
public static final Boolean DEFAULT_REDISTRIBUTE = false;
public static final Boolean DEFAULT_EXCEPTIONINVALIDSTORAGE = false;
public static final Boolean DEFAULT_ATTACHSTORAGE = true;
public static final String DEFAULT_ITEMCATEGORY = "";
public static final Boolean DEFAULT_PARALLEL = true;
......
......@@ -49,191 +49,194 @@ import com.x.base.core.project.tools.ListTools;
public class DumpData {
private static final Logger LOGGER = LoggerFactory.getLogger(DumpData.class);
public boolean execute(String path) throws IOException, URISyntaxException {
Path dir = null;
Date start = new Date();
if (StringUtils.isEmpty(path)) {
dir = Paths.get(Config.base(), "local", "dump", "dumpData_" + DateTools.compact(start));
} else {
dir = Paths.get(path);
if (dir.startsWith(Paths.get(Config.base()))) {
LOGGER.warn("path can not in base directory.");
return false;
}
}
ClassLoader classLoader = EntityClassLoaderTools.concreteClassLoader();
Files.createDirectories(dir);
Thread thread = new Thread(new RunnableImpl(dir, start, classLoader));
thread.setContextClassLoader(classLoader);
thread.start();
return true;
}
public class RunnableImpl implements Runnable {
private Path dir;
private Date start;
private DumpRestoreDataCatalog catalog;
private Gson pureGsonDateFormated;
private ClassLoader classLoader;
public RunnableImpl(Path dir, Date start, ClassLoader classLoader) {
this.dir = dir;
this.start = start;
this.catalog = new DumpRestoreDataCatalog();
this.pureGsonDateFormated = XGsonBuilder.instance();
this.classLoader = classLoader;
Thread.currentThread().setContextClassLoader(classLoader);
}
public void run() {
try {
List<String> classNames = this.entities(classLoader);
LOGGER.print("find {} data to dump, start at {}.", classNames.size(), DateTools.format(start));
Path xml = Paths.get(Config.dir_local_temp_classes().getAbsolutePath(),
DateTools.compact(start) + "_dump.xml");
PersistenceXmlHelper.write(xml.toString(), classNames, true, classLoader);
StorageMappings storageMappings = Config.storageMappings();
AtomicInteger idx = new AtomicInteger(1);
Stream<String> stream = BooleanUtils.isTrue(Config.dumpRestoreData().getParallel())
? classNames.parallelStream()
: classNames.stream();
stream.forEach(className -> {
Thread.currentThread().setContextClassLoader(classLoader);
String nameOfThread = Thread.currentThread().getName();
Thread.currentThread().setName(DumpData.class.getName() + ":" + className);
EntityManagerFactory emf = null;
EntityManager em = null;
try {
@SuppressWarnings("unchecked")
Class<JpaObject> cls = (Class<JpaObject>) classLoader.loadClass(className);
emf = OpenJPAPersistence.createEntityManagerFactory(cls.getName(), xml.getFileName().toString(),
PersistenceXmlHelper.properties(cls.getName(), false));
em = emf.createEntityManager();
long estimateCount = estimateCount(em, cls);
LOGGER.print("dump data({}/{}): {}, count: {}.", idx.getAndAdd(1), classNames.size(),
cls.getName(), estimateCount);
dump(cls, em, storageMappings, Config.dumpRestoreData().getAttachStorage(), estimateCount);
} catch (Exception e) {
e.printStackTrace();
LOGGER.error(new Exception(String.format("dump:%s error.", className), e));
} finally {
Thread.currentThread().setName(nameOfThread);
if (null != em) {
em.close();
}
if (null != emf) {
emf.close();
}
}
});
Files.write(dir.resolve("catalog.json"),
pureGsonDateFormated.toJson(catalog).getBytes(StandardCharsets.UTF_8));
LOGGER.print("dump data completed, directory: {}, count: {}, elapsed: {} minutes.", dir.toString(),
count(), (System.currentTimeMillis() - start.getTime()) / 1000 / 60);
} catch (Exception e) {
e.printStackTrace();
}
}
private List<String> entities(ClassLoader classLoader) throws Exception {
List<String> classNames = new ArrayList<>(JpaObjectTools.scanContainerEntityNames(classLoader));
classNames = ListTools.includesExcludesWildcard(classNames, Config.dumpRestoreData().getIncludes(),
Config.dumpRestoreData().getExcludes());
if (StringUtils.equalsIgnoreCase(DumpRestoreData.MODE_LITE, Config.dumpRestoreData().getMode())) {
return classNames.stream().filter(o -> {
try {
ContainerEntity containerEntity = classLoader.loadClass(o).getAnnotation(ContainerEntity.class);
return Objects.equals(containerEntity.reference(), ContainerEntity.Reference.strong);
} catch (Exception e) {
LOGGER.error(e);
}
return false;
}).collect(Collectors.toList());
}
return classNames;
}
private <T extends JpaObject> long estimateCount(EntityManager em, Class<T> cls) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Long> cq = cb.createQuery(Long.class);
Root<T> root = cq.from(cls);
cq.select(cb.count(root));
return em.createQuery(cq).getSingleResult();
}
private Integer count() {
return catalog.values().stream().mapToInt(Integer::intValue).sum();
}
private <T> List<T> list(EntityManager em, Class<T> cls, String id, Integer size) throws Exception {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<T> cq = cb.createQuery(cls);
Root<T> root = cq.from(cls);
Predicate p = cb.conjunction();
if (StringUtils.isNotEmpty(id)) {
p = cb.greaterThan(root.get(JpaObject.id_FIELDNAME), id);
}
if (StringUtils.equals(cls.getName(), "com.x.query.core.entity.Item")
&& (StringUtils.isNotBlank(Config.dumpRestoreData().getItemCategory()))) {
p = cb.and(p, cb.equal(root.get(DataItem.itemCategory_FIELDNAME),
ItemCategory.valueOf(Config.dumpRestoreData().getItemCategory())));
}
cq.select(root).where(p).orderBy(cb.asc(root.get(JpaObject.id_FIELDNAME)));
return em.createQuery(cq).setMaxResults(size).getResultList();
}
private <T> void dump(Class<T> cls, EntityManager em, StorageMappings storageMappings, boolean attachStorage,
long total) throws Exception {
// 创建最终存储文件的目录
Path directory = dir.resolve(cls.getName());
Files.createDirectories(directory);
PathUtils.cleanDirectory(directory);
ContainerEntity containerEntity = cls.getAnnotation(ContainerEntity.class);
String id = "";
List<T> list = null;
int count = 0;
int loop = 1;
int btach = (int) Math.ceil((total + 0.0) / containerEntity.dumpSize());
do {
list = list(em, cls, id, containerEntity.dumpSize());
if (ListTools.isNotEmpty(list)) {
count = count + list.size();
id = BeanUtils.getProperty(list.get(list.size() - 1), JpaObject.id_FIELDNAME);
if (StorageObject.class.isAssignableFrom(cls) && attachStorage) {
Path sub = directory.resolve(count + "");
Files.createDirectories(sub);
binary(list, sub, storageMappings);
}
Files.write(directory.resolve(count + ".json"),
pureGsonDateFormated.toJson(list).getBytes(StandardCharsets.UTF_8));
LOGGER.print("dump data {}/{} part of data:{}.", loop++, btach, cls.getName());
}
em.clear();
} while (ListTools.isNotEmpty(list));
catalog.put(cls.getName(), count);
}
private <T> void binary(List<T> list, Path sub, StorageMappings storageMappings) throws Exception {
for (T t : list) {
StorageObject s = (StorageObject) t;
String name = s.getStorage();
StorageMapping mapping = storageMappings.get(s.getClass(), name);
if (null == mapping && Config.dumpRestoreData().getExceptionInvalidStorage()) {
throw new ExceptionInvalidStorage(s);
}
if (null != mapping) {
Path p = sub.resolve(FilenameUtils.getName(s.path()));
if (s.existContent(mapping)) {
try (OutputStream out = Files.newOutputStream(p)) {
out.write(s.readContent(mapping));
}
}
}
}
}
}
private static final Logger LOGGER = LoggerFactory.getLogger(DumpData.class);
public boolean execute(String path) throws IOException, URISyntaxException {
Path dir = null;
Date start = new Date();
if (StringUtils.isEmpty(path)) {
dir = Paths.get(Config.base(), "local", "dump", "dumpData_" + DateTools.compact(start));
} else {
dir = Paths.get(path);
if (dir.startsWith(Paths.get(Config.base()))) {
LOGGER.warn("path can not in base directory.");
return false;
}
}
ClassLoader classLoader = EntityClassLoaderTools.concreteClassLoader();
Files.createDirectories(dir);
Thread thread = new Thread(new RunnableImpl(dir, start, classLoader));
thread.setContextClassLoader(classLoader);
thread.start();
return true;
}
public class RunnableImpl implements Runnable {
private Path dir;
private Date start;
private DumpRestoreDataCatalog catalog;
private Gson pureGsonDateFormated;
private ClassLoader classLoader;
public RunnableImpl(Path dir, Date start, ClassLoader classLoader) {
this.dir = dir;
this.start = start;
this.catalog = new DumpRestoreDataCatalog();
this.pureGsonDateFormated = XGsonBuilder.instance();
this.classLoader = classLoader;
Thread.currentThread().setContextClassLoader(classLoader);
}
public void run() {
try {
List<String> classNames = this.entities(classLoader);
LOGGER.print("find {} data to dump, start at {}.", classNames.size(), DateTools.format(start));
Path xml = Paths.get(Config.dir_local_temp_classes().getAbsolutePath(),
DateTools.compact(start) + "_dump.xml");
PersistenceXmlHelper.write(xml.toString(), classNames, true, classLoader);
StorageMappings storageMappings = Config.storageMappings();
AtomicInteger idx = new AtomicInteger(1);
Stream<String> stream = BooleanUtils.isTrue(Config.dumpRestoreData().getParallel())
? classNames.parallelStream()
: classNames.stream();
stream.forEach(className -> {
Thread.currentThread().setContextClassLoader(classLoader);
String nameOfThread = Thread.currentThread().getName();
Thread.currentThread().setName(DumpData.class.getName() + ":" + className);
EntityManagerFactory emf = null;
EntityManager em = null;
try {
@SuppressWarnings("unchecked")
Class<JpaObject> cls = (Class<JpaObject>) classLoader.loadClass(className);
emf = OpenJPAPersistence.createEntityManagerFactory(cls.getName(), xml.getFileName().toString(),
PersistenceXmlHelper.properties(cls.getName(), false));
em = emf.createEntityManager();
long estimateCount = estimateCount(em, cls);
LOGGER.print("dump data({}/{}): {}, count: {}.", idx.getAndAdd(1), classNames.size(),
cls.getName(), estimateCount);
dump(cls, em, storageMappings, Config.dumpRestoreData().getAttachStorage(), estimateCount);
} catch (Exception e) {
e.printStackTrace();
LOGGER.error(new Exception(String.format("dump:%s error.", className), e));
} finally {
Thread.currentThread().setName(nameOfThread);
if (null != em) {
em.close();
}
if (null != emf) {
emf.close();
}
}
});
Files.write(dir.resolve("catalog.json"),
pureGsonDateFormated.toJson(catalog).getBytes(StandardCharsets.UTF_8));
LOGGER.print("dump data completed, directory: {}, count: {}, elapsed: {} minutes.", dir.toString(),
count(), (System.currentTimeMillis() - start.getTime()) / 1000 / 60);
} catch (Exception e) {
e.printStackTrace();
}
}
private List<String> entities(ClassLoader classLoader) throws Exception {
List<String> classNames = new ArrayList<>(JpaObjectTools.scanContainerEntityNames(classLoader));
classNames = ListTools.includesExcludesWildcard(classNames, Config.dumpRestoreData().getIncludes(),
Config.dumpRestoreData().getExcludes());
if (StringUtils.equalsIgnoreCase(DumpRestoreData.MODE_LITE, Config.dumpRestoreData().getMode())) {
return classNames.stream().filter(o -> {
try {
ContainerEntity containerEntity = classLoader.loadClass(o).getAnnotation(ContainerEntity.class);
return Objects.equals(containerEntity.reference(), ContainerEntity.Reference.strong);
} catch (Exception e) {
LOGGER.error(e);
}
return false;
}).collect(Collectors.toList());
}
return classNames;
}
private <T extends JpaObject> long estimateCount(EntityManager em, Class<T> cls) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Long> cq = cb.createQuery(Long.class);
Root<T> root = cq.from(cls);
cq.select(cb.count(root));
return em.createQuery(cq).getSingleResult();
}
private Integer count() {
return catalog.values().stream().mapToInt(Integer::intValue).sum();
}
private <T> List<T> list(EntityManager em, Class<T> cls, String id, Integer size) throws Exception {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<T> cq = cb.createQuery(cls);
Root<T> root = cq.from(cls);
Predicate p = cb.conjunction();
if (StringUtils.isNotEmpty(id)) {
p = cb.greaterThan(root.get(JpaObject.id_FIELDNAME), id);
}
if (StringUtils.equals(cls.getName(), "com.x.query.core.entity.Item")
&& (StringUtils.isNotBlank(Config.dumpRestoreData().getItemCategory()))) {
p = cb.and(p, cb.equal(root.get(DataItem.itemCategory_FIELDNAME),
ItemCategory.valueOf(Config.dumpRestoreData().getItemCategory())));
}
cq.select(root).where(p).orderBy(cb.asc(root.get(JpaObject.id_FIELDNAME)));
return em.createQuery(cq).setMaxResults(size).getResultList();
}
private <T> void dump(Class<T> cls, EntityManager em, StorageMappings storageMappings, boolean attachStorage,
long total) throws Exception {
// 创建最终存储文件的目录
Path directory = dir.resolve(cls.getName());
Files.createDirectories(directory);
PathUtils.cleanDirectory(directory);
ContainerEntity containerEntity = cls.getAnnotation(ContainerEntity.class);
String id = "";
List<T> list = null;
int count = 0;
int loop = 1;
int btach = (int) Math.ceil((total + 0.0) / containerEntity.dumpSize());
do {
list = list(em, cls, id, containerEntity.dumpSize());
if (ListTools.isNotEmpty(list)) {
count = count + list.size();
id = BeanUtils.getProperty(list.get(list.size() - 1), JpaObject.id_FIELDNAME);
if (StorageObject.class.isAssignableFrom(cls) && attachStorage) {
Path sub = directory.resolve(count + "");
Files.createDirectories(sub);
binary(list, sub, storageMappings);
}
Files.write(directory.resolve(count + ".json"),
pureGsonDateFormated.toJson(list).getBytes(StandardCharsets.UTF_8));
LOGGER.print("dump data {}/{} part of data:{}.", loop++, btach, cls.getName());
}
em.clear();
} while (ListTools.isNotEmpty(list));
catalog.put(cls.getName(), count);
}
private <T> void binary(List<T> list, Path sub, StorageMappings storageMappings) throws Exception {
for (T t : list) {
StorageObject s = (StorageObject) t;
String name = s.getStorage();
StorageMapping mapping = storageMappings.get(s.getClass(), name);
if (null == mapping) {
if (BooleanUtils.isTrue(Config.dumpRestoreData().getExceptionInvalidStorage())) {
throw new ExceptionInvalidStorage(s);
} else {
LOGGER.warn("can not access storage:{}.", s);
}
} else {
Path p = sub.resolve(FilenameUtils.getName(s.path()));
if (s.existContent(mapping)) {
try (OutputStream out = Files.newOutputStream(p)) {
out.write(s.readContent(mapping));
}
}
}
}
}
}
}
......@@ -300,7 +300,10 @@ public class AeiObjects extends GsonPropertyObject {
public List<Route> getRoutes() throws Exception {
if (null == this.routes) {
this.routes = this.business.element().listRouteWithActvity(work.getActivity(), work.getActivityType());
List<Route> os = this.business.element().listRouteWithActvity(work.getActivity(), work.getActivityType());
this.routes = os.stream().sorted(Comparator.nullsLast(
Comparator.comparing(Route::getOrderNumber, Comparator.nullsLast(Comparator.naturalOrder()))))
.collect(Collectors.toList());
}
return this.routes;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册