diff --git a/o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/DumpRestoreData.java b/o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/DumpRestoreData.java index fb33e98ff64a13f78522aef9c8029bdc09b4d592..87e8e227666f977c3e6c57c7fcdb04b60e46598d 100644 --- a/o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/DumpRestoreData.java +++ b/o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/DumpRestoreData.java @@ -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; diff --git a/o2server/x_console/src/main/java/com/x/server/console/action/DumpData.java b/o2server/x_console/src/main/java/com/x/server/console/action/DumpData.java index 6be7b5382f77a38308555bb460ebc28ab657b39b..923f3f6eec71f153c9feb2ebdb27eec8da2f94ee 100644 --- a/o2server/x_console/src/main/java/com/x/server/console/action/DumpData.java +++ b/o2server/x_console/src/main/java/com/x/server/console/action/DumpData.java @@ -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 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 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 cls = (Class) 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 entities(ClassLoader classLoader) throws Exception { - List 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 long estimateCount(EntityManager em, Class cls) { - CriteriaBuilder cb = em.getCriteriaBuilder(); - CriteriaQuery cq = cb.createQuery(Long.class); - Root 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 List list(EntityManager em, Class cls, String id, Integer size) throws Exception { - CriteriaBuilder cb = em.getCriteriaBuilder(); - CriteriaQuery cq = cb.createQuery(cls); - Root 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 void dump(Class 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 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 void binary(List 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 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 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 cls = (Class) 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 entities(ClassLoader classLoader) throws Exception { + List 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 long estimateCount(EntityManager em, Class cls) { + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cq = cb.createQuery(Long.class); + Root 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 List list(EntityManager em, Class cls, String id, Integer size) throws Exception { + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cq = cb.createQuery(cls); + Root 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 void dump(Class 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 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 void binary(List 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)); + } + } + } + } + } + } } diff --git a/o2server/x_console/src/main/java/com/x/server/console/action/RestoreData.java b/o2server/x_console/src/main/java/com/x/server/console/action/RestoreData.java index ba770a1fb6db590e7380f88b31341461e10264b0..aadeb8188d1a6f8997cac063da9afc7aedbda74a 100644 --- a/o2server/x_console/src/main/java/com/x/server/console/action/RestoreData.java +++ b/o2server/x_console/src/main/java/com/x/server/console/action/RestoreData.java @@ -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 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 stream = BooleanUtils.isTrue(Config.dumpRestoreData().getParallel()) - ? classNames.parallelStream() - : classNames.stream(); - stream.forEach(className -> { - Thread.currentThread().setContextClassLoader(classLoader); - try { - @SuppressWarnings("unchecked") - Class cls = (Class) 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 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 stream = BooleanUtils.isTrue(Config.dumpRestoreData().getParallel()) + ? classNames.parallelStream() + : classNames.stream(); + stream.forEach(className -> { + Thread.currentThread().setContextClassLoader(classLoader); + try { + @SuppressWarnings("unchecked") + Class cls = (Class) 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 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 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 list(Path directory) throws IOException { - List list = new ArrayList<>(); - try (Stream 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 list(Path directory) throws IOException { + List list = new ArrayList<>(); + try (Stream 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 entities(DumpRestoreDataCatalog catalog, ClassLoader classLoader) throws Exception { - List 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 classNames = new ArrayList<>(catalog.keySet()); - classNames = ListTools.includesExcludesWildcard(classNames, Config.dumpRestoreData().getIncludes(), - Config.dumpRestoreData().getExcludes()); - return ListUtils.intersection(containerEntityNames, classNames); - } + private List entities(DumpRestoreDataCatalog catalog, ClassLoader classLoader) throws Exception { + List 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 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) cls); - } else { - mapping = storageMappings.get((Class) 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) cls); + } else { + mapping = storageMappings.get((Class) 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 void clean(Class cls, EntityManager em, StorageMappings storageMappings, - ContainerEntity containerEntity) throws Exception { - List 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) cls, so.getStorage()); - if (null != mapping) { - so.deleteContent(mapping); - } - } - em.remove(t); - } - em.getTransaction().commit(); - em.clear(); - } - } while (ListTools.isNotEmpty(list)); - } + private void clean(Class cls, EntityManager em, StorageMappings storageMappings, + ContainerEntity containerEntity) throws Exception { + List 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) cls, so.getStorage()); + if (null != mapping) { + so.deleteContent(mapping); + } + } + em.remove(t); + } + em.getTransaction().commit(); + em.clear(); + } + } while (ListTools.isNotEmpty(list)); + } - private List list(Class cls, EntityManager em, ContainerEntity containerEntity) throws Exception { - List list; - CriteriaBuilder cb = em.getCriteriaBuilder(); - CriteriaQuery cq = cb.createQuery(cls); - Root 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 List list(Class cls, EntityManager em, ContainerEntity containerEntity) throws Exception { + List list; + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cq = cb.createQuery(cls); + Root 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 diff --git a/o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/AeiObjects.java b/o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/AeiObjects.java index 3347ce95c7891b913d1fdbf00adcab7eb8bcb7fe..5e88a1026dc7cb05b39ae7578f14eb02e98e37c7 100644 --- a/o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/AeiObjects.java +++ b/o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/AeiObjects.java @@ -300,7 +300,10 @@ public class AeiObjects extends GsonPropertyObject { public List getRoutes() throws Exception { if (null == this.routes) { - this.routes = this.business.element().listRouteWithActvity(work.getActivity(), work.getActivityType()); + List 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; }