diff --git a/activemq-broker/src/main/java/org/apache/activemq/util/IOHelper.java b/activemq-broker/src/main/java/org/apache/activemq/util/IOHelper.java index 9c4b6155ec..a623de90eb 100644 --- a/activemq-broker/src/main/java/org/apache/activemq/util/IOHelper.java +++ b/activemq-broker/src/main/java/org/apache/activemq/util/IOHelper.java @@ -16,18 +16,26 @@ */ package org.apache.activemq.util; -import java.io.*; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import java.util.Stack; /** - * + * */ public final class IOHelper { + protected static final int MAX_DIR_NAME_LENGTH; protected static final int MAX_FILE_NAME_LENGTH; private static final int DEFAULT_BUFFER_SIZE = 4096; + private IOHelper() { } @@ -62,18 +70,18 @@ public final class IOHelper { public static String toFileSystemDirectorySafeName(String name) { return toFileSystemSafeName(name, true, MAX_DIR_NAME_LENGTH); } - + public static String toFileSystemSafeName(String name) { return toFileSystemSafeName(name, false, MAX_FILE_NAME_LENGTH); } - + /** * Converts any string into a string that is safe to use as a file name. * The result will only include ascii characters and numbers, and the "-","_", and "." characters. * * @param name - * @param dirSeparators - * @param maxFileLength + * @param dirSeparators + * @param maxFileLength * @return */ public static String toFileSystemSafeName(String name,boolean dirSeparators,int maxFileLength) { @@ -147,7 +155,7 @@ public final class IOHelper { result &= fileToDelete.delete(); return result; } - + public static boolean deleteChildren(File parent) { if (parent == null || !parent.exists()) { return false; @@ -172,21 +180,20 @@ public final class IOHelper { } } } - + return result; } - - + public static void moveFile(File src, File targetDirectory) throws IOException { if (!src.renameTo(new File(targetDirectory, src.getName()))) { throw new IOException("Failed to move " + src + " to " + targetDirectory); } } - + public static void copyFile(File src, File dest) throws IOException { copyFile(src, dest, null); } - + public static void copyFile(File src, File dest, FilenameFilter filter) throws IOException { if (src.getCanonicalPath().equals(dest.getCanonicalPath()) == false) { if (src.isDirectory()) { @@ -209,7 +216,7 @@ public final class IOHelper { } } } - + static File getCopyParent(File from, File to, File src) { File result = null; File parent = src.getParentFile(); @@ -224,13 +231,13 @@ public final class IOHelper { } return result; } - + static List getFiles(File dir,FilenameFilter filter){ List result = new ArrayList(); getFiles(dir,result,filter); return result; } - + static void getFiles(File dir,List list,FilenameFilter filter) { if (!list.contains(dir)) { list.add(dir); @@ -245,14 +252,13 @@ public final class IOHelper { } } } - - + public static void copySingleFile(File src, File dest) throws IOException { FileInputStream fileSrc = new FileInputStream(src); FileOutputStream fileDest = new FileOutputStream(dest); copyInputStream(fileSrc, fileDest); } - + public static void copyInputStream(InputStream in, OutputStream out) throws IOException { byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; int len = in.read(buffer); @@ -263,19 +269,26 @@ public final class IOHelper { in.close(); out.close(); } - + static { - MAX_DIR_NAME_LENGTH = Integer.getInteger("MaximumDirNameLength",200); - MAX_FILE_NAME_LENGTH = Integer.getInteger("MaximumFileNameLength",64); + MAX_DIR_NAME_LENGTH = Integer.getInteger("MaximumDirNameLength", 200); + MAX_FILE_NAME_LENGTH = Integer.getInteger("MaximumFileNameLength", 64); + } + + public static int getMaxDirNameLength() { + return MAX_DIR_NAME_LENGTH; + } + + public static int getMaxFileNameLength() { + return MAX_FILE_NAME_LENGTH; } - public static void mkdirs(File dir) throws IOException { if (dir.exists()) { if (!dir.isDirectory()) { throw new IOException("Failed to create directory '" + dir +"', regular file already existed with that name"); } - + } else { if (!dir.mkdirs()) { throw new IOException("Failed to create directory '" + dir+"'"); diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/MultiKahaDBPersistenceAdapter.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/MultiKahaDBPersistenceAdapter.java index 30ee7a1027..0ac4e03a03 100644 --- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/MultiKahaDBPersistenceAdapter.java +++ b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/MultiKahaDBPersistenceAdapter.java @@ -124,6 +124,12 @@ public class MultiKahaDBPersistenceAdapter extends DestinationMap implements Per } private String nameFromDestinationFilter(ActiveMQDestination destination) { + + if (destination.getQualifiedName().length() > IOHelper.getMaxFileNameLength()) { + LOG.warn("Destination name is longer than 'MaximumFileNameLength' system property, " + + "potential problem with recovery can result from name truncation."); + } + return IOHelper.toFileSystemSafeName(destination.getQualifiedName()); } @@ -132,20 +138,24 @@ public class MultiKahaDBPersistenceAdapter extends DestinationMap implements Per ((XATransactionId)xid).getFormatId() == LOCAL_FORMAT_ID_MAGIC; } + @Override public void beginTransaction(ConnectionContext context) throws IOException { throw new IllegalStateException(); } + @Override public void checkpoint(final boolean sync) throws IOException { for (PersistenceAdapter persistenceAdapter : adapters) { persistenceAdapter.checkpoint(sync); } } + @Override public void commitTransaction(ConnectionContext context) throws IOException { throw new IllegalStateException(); } + @Override public MessageStore createQueueMessageStore(ActiveMQQueue destination) throws IOException { PersistenceAdapter persistenceAdapter = getMatchingPersistenceAdapter(destination); return transactionStore.proxy(persistenceAdapter.createTransactionStore(), persistenceAdapter.createQueueMessageStore(destination)); @@ -187,15 +197,18 @@ public class MultiKahaDBPersistenceAdapter extends DestinationMap implements Per } } + @Override public TopicMessageStore createTopicMessageStore(ActiveMQTopic destination) throws IOException { PersistenceAdapter persistenceAdapter = getMatchingPersistenceAdapter(destination); return transactionStore.proxy(persistenceAdapter.createTransactionStore(), persistenceAdapter.createTopicMessageStore(destination)); } + @Override public TransactionStore createTransactionStore() throws IOException { return transactionStore; } + @Override public void deleteAllMessages() throws IOException { for (PersistenceAdapter persistenceAdapter : adapters) { persistenceAdapter.deleteAllMessages(); @@ -204,6 +217,7 @@ public class MultiKahaDBPersistenceAdapter extends DestinationMap implements Per IOHelper.deleteChildren(getDirectory()); } + @Override public Set getDestinations() { Set results = new HashSet(); for (PersistenceAdapter persistenceAdapter : adapters) { @@ -212,6 +226,7 @@ public class MultiKahaDBPersistenceAdapter extends DestinationMap implements Per return results; } + @Override public long getLastMessageBrokerSequenceId() throws IOException { long maxId = -1; for (PersistenceAdapter persistenceAdapter : adapters) { @@ -220,6 +235,7 @@ public class MultiKahaDBPersistenceAdapter extends DestinationMap implements Per return maxId; } + @Override public long getLastProducerSequenceId(ProducerId id) throws IOException { long maxId = -1; for (PersistenceAdapter persistenceAdapter : adapters) { @@ -228,6 +244,7 @@ public class MultiKahaDBPersistenceAdapter extends DestinationMap implements Per return maxId; } + @Override public void removeQueueMessageStore(ActiveMQQueue destination) { PersistenceAdapter adapter = getMatchingPersistenceAdapter(destination); adapter.removeQueueMessageStore(destination); @@ -237,6 +254,7 @@ public class MultiKahaDBPersistenceAdapter extends DestinationMap implements Per } } + @Override public void removeTopicMessageStore(ActiveMQTopic destination) { PersistenceAdapter adapter = getMatchingPersistenceAdapter(destination); if (adapter instanceof KahaDBPersistenceAdapter) { @@ -263,22 +281,26 @@ public class MultiKahaDBPersistenceAdapter extends DestinationMap implements Per } } + @Override public void rollbackTransaction(ConnectionContext context) throws IOException { throw new IllegalStateException(); } + @Override public void setBrokerName(String brokerName) { for (PersistenceAdapter persistenceAdapter : adapters) { persistenceAdapter.setBrokerName(brokerName); } } + @Override public void setUsageManager(SystemUsage usageManager) { for (PersistenceAdapter persistenceAdapter : adapters) { persistenceAdapter.setUsageManager(usageManager); } } + @Override public long size() { long size = 0; for (PersistenceAdapter persistenceAdapter : adapters) { @@ -287,6 +309,7 @@ public class MultiKahaDBPersistenceAdapter extends DestinationMap implements Per return size; } + @Override public void start() throws Exception { Object result = this.chooseValue(matchAll); if (result != null) { @@ -373,12 +396,14 @@ public class MultiKahaDBPersistenceAdapter extends DestinationMap implements Per return adapter; } + @Override public void stop() throws Exception { for (PersistenceAdapter persistenceAdapter : adapters) { persistenceAdapter.stop(); } } + @Override public File getDirectory() { return this.directory; } @@ -388,6 +413,7 @@ public class MultiKahaDBPersistenceAdapter extends DestinationMap implements Per this.directory = directory; } + @Override public void setBrokerService(BrokerService brokerService) { for (KahaDBPersistenceAdapter persistenceAdapter : adapters) { persistenceAdapter.setBrokerService(brokerService);