提交 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));
}
}
}
}
}
}
}
......@@ -54,247 +54,247 @@ import net.sf.ehcache.hibernate.management.impl.BeanUtils;
public class RestoreData {
private static final Logger LOGGER = LoggerFactory.getLogger(RestoreData.class);
private static final Logger LOGGER = LoggerFactory.getLogger(RestoreData.class);
public boolean execute(String path) throws IOException, URISyntaxException {
Date start = new Date();
if (StringUtils.isEmpty(path)) {
LOGGER.warn("{}.", () -> "path is empty.");
}
ClassLoader classLoader = EntityClassLoaderTools.concreteClassLoader();
Path dir = dir(path);
Thread thread = new Thread(new RunnableImpl(dir, start, classLoader));
thread.start();
return true;
}
public boolean execute(String path) throws IOException, URISyntaxException {
Date start = new Date();
if (StringUtils.isEmpty(path)) {
LOGGER.warn("{}.", () -> "path is empty.");
}
ClassLoader classLoader = EntityClassLoaderTools.concreteClassLoader();
Path dir = dir(path);
Thread thread = new Thread(new RunnableImpl(dir, start, classLoader));
thread.start();
return true;
}
private Path dir(String path) throws IOException, URISyntaxException {
Path dir;
if (BooleanUtils.isTrue(DateTools.isCompactDateTime(path))) {
dir = Paths.get(Config.base(), "local", "dump", "dumpData_" + path);
} else {
dir = Paths.get(path);
if ((!Files.exists(dir)) || (!Files.isDirectory(dir))) {
throw new IllegalArgumentException("directory not exist: " + path + ".");
} else if (dir.startsWith(Paths.get(Config.base()))) {
throw new IllegalArgumentException("path can not in base directory.");
}
}
return dir;
}
private Path dir(String path) throws IOException, URISyntaxException {
Path dir;
if (BooleanUtils.isTrue(DateTools.isCompactDateTime(path))) {
dir = Paths.get(Config.base(), "local", "dump", "dumpData_" + path);
} else {
dir = Paths.get(path);
if ((!Files.exists(dir)) || (!Files.isDirectory(dir))) {
throw new IllegalArgumentException("directory not exist: " + path + ".");
} else if (dir.startsWith(Paths.get(Config.base()))) {
throw new IllegalArgumentException("path can not in base directory.");
}
}
return dir;
}
public class RunnableImpl implements Runnable {
public class RunnableImpl implements Runnable {
private Path dir;
private Date start;
private DumpRestoreDataCatalog catalog;
private Gson gson;
private ClassLoader classLoader;
private Path dir;
private Date start;
private DumpRestoreDataCatalog catalog;
private Gson gson;
private ClassLoader classLoader;
public RunnableImpl(Path dir, Date start, ClassLoader classLoader) throws IOException {
this.dir = dir;
this.start = start;
this.classLoader = classLoader;
Thread.currentThread().setContextClassLoader(classLoader);
this.catalog = new DumpRestoreDataCatalog();
this.gson = XGsonBuilder.instance();
Path path = dir.resolve("catalog.json");
this.catalog = XGsonBuilder.instance().fromJson(
new String(Files.readAllBytes(path), StandardCharsets.UTF_8), DumpRestoreDataCatalog.class);
}
public RunnableImpl(Path dir, Date start, ClassLoader classLoader) throws IOException {
this.dir = dir;
this.start = start;
this.classLoader = classLoader;
Thread.currentThread().setContextClassLoader(classLoader);
this.catalog = new DumpRestoreDataCatalog();
this.gson = XGsonBuilder.instance();
Path path = dir.resolve("catalog.json");
this.catalog = XGsonBuilder.instance().fromJson(
new String(Files.readAllBytes(path), StandardCharsets.UTF_8), DumpRestoreDataCatalog.class);
}
@Override
public void run() {
try {
List<String> classNames = entities(catalog, classLoader);
LOGGER.print("find: {} data to restore, path: {}.", classNames.size(), this.dir.toString());
Path xml = Paths.get(Config.dir_local_temp_classes().getAbsolutePath(),
DateTools.compact(start) + "_restore.xml");
PersistenceXmlHelper.write(xml.toString(), classNames, true, classLoader);
AtomicInteger idx = new AtomicInteger(1);
AtomicLong total = new AtomicLong(0);
Stream<String> stream = BooleanUtils.isTrue(Config.dumpRestoreData().getParallel())
? classNames.parallelStream()
: classNames.stream();
stream.forEach(className -> {
Thread.currentThread().setContextClassLoader(classLoader);
try {
@SuppressWarnings("unchecked")
Class<JpaObject> cls = (Class<JpaObject>) Thread.currentThread().getContextClassLoader()
.loadClass(className);
LOGGER.print("restore data({}/{}): {}.", idx.getAndAdd(1), classNames.size(), cls.getName());
long size = restore(cls, Config.dumpRestoreData().getAttachStorage(), xml);
total.getAndAdd(size);
} catch (Exception e) {
LOGGER.error(new Exception(String.format("restore:%s error.", className), e));
}
});
LOGGER.print("restore data completed, directory: {}, count: {}, total: {}, elapsed: {} minutes.",
dir.toString(), idx.get(), total.longValue(),
(System.currentTimeMillis() - start.getTime()) / 1000 / 60);
} catch (Exception e) {
LOGGER.error(e);
}
}
@Override
public void run() {
try {
List<String> classNames = entities(catalog, classLoader);
LOGGER.print("find: {} data to restore, path: {}.", classNames.size(), this.dir.toString());
Path xml = Paths.get(Config.dir_local_temp_classes().getAbsolutePath(),
DateTools.compact(start) + "_restore.xml");
PersistenceXmlHelper.write(xml.toString(), classNames, true, classLoader);
AtomicInteger idx = new AtomicInteger(1);
AtomicLong total = new AtomicLong(0);
Stream<String> stream = BooleanUtils.isTrue(Config.dumpRestoreData().getParallel())
? classNames.parallelStream()
: classNames.stream();
stream.forEach(className -> {
Thread.currentThread().setContextClassLoader(classLoader);
try {
@SuppressWarnings("unchecked")
Class<JpaObject> cls = (Class<JpaObject>) Thread.currentThread().getContextClassLoader()
.loadClass(className);
LOGGER.print("restore data({}/{}): {}.", idx.getAndAdd(1), classNames.size(), cls.getName());
long size = restore(cls, Config.dumpRestoreData().getAttachStorage(), xml);
total.getAndAdd(size);
} catch (Exception e) {
LOGGER.error(new Exception(String.format("restore:%s error.", className), e));
}
});
LOGGER.print("restore data completed, directory: {}, count: {}, total: {}, elapsed: {} minutes.",
dir.toString(), idx.get(), total.longValue(),
(System.currentTimeMillis() - start.getTime()) / 1000 / 60);
} catch (Exception e) {
LOGGER.error(e);
}
}
private long restore(Class<?> cls, boolean attachStorage, Path xml) throws Exception {
EntityManagerFactory emf = OpenJPAPersistence.createEntityManagerFactory(cls.getName(),
xml.getFileName().toString(), PersistenceXmlHelper.properties(cls.getName(), false));
EntityManager em = emf.createEntityManager();
em.setFlushMode(FlushModeType.COMMIT);
AtomicLong count = new AtomicLong(0);
AtomicInteger batch = new AtomicInteger(1);
try {
Path directory = dir.resolve(cls.getName());
if ((!Files.exists(directory)) || (!Files.isDirectory(directory))) {
throw new ExceptionDirectoryNotExist(directory);
}
StorageMappings storageMappings = Config.storageMappings();
if (!Objects.equals(Config.dumpRestoreData().getRestoreOverride(),
DumpRestoreData.RESTOREOVERRIDE_SKIPEXISTED)) {
this.clean(cls, em, storageMappings, cls.getAnnotation(ContainerEntity.class));
em.clear();
}
List<Path> paths = this.list(directory);
paths.stream().forEach(o -> {
LOGGER.print("restore {}/{} part of data:{}.", batch.getAndAdd(1), paths.size(), cls.getName());
try {
restore(cls, o, em, attachStorage, storageMappings, count);
} catch (Exception e) {
LOGGER.error(new Exception(String.format("restore error with file:%s.", o.toString()), e));
}
});
LOGGER.print("restore data: {} completed, count: {}.", cls.getName(), count.intValue());
} catch (Exception e) {
LOGGER.error(e);
} finally {
em.close();
emf.close();
}
return count.longValue();
}
private long restore(Class<?> cls, boolean attachStorage, Path xml) throws Exception {
EntityManagerFactory emf = OpenJPAPersistence.createEntityManagerFactory(cls.getName(),
xml.getFileName().toString(), PersistenceXmlHelper.properties(cls.getName(), false));
EntityManager em = emf.createEntityManager();
em.setFlushMode(FlushModeType.COMMIT);
AtomicLong count = new AtomicLong(0);
AtomicInteger batch = new AtomicInteger(1);
try {
Path directory = dir.resolve(cls.getName());
if ((!Files.exists(directory)) || (!Files.isDirectory(directory))) {
throw new ExceptionDirectoryNotExist(directory);
}
StorageMappings storageMappings = Config.storageMappings();
if (!Objects.equals(Config.dumpRestoreData().getRestoreOverride(),
DumpRestoreData.RESTOREOVERRIDE_SKIPEXISTED)) {
this.clean(cls, em, storageMappings, cls.getAnnotation(ContainerEntity.class));
em.clear();
}
List<Path> paths = this.list(directory);
paths.stream().forEach(o -> {
LOGGER.print("restore {}/{} part of data:{}.", batch.getAndAdd(1), paths.size(), cls.getName());
try {
restore(cls, o, em, attachStorage, storageMappings, count);
} catch (Exception e) {
LOGGER.error(new Exception(String.format("restore error with file:%s.", o.toString()), e));
}
});
LOGGER.print("restore data: {} completed, count: {}.", cls.getName(), count.intValue());
} catch (Exception e) {
LOGGER.error(e);
} finally {
em.close();
emf.close();
}
return count.longValue();
}
private void restore(Class<?> cls, Path o, EntityManager em, boolean attachStorage,
StorageMappings storageMappings, AtomicLong count) throws Exception {
em.getTransaction().begin();
JsonArray raws = this.convert(o);
for (JsonElement json : raws) {
Object t = gson.fromJson(json, cls);
if (Objects.equals(Config.dumpRestoreData().getRestoreOverride(),
DumpRestoreData.RESTOREOVERRIDE_SKIPEXISTED)
&& (null != em.find(cls, BeanUtils.getBeanProperty(t, JpaObject.id_FIELDNAME)))) {
continue;
}
if (StorageObject.class.isAssignableFrom(cls) && attachStorage) {
Path sub = o.resolveSibling(FilenameUtils.getBaseName(o.getFileName().toString()));
this.binary(t, cls, sub, storageMappings);
}
em.persist(t);
count.getAndAdd(1);
}
em.getTransaction().commit();
em.clear();
}
private void restore(Class<?> cls, Path o, EntityManager em, boolean attachStorage,
StorageMappings storageMappings, AtomicLong count) throws Exception {
em.getTransaction().begin();
JsonArray raws = this.convert(o);
for (JsonElement json : raws) {
Object t = gson.fromJson(json, cls);
if (Objects.equals(Config.dumpRestoreData().getRestoreOverride(),
DumpRestoreData.RESTOREOVERRIDE_SKIPEXISTED)
&& (null != em.find(cls, BeanUtils.getBeanProperty(t, JpaObject.id_FIELDNAME)))) {
continue;
}
if (StorageObject.class.isAssignableFrom(cls) && attachStorage) {
Path sub = o.resolveSibling(FilenameUtils.getBaseName(o.getFileName().toString()));
this.binary(t, cls, sub, storageMappings);
}
em.persist(t);
count.getAndAdd(1);
}
em.getTransaction().commit();
em.clear();
}
private List<Path> list(Path directory) throws IOException {
List<Path> list = new ArrayList<>();
try (Stream<Path> stream = Files.list(directory)) {
stream.filter(p -> StringUtils.endsWithIgnoreCase(p.getFileName().toString(), ".json"))
.sorted((Path p1, Path p2) -> {
Integer i1 = Integer.parseInt(FilenameUtils.getBaseName(p1.getFileName().toString()));
Integer i2 = Integer.parseInt(FilenameUtils.getBaseName(p2.getFileName().toString()));
return i1.compareTo(i2);
}).forEach(list::add);
}
return list;
}
private List<Path> list(Path directory) throws IOException {
List<Path> list = new ArrayList<>();
try (Stream<Path> stream = Files.list(directory)) {
stream.filter(p -> StringUtils.endsWithIgnoreCase(p.getFileName().toString(), ".json"))
.sorted((Path p1, Path p2) -> {
Integer i1 = Integer.parseInt(FilenameUtils.getBaseName(p1.getFileName().toString()));
Integer i2 = Integer.parseInt(FilenameUtils.getBaseName(p2.getFileName().toString()));
return i1.compareTo(i2);
}).forEach(list::add);
}
return list;
}
private List<String> entities(DumpRestoreDataCatalog catalog, ClassLoader classLoader) throws Exception {
List<String> containerEntityNames = new ArrayList<>(JpaObjectTools.scanContainerEntityNames(classLoader));
if (StringUtils.equalsIgnoreCase(DumpRestoreData.MODE_LITE, Config.dumpRestoreData().getMode())) {
containerEntityNames = containerEntityNames.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());
}
List<String> classNames = new ArrayList<>(catalog.keySet());
classNames = ListTools.includesExcludesWildcard(classNames, Config.dumpRestoreData().getIncludes(),
Config.dumpRestoreData().getExcludes());
return ListUtils.intersection(containerEntityNames, classNames);
}
private List<String> entities(DumpRestoreDataCatalog catalog, ClassLoader classLoader) throws Exception {
List<String> containerEntityNames = new ArrayList<>(JpaObjectTools.scanContainerEntityNames(classLoader));
if (StringUtils.equalsIgnoreCase(DumpRestoreData.MODE_LITE, Config.dumpRestoreData().getMode())) {
containerEntityNames = containerEntityNames.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());
}
List<String> classNames = new ArrayList<>(catalog.keySet());
classNames = ListTools.includesExcludesWildcard(classNames, Config.dumpRestoreData().getIncludes(),
Config.dumpRestoreData().getExcludes());
return ListUtils.intersection(containerEntityNames, classNames);
}
@SuppressWarnings("unchecked")
private void binary(Object o, Class<?> cls, Path sub, StorageMappings storageMappings) throws Exception {
StorageObject so = (StorageObject) o;
StorageMapping mapping = null;
if (BooleanUtils.isTrue(Config.dumpRestoreData().getRedistributeStorage())) {
mapping = storageMappings.random((Class<StorageObject>) cls);
} else {
mapping = storageMappings.get((Class<StorageObject>) cls, so.getStorage());
}
if (null == mapping) {
throw new ExceptionMappingNotExist();
}
Path path = sub.resolve(Paths.get(so.path()).getFileName());
if (!Files.exists(path)) {
LOGGER.warn("file not exist: {}.", path.toString());
} else {
try (InputStream input = Files.newInputStream(path)) {
so.saveContent(mapping, input, so.getName());
}
}
}
@SuppressWarnings("unchecked")
private void binary(Object o, Class<?> cls, Path sub, StorageMappings storageMappings) throws Exception {
StorageObject so = (StorageObject) o;
StorageMapping mapping = null;
if (BooleanUtils.isTrue(Config.dumpRestoreData().getRedistributeStorage())) {
mapping = storageMappings.random((Class<StorageObject>) cls);
} else {
mapping = storageMappings.get((Class<StorageObject>) cls, so.getStorage());
}
if (null == mapping) {
throw new ExceptionMappingNotExist();
}
Path path = sub.resolve(Paths.get(so.path()).getFileName());
if (!Files.exists(path)) {
LOGGER.warn("file not exist: {}.", path.toString());
} else {
try (InputStream input = Files.newInputStream(path)) {
so.saveContent(mapping, input, so.getName());
}
}
}
private JsonArray convert(Path path) throws IOException {
// 必须先转换成 jsonElement 不能直接转成泛型T,如果直接转会有类型不匹配比如Integer变成了Double
String json = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
JsonElement jsonElement = gson.fromJson(json, JsonElement.class);
return jsonElement.getAsJsonArray();
}
private JsonArray convert(Path path) throws IOException {
// 必须先转换成 jsonElement 不能直接转成泛型T,如果直接转会有类型不匹配比如Integer变成了Double
String json = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
JsonElement jsonElement = gson.fromJson(json, JsonElement.class);
return jsonElement.getAsJsonArray();
}
private <T> void clean(Class<T> cls, EntityManager em, StorageMappings storageMappings,
ContainerEntity containerEntity) throws Exception {
List<T> list = null;
do {
list = list(cls, em, containerEntity);
if (ListTools.isNotEmpty(list)) {
em.getTransaction().begin();
for (T t : list) {
if (BooleanUtils.isTrue(Config.dumpRestoreData().getAttachStorage())
&& StorageObject.class.isAssignableFrom(cls)) {
StorageObject so = (StorageObject) t;
@SuppressWarnings("unchecked")
StorageMapping mapping = storageMappings.get((Class<StorageObject>) cls, so.getStorage());
if (null != mapping) {
so.deleteContent(mapping);
}
}
em.remove(t);
}
em.getTransaction().commit();
em.clear();
}
} while (ListTools.isNotEmpty(list));
}
private <T> void clean(Class<T> cls, EntityManager em, StorageMappings storageMappings,
ContainerEntity containerEntity) throws Exception {
List<T> list = null;
do {
list = list(cls, em, containerEntity);
if (ListTools.isNotEmpty(list)) {
em.getTransaction().begin();
for (T t : list) {
if (BooleanUtils.isTrue(Config.dumpRestoreData().getAttachStorage())
&& StorageObject.class.isAssignableFrom(cls)) {
StorageObject so = (StorageObject) t;
@SuppressWarnings("unchecked")
StorageMapping mapping = storageMappings.get((Class<StorageObject>) cls, so.getStorage());
if (null != mapping) {
so.deleteContent(mapping);
}
}
em.remove(t);
}
em.getTransaction().commit();
em.clear();
}
} while (ListTools.isNotEmpty(list));
}
private <T> List<T> list(Class<T> cls, EntityManager em, ContainerEntity containerEntity) throws Exception {
List<T> list;
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<T> cq = cb.createQuery(cls);
Root<T> root = cq.from(cls);
Predicate p = cb.conjunction();
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())));
}
list = em.createQuery(cq.select(root).where(p)).setMaxResults(containerEntity.dumpSize()).getResultList();
return list;
}
}
private <T> List<T> list(Class<T> cls, EntityManager em, ContainerEntity containerEntity) throws Exception {
List<T> list;
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<T> cq = cb.createQuery(cls);
Root<T> root = cq.from(cls);
Predicate p = cb.conjunction();
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())));
}
list = em.createQuery(cq.select(root).where(p)).setMaxResults(containerEntity.dumpSize()).getResultList();
return list;
}
}
}
\ No newline at end of file
......@@ -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.
先完成此消息的编辑!
想要评论请 注册