From c7d3b8e9baea5f6e212af0a0812654d00c480bc4 Mon Sep 17 00:00:00 2001 From: Chris Henson Date: Sat, 4 Nov 2017 14:29:28 -0400 Subject: [PATCH] 0003301: Don't package snapshot zip like a jar file. Use zip utility instead. 0003302: Package all symmetric log files and wrapper log files in a system snapshot 0003303: Include more outgoing batch rows in the snapshot --- .../jumpmind/symmetric/util/SnapshotUtil.java | 243 ++++++++---------- .../java/org/jumpmind/util/ZipBuilder.java | 118 +++++++++ 2 files changed, 228 insertions(+), 133 deletions(-) create mode 100644 symmetric-util/src/main/java/org/jumpmind/util/ZipBuilder.java diff --git a/symmetric-client/src/main/java/org/jumpmind/symmetric/util/SnapshotUtil.java b/symmetric-client/src/main/java/org/jumpmind/symmetric/util/SnapshotUtil.java index 4b5ca2ff5e..3fe41a8b88 100644 --- a/symmetric-client/src/main/java/org/jumpmind/symmetric/util/SnapshotUtil.java +++ b/symmetric-client/src/main/java/org/jumpmind/symmetric/util/SnapshotUtil.java @@ -61,7 +61,6 @@ import org.jumpmind.exception.IoException; import org.jumpmind.properties.DefaultParameterParser.ParameterMetaData; import org.jumpmind.symmetric.ISymmetricEngine; -import org.jumpmind.symmetric.Version; import org.jumpmind.symmetric.common.ParameterConstants; import org.jumpmind.symmetric.common.SystemConstants; import org.jumpmind.symmetric.common.TableConstants; @@ -79,7 +78,7 @@ import org.jumpmind.symmetric.service.IParameterService; import org.jumpmind.symmetric.service.ITriggerRouterService; import org.jumpmind.util.AppUtils; -import org.jumpmind.util.JarBuilder; +import org.jumpmind.util.ZipBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -87,7 +86,7 @@ public class SnapshotUtil { protected static final Logger log = LoggerFactory.getLogger(SnapshotUtil.class); - + protected static final int THREAD_INDENT_SPACE = 50; public static File getSnapshotDirectory(ISymmetricEngine engine) { @@ -103,14 +102,14 @@ public static File createSnapshot(ISymmetricEngine engine) { IParameterService parameterService = engine.getParameterService(); File tmpDir = new File(parameterService.getTempDirectory(), dirName); tmpDir.mkdirs(); - + File logDir = null; - + String parameterizedLogDir = parameterService.getString("server.log.dir"); if (isNotBlank(parameterizedLogDir)) { logDir = new File(parameterizedLogDir); } - + if (logDir != null && logDir.exists()) { log.info("Using server.log.dir setting as the location of the log files"); } else { @@ -130,17 +129,18 @@ public static File createSnapshot(ISymmetricEngine engine) { if (!logDir.exists()) { logDir = new File("target"); } - + if (logDir.exists()) { File[] files = logDir.listFiles(); if (files != null) { for (File file : files) { - if (file.getName().toLowerCase().endsWith(".log")) { + String lowerCaseFileName = file.getName().toLowerCase(); + if (lowerCaseFileName.contains(".log") + && (lowerCaseFileName.contains("symmetric") || lowerCaseFileName.contains("wrapper"))) { try { FileUtils.copyFileToDirectory(file, tmpDir); } catch (IOException e) { - log.warn("Failed to copy " + file.getName() - + " to the snapshot directory", e); + log.warn("Failed to copy " + file.getName() + " to the snapshot directory", e); } } } @@ -152,11 +152,10 @@ public static File createSnapshot(ISymmetricEngine engine) { FileWriter fwriter = null; try { fwriter = new FileWriter(new File(tmpDir, "config-export.csv")); - engine.getDataExtractorService().extractConfigurationStandalone(engine.getNodeService().findIdentity(), - fwriter, TableConstants.SYM_NODE, TableConstants.SYM_NODE_SECURITY, - TableConstants.SYM_NODE_IDENTITY, TableConstants.SYM_NODE_HOST, - TableConstants.SYM_NODE_CHANNEL_CTL, TableConstants.SYM_CONSOLE_USER, - TableConstants.SYM_MONITOR_EVENT, TableConstants.SYM_CONSOLE_EVENT); + engine.getDataExtractorService().extractConfigurationStandalone(engine.getNodeService().findIdentity(), fwriter, + TableConstants.SYM_NODE, TableConstants.SYM_NODE_SECURITY, TableConstants.SYM_NODE_IDENTITY, TableConstants.SYM_NODE_HOST, + TableConstants.SYM_NODE_CHANNEL_CTL, TableConstants.SYM_CONSOLE_USER, TableConstants.SYM_MONITOR_EVENT, + TableConstants.SYM_CONSOLE_EVENT); } catch (Exception e) { log.warn("Failed to export symmetric configuration", e); } finally { @@ -174,26 +173,24 @@ public static File createSnapshot(ISymmetricEngine engine) { TreeSet tables = new TreeSet
(); FileOutputStream fos = null; - try { - ITriggerRouterService triggerRouterService = engine.getTriggerRouterService(); + try { + ITriggerRouterService triggerRouterService = engine.getTriggerRouterService(); List triggerHistories = triggerRouterService.getActiveTriggerHistories(); for (TriggerHistory triggerHistory : triggerHistories) { Table table = engine.getDatabasePlatform().getTableFromCache(triggerHistory.getSourceCatalogName(), - triggerHistory.getSourceSchemaName(), triggerHistory.getSourceTableName(), - false); + triggerHistory.getSourceSchemaName(), triggerHistory.getSourceTableName(), false); if (table != null && !table.getName().toUpperCase().startsWith(engine.getSymmetricDialect().getTablePrefix().toUpperCase())) { tables.add(table); } } - + List triggers = triggerRouterService.getTriggers(); for (Trigger trigger : triggers) { - Table table = engine.getDatabasePlatform().getTableFromCache(trigger.getSourceCatalogName(), - trigger.getSourceSchemaName(), trigger.getSourceTableName(), - false); + Table table = engine.getDatabasePlatform().getTableFromCache(trigger.getSourceCatalogName(), trigger.getSourceSchemaName(), + trigger.getSourceTableName(), false); if (table != null) { tables.add(table); - } + } } fos = new FileOutputStream(new File(tmpDir, "table-definitions.xml")); @@ -201,86 +198,80 @@ public static File createSnapshot(ISymmetricEngine engine) { export.setFormat(Format.XML); export.setNoData(true); export.exportTables(fos, tables.toArray(new Table[tables.size()])); - } catch(Exception e) { + } catch (Exception e) { log.warn("Failed to export table definitions", e); } finally { IOUtils.closeQuietly(fos); } String tablePrefix = engine.getTablePrefix(); - + DbExport export = new DbExport(engine.getDatabasePlatform()); export.setFormat(Format.CSV); export.setNoCreateInfo(true); - + extract(export, new File(tmpDir, "sym_identity.csv"), TableConstants.getTableName(tablePrefix, TableConstants.SYM_NODE_IDENTITY)); - - extract(export, new File(tmpDir, "sym_node.csv"), - TableConstants.getTableName(tablePrefix, TableConstants.SYM_NODE)); - - extract(export, new File(tmpDir, "sym_node_security.csv"), + + extract(export, new File(tmpDir, "sym_node.csv"), TableConstants.getTableName(tablePrefix, TableConstants.SYM_NODE)); + + extract(export, new File(tmpDir, "sym_node_security.csv"), TableConstants.getTableName(tablePrefix, TableConstants.SYM_NODE_SECURITY)); - extract(export, new File(tmpDir, "sym_node_host.csv"), - TableConstants.getTableName(tablePrefix, TableConstants.SYM_NODE_HOST)); - - extract(export, new File(tmpDir, "sym_trigger_hist.csv"), - TableConstants.getTableName(tablePrefix, TableConstants.SYM_TRIGGER_HIST)); + extract(export, new File(tmpDir, "sym_node_host.csv"), TableConstants.getTableName(tablePrefix, TableConstants.SYM_NODE_HOST)); + + extract(export, new File(tmpDir, "sym_trigger_hist.csv"), TableConstants.getTableName(tablePrefix, TableConstants.SYM_TRIGGER_HIST)); try { if (!parameterService.is(ParameterConstants.CLUSTER_LOCKING_ENABLED)) { - engine.getNodeCommunicationService().persistToTableForSnapshot(); - engine.getClusterService().persistToTableForSnapshot(); + engine.getNodeCommunicationService().persistToTableForSnapshot(); + engine.getClusterService().persistToTableForSnapshot(); } - } - catch (Exception e) { + } catch (Exception e) { log.warn("Unable to add SYM_NODE_COMMUNICATION to the snapshot.", e); } - - extract(export, new File(tmpDir, "sym_lock.csv"), - TableConstants.getTableName(tablePrefix, TableConstants.SYM_LOCK)); - - extract(export, new File(tmpDir, "sym_node_communication.csv"), + + extract(export, new File(tmpDir, "sym_lock.csv"), TableConstants.getTableName(tablePrefix, TableConstants.SYM_LOCK)); + + extract(export, new File(tmpDir, "sym_node_communication.csv"), TableConstants.getTableName(tablePrefix, TableConstants.SYM_NODE_COMMUNICATION)); - - extract(export, 10000, "order by create_time desc", new File(tmpDir, "sym_outgoing_batch.csv"), - TableConstants.getTableName(tablePrefix, TableConstants.SYM_OUTGOING_BATCH)); - extract(export, 10000, "where status != 'OK' order by create_time", new File(tmpDir, "sym_outgoing_batch_not_ok.csv"), - TableConstants.getTableName(tablePrefix, TableConstants.SYM_OUTGOING_BATCH)); + extract(export, 50000, "where status = 'OK' order by batch_id desc", new File(tmpDir, "sym_outgoing_batch_ok.csv"), + TableConstants.getTableName(tablePrefix, TableConstants.SYM_OUTGOING_BATCH)); - extract(export, 10000, "order by create_time desc", new File(tmpDir, "sym_incoming_batch.csv"), - TableConstants.getTableName(tablePrefix, TableConstants.SYM_INCOMING_BATCH)); + extract(export, 10000, "where status != 'OK' order by batch_id desc", new File(tmpDir, "sym_outgoing_batch_not_ok.csv"), + TableConstants.getTableName(tablePrefix, TableConstants.SYM_OUTGOING_BATCH)); - extract(export, 10000, "where status != 'OK' order by create_time", new File(tmpDir, "sym_incoming_batch_not_ok.csv"), - TableConstants.getTableName(tablePrefix, TableConstants.SYM_INCOMING_BATCH)); + extract(export, 10000, "where status = 'OK' order by create_time desc", new File(tmpDir, "sym_incoming_batch_ok.csv"), + TableConstants.getTableName(tablePrefix, TableConstants.SYM_INCOMING_BATCH)); - extract(export, 5000, "order by start_id, end_id desc", new File(tmpDir, "sym_data_gap.csv"), + extract(export, 10000, "where status != 'OK' order by create_time", new File(tmpDir, "sym_incoming_batch_not_ok.csv"), + TableConstants.getTableName(tablePrefix, TableConstants.SYM_INCOMING_BATCH)); + + extract(export, 10000, "order by start_id, end_id desc", new File(tmpDir, "sym_data_gap.csv"), TableConstants.getTableName(tablePrefix, TableConstants.SYM_DATA_GAP)); - extract(export, new File(tmpDir, "sym_table_reload_request.csv"), - TableConstants.getTableName(tablePrefix, TableConstants.SYM_TABLE_RELOAD_REQUEST)); + extract(export, new File(tmpDir, "sym_table_reload_request.csv"), + TableConstants.getTableName(tablePrefix, TableConstants.SYM_TABLE_RELOAD_REQUEST)); - extract(export, 5000, "order by relative_dir, file_name", new File(tmpDir, "sym_file_snapshot.csv"), - TableConstants.getTableName(tablePrefix, TableConstants.SYM_FILE_SNAPSHOT)); + extract(export, 5000, "order by relative_dir, file_name", new File(tmpDir, "sym_file_snapshot.csv"), + TableConstants.getTableName(tablePrefix, TableConstants.SYM_FILE_SNAPSHOT)); - extract(export, new File(tmpDir, "sym_console_event.csv"), - TableConstants.getTableName(tablePrefix, TableConstants.SYM_CONSOLE_EVENT)); + extract(export, new File(tmpDir, "sym_console_event.csv"), + TableConstants.getTableName(tablePrefix, TableConstants.SYM_CONSOLE_EVENT)); - extract(export, new File(tmpDir, "sym_monitor_event.csv"), - TableConstants.getTableName(tablePrefix, TableConstants.SYM_MONITOR_EVENT)); + extract(export, new File(tmpDir, "sym_monitor_event.csv"), + TableConstants.getTableName(tablePrefix, TableConstants.SYM_MONITOR_EVENT)); - extract(export, new File(tmpDir, "sym_extract_request.csv"), - TableConstants.getTableName(tablePrefix, TableConstants.SYM_EXTRACT_REQUEST)); + extract(export, new File(tmpDir, "sym_extract_request.csv"), + TableConstants.getTableName(tablePrefix, TableConstants.SYM_EXTRACT_REQUEST)); if (engine.getSymmetricDialect() instanceof FirebirdSymmetricDialect) { - final String[] monTables = { "mon$database", "mon$attachments", "mon$transactions", "mon$statements", - "mon$io_stats", "mon$record_stats", "mon$memory_usage", "mon$call_stack", "mon$context_variables"}; + final String[] monTables = { "mon$database", "mon$attachments", "mon$transactions", "mon$statements", "mon$io_stats", + "mon$record_stats", "mon$memory_usage", "mon$call_stack", "mon$context_variables" }; for (String table : monTables) { extract(export, new File(tmpDir, "firebird-" + table + ".csv"), table); } } - - + fwriter = null; try { fwriter = new FileWriter(new File(tmpDir, "threads.txt")); @@ -307,7 +298,7 @@ public static File createSnapshot(ISymmetricEngine engine) { Properties effectiveParameters = engine.getParameterService().getAllParameters(); SortedProperties parameters = new SortedProperties(); parameters.putAll(effectiveParameters); - parameters.remove("db.password"); + parameters.remove("db.password"); parameters.store(fos, "parameters.properties"); } catch (IOException e) { log.warn("Failed to export parameter information", e); @@ -330,10 +321,10 @@ public static File createSnapshot(ISymmetricEngine engine) { Properties effectiveParameters = engine.getParameterService().getAllParameters(); Properties changedParameters = new SortedProperties(); Map parameters = ParameterConstants.getParameterMetaData(); - for (String key: parameters.keySet()) { + for (String key : parameters.keySet()) { String defaultValue = defaultParameters.getProperty((String) key); String currentValue = effectiveParameters.getProperty((String) key); - if (defaultValue == null && currentValue != null || (defaultValue != null && ! defaultValue.equals(currentValue))) { + if (defaultValue == null && currentValue != null || (defaultValue != null && !defaultValue.equals(currentValue))) { changedParameters.put(key, currentValue == null ? "" : currentValue); } } @@ -347,7 +338,7 @@ public static File createSnapshot(ISymmetricEngine engine) { writeRuntimeStats(engine, tmpDir); writeJobsStats(engine, tmpDir); - + if ("true".equals(System.getProperty(SystemConstants.SYSPROP_STANDALONE_WEB))) { writeDirectoryListing(engine, tmpDir); } @@ -365,9 +356,8 @@ public static File createSnapshot(ISymmetricEngine engine) { } try { - File jarFile = new File(getSnapshotDirectory(engine), tmpDir.getName() - + ".zip"); - JarBuilder builder = new JarBuilder(tmpDir, jarFile, new File[] { tmpDir }, Version.version()); + File jarFile = new File(getSnapshotDirectory(engine), tmpDir.getName() + ".zip"); + ZipBuilder builder = new ZipBuilder(tmpDir, jarFile, new File[] { tmpDir }); builder.build(); FileUtils.deleteDirectory(tmpDir); return jarFile; @@ -375,42 +365,40 @@ public static File createSnapshot(ISymmetricEngine engine) { throw new IoException("Failed to package snapshot files into archive", e); } } - + protected static void extract(DbExport export, File file, String... tables) { extract(export, Integer.MAX_VALUE, null, file, tables); } - + protected static void extract(DbExport export, int maxRows, String whereClause, File file, String... tables) { FileOutputStream fos = null; try { fos = new FileOutputStream(file); export.setMaxRows(maxRows); export.setWhereClause(whereClause); - export.exportTables( - fos, - tables); + export.exportTables(fos, tables); } catch (Exception e) { log.warn("Failed to export table definitions", e); } finally { IOUtils.closeQuietly(fos); } } - + protected static void writeDirectoryListing(ISymmetricEngine engine, File tmpDir) { try { File home = new File(System.getProperty("user.dir")); if (home.getName().equalsIgnoreCase("bin")) { home = home.getParentFile(); } - + StringBuilder output = new StringBuilder(); printDirectoryContents(home, output); FileUtils.write(new File(tmpDir, "directory-listing.txt"), output); } catch (Exception ex) { - log.warn("Failed to output the direcetory listing" , ex); + log.warn("Failed to output the direcetory listing", ex); } } - + protected static void printDirectoryContents(File dir, StringBuilder output) throws IOException { output.append("\n"); output.append(dir.getCanonicalPath()); @@ -424,8 +412,7 @@ protected static void printDirectoryContents(File dir, StringBuilder output) thr output.append(file.canExecute() ? "x" : "-"); output.append(StringUtils.leftPad(file.length() + "", 11)); output.append(" "); - output.append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date(file - .lastModified()))); + output.append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date(file.lastModified()))); output.append(" "); output.append(file.getName()); output.append("\n"); @@ -445,6 +432,7 @@ protected static void writeRuntimeStats(ISymmetricEngine engine, File tmpDir) { fos = new FileOutputStream(new File(tmpDir, "runtime-stats.properties")); Properties runtimeProperties = new Properties() { private static final long serialVersionUID = 1L; + public synchronized Enumeration keys() { return Collections.enumeration(new TreeSet(super.keySet())); } @@ -455,14 +443,14 @@ public synchronized Enumeration keys() { BasicDataSource dbcp = (BasicDataSource) dataSource; runtimeProperties.setProperty("connections.idle", String.valueOf(dbcp.getNumIdle())); runtimeProperties.setProperty("connections.used", String.valueOf(dbcp.getNumActive())); - runtimeProperties.setProperty("connections.max", String.valueOf(dbcp.getMaxActive())); + runtimeProperties.setProperty("connections.max", String.valueOf(dbcp.getMaxActive())); } - + Runtime rt = Runtime.getRuntime(); runtimeProperties.setProperty("memory.free", String.valueOf(rt.freeMemory())); runtimeProperties.setProperty("memory.used", String.valueOf(rt.totalMemory() - rt.freeMemory())); runtimeProperties.setProperty("memory.max", String.valueOf(rt.maxMemory())); - + List memoryPools = new ArrayList(ManagementFactory.getMemoryPoolMXBeans()); long usedHeapMemory = 0; for (MemoryPoolMXBean memoryPool : memoryPools) { @@ -474,40 +462,34 @@ public synchronized Enumeration keys() { } } runtimeProperties.setProperty("memory.heap.total", Long.toString(usedHeapMemory)); - + OperatingSystemMXBean osBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean(); runtimeProperties.setProperty("os.name", System.getProperty("os.name") + " (" + System.getProperty("os.arch") + ")"); runtimeProperties.setProperty("os.processors", String.valueOf(osBean.getAvailableProcessors())); runtimeProperties.setProperty("os.load.average", String.valueOf(osBean.getSystemLoadAverage())); - + runtimeProperties.setProperty("engine.is.started", Boolean.toString(engine.isStarted())); runtimeProperties.setProperty("engine.last.restart", engine.getLastRestartTime().toString()); - + runtimeProperties.setProperty("time.server", new Date().toString()); runtimeProperties.setProperty("time.database", new Date(engine.getSymmetricDialect().getDatabaseTime()).toString()); - runtimeProperties.setProperty("batch.unrouted.data.count", - Long.toString(engine.getRouterService().getUnroutedDataCount())); + runtimeProperties.setProperty("batch.unrouted.data.count", Long.toString(engine.getRouterService().getUnroutedDataCount())); runtimeProperties.setProperty("batch.outgoing.errors.count", Long.toString(engine.getOutgoingBatchService().countOutgoingBatchesInError())); runtimeProperties.setProperty("batch.outgoing.tosend.count", Long.toString(engine.getOutgoingBatchService().countOutgoingBatchesUnsent())); runtimeProperties.setProperty("batch.incoming.errors.count", Long.toString(engine.getIncomingBatchService().countIncomingBatchesInError())); - + List gaps = engine.getDataService().findDataGapsByStatus(DataGap.Status.GP); - runtimeProperties.setProperty("data.gap.count", - Long.toString(gaps.size())); + runtimeProperties.setProperty("data.gap.count", Long.toString(gaps.size())); if (gaps.size() > 0) { - runtimeProperties.setProperty("data.gap.start.id", - Long.toString(gaps.get(0).getStartId())); - runtimeProperties.setProperty("data.gap.end.id", - Long.toString(gaps.get(gaps.size()-1).getEndId())); + runtimeProperties.setProperty("data.gap.start.id", Long.toString(gaps.get(0).getStartId())); + runtimeProperties.setProperty("data.gap.end.id", Long.toString(gaps.get(gaps.size() - 1).getEndId())); } - - runtimeProperties.setProperty("data.id.min", - Long.toString(engine.getDataService().findMinDataId())); - runtimeProperties.setProperty("data.id.max", - Long.toString(engine.getDataService().findMaxDataId())); + + runtimeProperties.setProperty("data.id.min", Long.toString(engine.getDataService().findMinDataId())); + runtimeProperties.setProperty("data.id.max", Long.toString(engine.getDataService().findMaxDataId())); runtimeProperties.put("jvm.title", Runtime.class.getPackage().getImplementationTitle()); runtimeProperties.put("jvm.vendor", Runtime.class.getPackage().getImplementationVendor()); @@ -515,7 +497,7 @@ public synchronized Enumeration keys() { RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean(); List arguments = runtimeMxBean.getInputArguments(); runtimeProperties.setProperty("jvm.arguments", arguments.toString()); - + runtimeProperties.store(fos, "runtime-stats.properties"); } catch (Exception e) { log.warn("Failed to export runtime-stats information", e); @@ -523,7 +505,7 @@ public synchronized Enumeration keys() { IOUtils.closeQuietly(fos); } } - + protected static void writeJobsStats(ISymmetricEngine engine, File tmpDir) { FileWriter writer = null; try { @@ -531,13 +513,12 @@ protected static void writeJobsStats(ISymmetricEngine engine, File tmpDir) { IJobManager jobManager = engine.getJobManager(); IClusterService clusterService = engine.getClusterService(); INodeService nodeService = engine.getNodeService(); - writer.write("Clustering is " + (clusterService.isClusteringEnabled() ? "" : "not ") + - "enabled and there are " + nodeService.findNodeHosts(nodeService.findIdentityNodeId()).size() + - " instances in the cluster\n\n"); - writer.write(StringUtils.rightPad("Job Name", 30) + StringUtils.rightPad("Schedule", 20) + - StringUtils.rightPad("Status", 10) + StringUtils.rightPad("Server Id", 30) + - StringUtils.rightPad("Last Server Id", 30) + StringUtils.rightPad("Last Finish Time", 30) + - StringUtils.rightPad("Last Run Period", 20) + StringUtils.rightPad("Avg. Run Period", 20) + "\n"); + writer.write("Clustering is " + (clusterService.isClusteringEnabled() ? "" : "not ") + "enabled and there are " + + nodeService.findNodeHosts(nodeService.findIdentityNodeId()).size() + " instances in the cluster\n\n"); + writer.write(StringUtils.rightPad("Job Name", 30) + StringUtils.rightPad("Schedule", 20) + StringUtils.rightPad("Status", 10) + + StringUtils.rightPad("Server Id", 30) + StringUtils.rightPad("Last Server Id", 30) + + StringUtils.rightPad("Last Finish Time", 30) + StringUtils.rightPad("Last Run Period", 20) + + StringUtils.rightPad("Avg. Run Period", 20) + "\n"); List jobs = jobManager.getJobs(); Map locks = clusterService.findLocks(); for (IJob job : jobs) { @@ -548,17 +529,16 @@ protected static void writeJobsStats(ISymmetricEngine engine, File tmpDir) { if (lock != null) { lastServerId = lock.getLastLockingServerId(); } - String schedule = StringUtils.isBlank(job.getCronExpression()) ? Long.toString(job - .getTimeBetweenRunsInMs()) : job.getCronExpression(); + String schedule = StringUtils.isBlank(job.getCronExpression()) ? Long.toString(job.getTimeBetweenRunsInMs()) + : job.getCronExpression(); String lastFinishTime = getLastFinishTime(job, lock); - - writer.write(StringUtils.rightPad(job.getClusterLockName().replace("_", " "), 30)+ - StringUtils.rightPad(schedule, 20) + StringUtils.rightPad(status, 10) + - StringUtils.rightPad(runningServerId == null ? "" : runningServerId, 30) + - StringUtils.rightPad(lastServerId == null ? "" : lastServerId, 30) + - StringUtils.rightPad(lastFinishTime == null ? "" : lastFinishTime, 30) + - StringUtils.rightPad(job.getLastExecutionTimeInMs() + "", 20) + - StringUtils.rightPad(job.getAverageExecutionTimeInMs() + "", 20) + "\n"); + + writer.write(StringUtils.rightPad(job.getClusterLockName().replace("_", " "), 30) + StringUtils.rightPad(schedule, 20) + + StringUtils.rightPad(status, 10) + StringUtils.rightPad(runningServerId == null ? "" : runningServerId, 30) + + StringUtils.rightPad(lastServerId == null ? "" : lastServerId, 30) + + StringUtils.rightPad(lastFinishTime == null ? "" : lastFinishTime, 30) + + StringUtils.rightPad(job.getLastExecutionTimeInMs() + "", 20) + + StringUtils.rightPad(job.getAverageExecutionTimeInMs() + "", 20) + "\n"); } } catch (Exception e) { log.warn("Failed to write jobs information", e); @@ -576,8 +556,7 @@ protected static String getJobStatus(IJob job, Lock lock) { status = "RUNNING"; } } else { - status = job.isRunning() ? "RUNNING" : job.isPaused() ? "PAUSED" : job - .isStarted() ? "IDLE" : "STOPPED"; + status = job.isRunning() ? "RUNNING" : job.isPaused() ? "PAUSED" : job.isStarted() ? "IDLE" : "STOPPED"; } return status; } @@ -586,11 +565,10 @@ protected static String getLastFinishTime(IJob job, Lock lock) { if (lock != null && lock.getLastLockTime() != null) { return DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format(lock.getLastLockTime()); } else { - return job.getLastFinishTime() == null ? null : DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format(job - .getLastFinishTime()); + return job.getLastFinishTime() == null ? null : DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format(job.getLastFinishTime()); } } - + @SuppressWarnings("unchecked") public static Map findSymmetricLogFile() { Enumeration appenders = org.apache.log4j.Logger.getRootLogger().getAllAppenders(); @@ -611,7 +589,6 @@ public static Map findSymmetricLogFile() { return null; } - static class SortedProperties extends Properties { private static final long serialVersionUID = 1L; diff --git a/symmetric-util/src/main/java/org/jumpmind/util/ZipBuilder.java b/symmetric-util/src/main/java/org/jumpmind/util/ZipBuilder.java new file mode 100644 index 0000000000..7eaad9c8c9 --- /dev/null +++ b/symmetric-util/src/main/java/org/jumpmind/util/ZipBuilder.java @@ -0,0 +1,118 @@ +/** + * Licensed to JumpMind Inc under one or more contributor + * license agreements. See the NOTICE file distributed + * with this work for additional information regarding + * copyright ownership. JumpMind Inc licenses this file + * to you under the GNU General Public License, version 3.0 (GPLv3) + * (the "License"); you may not use this file except in compliance + * with the License. + * + * You should have received a copy of the GNU General Public License, + * version 3.0 (GPLv3) along with this library; if not, see + * . + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jumpmind.util; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.jar.JarEntry; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +public class ZipBuilder { + + private File baseDir; + + private File[] sourceFiles; + + private File outputFile; + + public ZipBuilder(File baseDir, File outputFile, File[] sourceFiles) { + this.sourceFiles = sourceFiles; + this.outputFile = outputFile; + this.baseDir = baseDir; + } + + public void build() throws IOException { + this.outputFile.delete(); + if (outputFile.getParentFile() != null) { + outputFile.getParentFile().mkdirs(); + } + ZipOutputStream target = new ZipOutputStream(new FileOutputStream(outputFile)); + for (File file : sourceFiles) { + add(file, target); + } + target.close(); + } + + private String massageEntryName(File source) { + String name = source.getPath(); + if (baseDir != null && name.startsWith(baseDir.getPath())) { + if (name.length() > baseDir.getPath().length()) { + name = name.substring(baseDir.getPath().length() + 1); + } else { + name = ""; + } + } + + name = name.replace("\\","/"); + + if (name.equals("META-INF/MANIFEST.MF")) { + name = ""; + } + return name; + } + + private void add(File source, ZipOutputStream target) throws IOException { + BufferedInputStream in = null; + try { + if (source.isDirectory()) { + String name = massageEntryName(source); + if (name.trim().length() != 0) { + if (!name.endsWith("/")) { + name += "/"; + } + JarEntry entry = new JarEntry(name); + entry.setTime(source.lastModified()); + target.putNextEntry(entry); + target.closeEntry(); + } + for (File nestedFile : source.listFiles()) { + add(nestedFile, target); + } + } else { + ZipEntry entry = new ZipEntry(massageEntryName(source)); + entry.setTime(source.lastModified()); + target.putNextEntry(entry); + in = new BufferedInputStream(new FileInputStream(source)); + + byte[] buffer = new byte[1024]; + while (true) { + int count = in.read(buffer); + if (count == -1) { + break; + } + target.write(buffer, 0, count); + } + target.closeEntry(); + } + } finally { + try { + if (in != null) { + in.close(); + } + } catch (Exception ex) {} + } + } + +} \ No newline at end of file