Author: orudyy
Date: Thu Jul  2 13:30:52 2015
New Revision: 1688825

URL: http://svn.apache.org/r1688825
Log:
QPID-6614: Improve functionality around exposing log files and their content 
and add UI to browse and download log files (work by Lorenz Quack and Alex 
Rudyy)

Added:
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/LogFileDetails.java
      - copied, changed from r1688819, 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/virtualhostlogger/file/show.js
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/PathContent.java
      - copied, changed from r1688819, 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/logback/PathTypedContent.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/ZippedContent.java
      - copied, changed from r1688819, 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/logback/PathTypedContent.java
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/FileBrowser.js
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/logger/file/fileBrowser.html
      - copied, changed from r1688819, 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/logs/showLogFileDownloadDialog.html
Removed:
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/logback/PathTypedContent.java
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/log/LogFileDetails.java
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/log/LogFileHelper.java
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/LogFileServlet.java
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogFileListingServlet.java
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logs/LogFileDownloadDialog.js
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/logs/showLogFileDownloadDialog.html
Modified:
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLogger.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLoggerImpl.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/RollingFileAppenderFactory.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/VirtualHostFileLogger.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/VirtualHostFileLoggerImpl.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/logback/RolloverWatcher.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/SecurityManager.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/access/ObjectType.java
    
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/VirtualHostLoggerTest.java
    
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/logback/RolloverWatcherTest.java
    
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/security/SecurityManagerTest.java
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsServlet.java
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/common/CategoryTabExtension.js
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Logger.js
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/brokerlogger/file/show.js
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/brokerlogger/show.js
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/virtualhostlogger/file/show.js
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/virtualhostlogger/show.js
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logs/LogViewer.js
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/logs/showLogViewer.html
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/showLogger.html
    
qpid/java/trunk/systests/src/test/java/org/apache/qpid/systest/rest/acl/BrokerACLTest.java
    
qpid/java/trunk/systests/src/test/java/org/apache/qpid/systest/rest/acl/VirtualHostACLTest.java

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLogger.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLogger.java?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLogger.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLogger.java
 Thu Jul  2 13:30:52 2015
@@ -21,6 +21,7 @@
 package org.apache.qpid.server.logging;
 
 import java.util.Collection;
+import java.util.Set;
 
 import org.apache.qpid.server.model.BrokerLogger;
 import org.apache.qpid.server.model.DerivedAttribute;
@@ -57,8 +58,14 @@ public interface BrokerFileLogger<X exte
     String getLayout();
 
     @DerivedAttribute
-    Collection<String> getRolledFiles();
+    Collection<LogFileDetails> getLogFiles();
 
     @ManagedOperation(nonModifying = true)
     Content getFile(@Param(name = "fileName") String fileName);
+
+    @ManagedOperation(nonModifying = true)
+    Content getFiles(@Param(name = "fileName") Set<String> fileName);
+
+    @ManagedOperation(nonModifying = true)
+    Content getAllFiles();
 }

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLoggerImpl.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLoggerImpl.java?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLoggerImpl.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLoggerImpl.java
 Thu Jul  2 13:30:52 2015
@@ -20,9 +20,10 @@
  */
 package org.apache.qpid.server.logging;
 
-import java.nio.file.Path;
+import java.security.AccessControlException;
 import java.util.Collection;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 
@@ -36,12 +37,13 @@ import org.apache.qpid.server.model.Brok
 import org.apache.qpid.server.model.ManagedAttributeField;
 import org.apache.qpid.server.model.ManagedObjectFactoryConstructor;
 import org.apache.qpid.server.model.Content;
+import org.apache.qpid.server.model.Param;
 import org.apache.qpid.server.util.DaemonThreadFactory;
 
 public class BrokerFileLoggerImpl extends 
AbstractBrokerLogger<BrokerFileLoggerImpl> implements 
BrokerFileLogger<BrokerFileLoggerImpl>, FileLoggerSettings
 {
-    private final RolloverWatcher _rolloverWatcher;
-    private final ScheduledExecutorService _rolledPolicyExecutor;
+    private RolloverWatcher _rolloverWatcher;
+    private ScheduledExecutorService _rolledPolicyExecutor;
 
     @ManagedAttributeField
     private String _layout;
@@ -57,15 +59,20 @@ public class BrokerFileLoggerImpl extend
     private int _maxHistory;
     @ManagedAttributeField
     private String _maxFileSize;
-    private Collection<String> _rolledFiles;
-    private Path _baseFolder;
 
     @ManagedObjectFactoryConstructor
     protected BrokerFileLoggerImpl(final Map<String, Object> attributes, 
Broker<?> broker)
     {
         super(attributes, broker);
-        _rolloverWatcher = new RolloverWatcher();
+    }
+
+    @Override
+    protected void postResolveChildren()
+    {
+        _rolloverWatcher = new RolloverWatcher(getFileName());
         _rolledPolicyExecutor = Executors.newSingleThreadScheduledExecutor(new 
DaemonThreadFactory("RolledFileScanner-" + getName()));
+
+        super.postResolveChildren();
     }
 
     @Override
@@ -109,16 +116,44 @@ public class BrokerFileLoggerImpl extend
     {
         return _layout;
     }
+
     @Override
-    public Collection<String> getRolledFiles()
+    public Collection<LogFileDetails> getLogFiles()
     {
-        return _rolloverWatcher.getRolledFiles();
+        return _rolloverWatcher.getLogFileDetails();
     }
 
     @Override
     public Content getFile(final String fileName)
     {
-        return _rolloverWatcher.getTypedContent(fileName, 
_fileName.equals(fileName));
+        if (!getSecurityManager().authoriseLogsAccess(this))
+        {
+            throw new AccessControlException("Permission denied to access log 
content");
+        }
+
+        return _rolloverWatcher.getFileContent(fileName);
+    }
+
+    @Override
+    public Content getFiles(@Param(name = "fileName") Set<String> fileName)
+    {
+        if (!getSecurityManager().authoriseLogsAccess(this))
+        {
+            throw new AccessControlException("Permission denied to access log 
content");
+        }
+
+        return _rolloverWatcher.getFilesAsZippedContent(fileName);
+    }
+
+    @Override
+    public Content getAllFiles()
+    {
+        if (!getSecurityManager().authoriseLogsAccess(this))
+        {
+            throw new AccessControlException("Permission denied to access log 
content");
+        }
+
+        return _rolloverWatcher.getAllFilesAsZippedContent();
     }
 
     @Override

Copied: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/LogFileDetails.java
 (from r1688819, 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/virtualhostlogger/file/show.js)
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/LogFileDetails.java?p2=qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/LogFileDetails.java&p1=qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/virtualhostlogger/file/show.js&r1=1688819&r2=1688825&rev=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/virtualhostlogger/file/show.js
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/LogFileDetails.java
 Thu Jul  2 13:30:52 2015
@@ -18,19 +18,37 @@
  * under the License.
  *
  */
-define(["qpid/common/util",
-    "dojo/query",
-    "dojox/html/entities",
-    "dojo/text!logger/file/show.html",
-    "qpid/common/TypeTabExtension",
-    "dojo/domReady!"],
-  function (util, query, entities, template, TypeTabExtension)
-  {
-    function VirtualHostFileLogger(params)
+package org.apache.qpid.server.logging;
+
+import org.apache.qpid.server.model.ManagedAttributeValue;
+import org.apache.qpid.server.model.ManagedAttributeValueType;
+
+@ManagedAttributeValueType
+public class LogFileDetails implements ManagedAttributeValue
+{
+    private final String _name;
+    private final long _lastModified;
+    private final long _size;
+
+    public LogFileDetails(String name, long lastModified, long size)
+    {
+        _name = name;
+        _lastModified = lastModified;
+        _size = size;
+    }
+
+    public String getName()
     {
-      TypeTabExtension.call(this, params.containerNode, template, 
"VirtualHostLogger", "File", params.metadata, params.data);
+        return _name;
     }
 
-    return util.extend(VirtualHostFileLogger, TypeTabExtension);
-  }
-);
+    public long getLastModified()
+    {
+        return _lastModified;
+    }
+
+    public long getSize()
+    {
+        return _size;
+    }
+}

Copied: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/PathContent.java
 (from r1688819, 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/logback/PathTypedContent.java)
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/PathContent.java?p2=qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/PathContent.java&p1=qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/logback/PathTypedContent.java&r1=1688819&r2=1688825&rev=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/logback/PathTypedContent.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/PathContent.java
 Thu Jul  2 13:30:52 2015
@@ -18,7 +18,7 @@
  * under the License.
  *
  */
-package org.apache.qpid.server.logging.logback;
+package org.apache.qpid.server.logging;
 
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -30,14 +30,14 @@ import org.apache.qpid.server.model.Cust
 import org.apache.qpid.server.model.RestContentHeader;
 import org.apache.qpid.server.model.Content;
 
-public class PathTypedContent implements Content, CustomRestHeaders
+public class PathContent implements Content, CustomRestHeaders
 {
     private final Path _path;
     private final String _contentType;
     private final String _disposition;
     private final long _contentSize;
 
-    public PathTypedContent(Path path, String contentType)
+    public PathContent(Path path, String contentType)
     {
         _path = path;
         _contentType = contentType;

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/RollingFileAppenderFactory.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/RollingFileAppenderFactory.java?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/RollingFileAppenderFactory.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/RollingFileAppenderFactory.java
 Thu Jul  2 13:30:52 2015
@@ -31,6 +31,7 @@ import ch.qos.logback.core.rolling.Rolli
 import ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP;
 import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy;
 import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
+import ch.qos.logback.core.rolling.TriggeringPolicy;
 import org.apache.qpid.server.logging.logback.RollingPolicyDecorator;
 
 public class RollingFileAppenderFactory
@@ -42,34 +43,38 @@ public class RollingFileAppenderFactory
         appender.setAppend(true);
         appender.setContext(loggerContext);
 
-        RollingPolicyBase policy;
+        TriggeringPolicy triggeringPolicy;
+        RollingPolicyBase rollingPolicy;
         if(fileLoggerSettings.isRollDaily())
         {
-            DailyTriggeringPolicy triggeringPolicy = new 
DailyTriggeringPolicy(fileLoggerSettings.isRollOnRestart(), 
fileLoggerSettings.getMaxFileSize());
-            triggeringPolicy.setContext(loggerContext);
-            TimeBasedRollingPolicy<ILoggingEvent> rollingPolicy = new 
TimeBasedRollingPolicy<>();
-            rollingPolicy.setMaxHistory(fileLoggerSettings.getMaxHistory());
-            
rollingPolicy.setTimeBasedFileNamingAndTriggeringPolicy(triggeringPolicy);
-            rollingPolicy.setFileNamePattern(fileLoggerSettings.getFileName() 
+ ".%d{yyyy-MM-dd}.%i" + (fileLoggerSettings.isCompressOldFiles()
+            DailyTriggeringPolicy dailyTriggeringPolicy = new 
DailyTriggeringPolicy(fileLoggerSettings.isRollOnRestart(), 
fileLoggerSettings.getMaxFileSize());
+            dailyTriggeringPolicy.setContext(loggerContext);
+            TimeBasedRollingPolicy<ILoggingEvent> timeBasedRollingPolicy = new 
TimeBasedRollingPolicy<>();
+            
timeBasedRollingPolicy.setMaxHistory(fileLoggerSettings.getMaxHistory());
+            
timeBasedRollingPolicy.setTimeBasedFileNamingAndTriggeringPolicy(dailyTriggeringPolicy);
+            
timeBasedRollingPolicy.setFileNamePattern(fileLoggerSettings.getFileName() + 
".%d{yyyy-MM-dd}.%i" + (fileLoggerSettings.isCompressOldFiles()
                     ? ".gz"
                     : ""));
-            policy = rollingPolicy;
+            rollingPolicy = timeBasedRollingPolicy;
+            triggeringPolicy = dailyTriggeringPolicy;
         }
         else
         {
             SizeTriggeringPolicy sizeTriggeringPolicy = new 
SizeTriggeringPolicy(fileLoggerSettings.isRollOnRestart(), 
fileLoggerSettings.getMaxFileSize());
             sizeTriggeringPolicy.setContext(loggerContext);
-            SimpleRollingPolicy rollingPolicy = new 
SimpleRollingPolicy(fileLoggerSettings.getMaxHistory());
-            rollingPolicy.setFileNamePattern(fileLoggerSettings.getFileName() 
+ ".%i" + (fileLoggerSettings.isCompressOldFiles() ? ".gz" : ""));
-            appender.setTriggeringPolicy(sizeTriggeringPolicy);
-            sizeTriggeringPolicy.start();
-            policy = rollingPolicy;
+            SimpleRollingPolicy simpleRollingPolicy = new 
SimpleRollingPolicy(fileLoggerSettings.getMaxHistory());
+            
simpleRollingPolicy.setFileNamePattern(fileLoggerSettings.getFileName() + ".%i" 
+ (fileLoggerSettings.isCompressOldFiles() ? ".gz" : ""));
+            rollingPolicy = simpleRollingPolicy;
+            triggeringPolicy = sizeTriggeringPolicy;
         }
-        policy.setContext(loggerContext);
-        RollingPolicyDecorator decorator = new RollingPolicyDecorator(policy, 
fileLoggerSettings.getRolloverListener(), 
fileLoggerSettings.getExecutorService());
+
+        rollingPolicy.setContext(loggerContext);
+        RollingPolicyDecorator decorator = new 
RollingPolicyDecorator(rollingPolicy, fileLoggerSettings.getRolloverListener(), 
fileLoggerSettings.getExecutorService());
         decorator.setParent(appender);
         appender.setRollingPolicy(decorator);
+        appender.setTriggeringPolicy(triggeringPolicy);
         decorator.start();
+        triggeringPolicy.start();
 
         final PatternLayoutEncoder encoder = new PatternLayoutEncoder();
         encoder.setPattern(fileLoggerSettings.getLayout());

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/VirtualHostFileLogger.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/VirtualHostFileLogger.java?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/VirtualHostFileLogger.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/VirtualHostFileLogger.java
 Thu Jul  2 13:30:52 2015
@@ -22,6 +22,8 @@ package org.apache.qpid.server.logging;
 
 
 import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
 
 import org.apache.qpid.server.model.DerivedAttribute;
 import org.apache.qpid.server.model.ManagedAttribute;
@@ -59,8 +61,14 @@ public interface VirtualHostFileLogger<X
     String getLayout();
 
     @DerivedAttribute
-    Collection<String> getRolledFiles();
+    Collection<LogFileDetails> getLogFiles();
 
     @ManagedOperation(nonModifying = true)
     Content getFile(@Param(name = "fileName") String fileName);
+
+    @ManagedOperation(nonModifying = true)
+    Content getFiles(@Param(name = "fileName") Set<String> fileName);
+
+    @ManagedOperation(nonModifying = true)
+    Content getAllFiles();
 }

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/VirtualHostFileLoggerImpl.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/VirtualHostFileLoggerImpl.java?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/VirtualHostFileLoggerImpl.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/VirtualHostFileLoggerImpl.java
 Thu Jul  2 13:30:52 2015
@@ -20,9 +20,10 @@
  */
 package org.apache.qpid.server.logging;
 
-import java.security.Principal;
+import java.security.AccessControlException;
 import java.util.Collection;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 
@@ -35,14 +36,14 @@ import org.apache.qpid.server.logging.lo
 import org.apache.qpid.server.model.ManagedAttributeField;
 import org.apache.qpid.server.model.ManagedObjectFactoryConstructor;
 import org.apache.qpid.server.model.Content;
+import org.apache.qpid.server.model.Param;
 import org.apache.qpid.server.model.VirtualHost;
 import org.apache.qpid.server.util.DaemonThreadFactory;
 
 public class VirtualHostFileLoggerImpl extends 
AbstractVirtualHostLogger<VirtualHostFileLoggerImpl> implements 
VirtualHostFileLogger<VirtualHostFileLoggerImpl>, FileLoggerSettings
 {
-    private final Principal _principal;
-    private final RolloverWatcher _rolloverWatcher;
-    private final ScheduledExecutorService _rolledPolicyExecutor;
+    private RolloverWatcher _rolloverWatcher;
+    private ScheduledExecutorService _rolledPolicyExecutor;
 
     @ManagedAttributeField
     private String _layout;
@@ -65,9 +66,15 @@ public class VirtualHostFileLoggerImpl e
     protected VirtualHostFileLoggerImpl(final Map<String, Object> attributes, 
VirtualHost<?,?,?> virtualHost)
     {
         super(attributes, virtualHost);
-        _principal = virtualHost.getPrincipal();
-        _rolloverWatcher = new RolloverWatcher();
+    }
+
+    @Override
+    protected void postResolveChildren()
+    {
+        _rolloverWatcher = new RolloverWatcher(getFileName());
         _rolledPolicyExecutor = Executors.newSingleThreadScheduledExecutor(new 
DaemonThreadFactory("RolledFileScanner-" + getName()));
+
+        super.postResolveChildren();
     }
 
     @Override
@@ -113,15 +120,43 @@ public class VirtualHostFileLoggerImpl e
     }
 
     @Override
-    public Collection<String> getRolledFiles()
+    public Collection<LogFileDetails> getLogFiles()
     {
-        return _rolloverWatcher.getRolledFiles();
+        return _rolloverWatcher.getLogFileDetails();
     }
 
     @Override
     public Content getFile(final String fileName)
     {
-        return _rolloverWatcher.getTypedContent(fileName, 
_fileName.equals(fileName));
+        if (!getSecurityManager().authoriseLogsAccess(this))
+        {
+            throw new AccessControlException("Permission denied to access log 
content");
+        }
+
+        return _rolloverWatcher.getFileContent(fileName);
+    }
+
+    @Override
+    public Content getFiles(@Param(name = "fileName") Set<String> fileName)
+    {
+        if (!getSecurityManager().authoriseLogsAccess(this))
+        {
+            throw new AccessControlException("Permission denied to access log 
content");
+        }
+
+        return _rolloverWatcher.getFilesAsZippedContent(fileName);
+    }
+
+
+    @Override
+    public Content getAllFiles()
+    {
+        if (!getSecurityManager().authoriseLogsAccess(this))
+        {
+            throw new AccessControlException("Permission denied to access log 
content");
+        }
+
+        return _rolloverWatcher.getAllFilesAsZippedContent();
     }
 
     @Override

Copied: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/ZippedContent.java
 (from r1688819, 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/logback/PathTypedContent.java)
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/ZippedContent.java?p2=qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/ZippedContent.java&p1=qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/logback/PathTypedContent.java&r1=1688819&r2=1688825&rev=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/logback/PathTypedContent.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/ZippedContent.java
 Thu Jul  2 13:30:52 2015
@@ -18,61 +18,74 @@
  * under the License.
  *
  */
-package org.apache.qpid.server.logging.logback;
+package org.apache.qpid.server.logging;
 
-import java.io.FileNotFoundException;
+import java.io.File;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.text.Format;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
 
+import org.apache.qpid.server.model.Content;
 import org.apache.qpid.server.model.CustomRestHeaders;
 import org.apache.qpid.server.model.RestContentHeader;
-import org.apache.qpid.server.model.Content;
 
-public class PathTypedContent implements Content, CustomRestHeaders
+public class ZippedContent implements Content, CustomRestHeaders
 {
-    private final Path _path;
-    private final String _contentType;
+    private static final Format FORMAT =  new 
SimpleDateFormat("YYYY-MM-dd-HHmmss");
+    private static final String DISPOSITION =  "attachment; 
filename=\"log-files-%s.zip\"";
+
+    private final Map<String, Path> _paths;
     private final String _disposition;
-    private final long _contentSize;
 
-    public PathTypedContent(Path path, String contentType)
+
+    public ZippedContent(Map<String, Path> paths)
     {
-        _path = path;
-        _contentType = contentType;
-        _disposition = _path == null ? "attachment" : "attachment; 
filename=\"" + _path.getFileName().toString() + "\"";
-        _contentSize = _path == null ? 0 : _path.toFile().length();
+        _paths = paths;
+        _disposition = String.format(DISPOSITION, FORMAT.format(new Date()));
     }
 
-    @RestContentHeader("Content-Type")
-    public String getContentType()
+    @Override
+    public void write(OutputStream outputStream) throws IOException
     {
-        return _contentType;
+        try(ZipOutputStream out = new ZipOutputStream(outputStream))
+        {
+            for (Map.Entry<String, Path> entry: _paths.entrySet())
+            {
+                addLogFileEntry(entry.getKey(), entry.getValue(), out);
+            }
+        }
     }
 
-    @RestContentHeader("Content-Length")
-    public long getContentLength()
+    private void addLogFileEntry(String zipEntryName, Path path, 
ZipOutputStream out) throws IOException
     {
-        return _contentSize;
+        File file = path.toFile();
+        if (file.exists())
+        {
+            ZipEntry entry = new ZipEntry(zipEntryName);
+            entry.setSize(file.length());
+            out.putNextEntry(entry);
+            Files.copy(path, out);
+            out.closeEntry();
+        }
+        out.flush();
     }
 
-    @RestContentHeader("Content-Disposition")
-    public String getContentDisposition()
+    @RestContentHeader("Content-Type")
+    public String getContentType()
     {
-        return _disposition;
+        return "application/x-zip";
     }
 
-    @Override
-    public void write(OutputStream outputStream) throws IOException
+    @RestContentHeader("Content-Disposition")
+    public String getContentDisposition()
     {
-        if (_path != null && _path.toFile().exists())
-        {
-            Files.copy(_path, outputStream);
-        }
-        else
-        {
-            throw new FileNotFoundException();
-        }
+        return _disposition;
     }
 }

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/logback/RolloverWatcher.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/logback/RolloverWatcher.java?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/logback/RolloverWatcher.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/logback/RolloverWatcher.java
 Thu Jul  2 13:30:52 2015
@@ -22,17 +22,30 @@ package org.apache.qpid.server.logging.l
 
 import java.io.File;
 import java.nio.file.Path;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.apache.qpid.server.logging.LogFileDetails;
+import org.apache.qpid.server.logging.PathContent;
+import org.apache.qpid.server.logging.ZippedContent;
+import org.apache.qpid.server.model.Content;
 
 public class RolloverWatcher implements RollingPolicyDecorator.RolloverListener
 {
+    private final Path _activeFilePath;
     private volatile Collection<String> _rolledFiles;
     private volatile Path _baseFolder;
 
-    public RolloverWatcher()
+    public RolloverWatcher(final String activeFileName)
     {
+        _activeFilePath = new File(activeFileName).toPath();
         _rolledFiles = Collections.emptyList();
     }
 
@@ -43,23 +56,30 @@ public class RolloverWatcher implements
         _baseFolder = baseFolder;
     }
 
-    public PathTypedContent getTypedContent(String fileName, boolean 
activeFile)
+    public PathContent getFileContent(String fileName)
     {
         if (fileName == null)
         {
             throw new IllegalArgumentException("File name cannot be null");
         }
 
+        Path path = getPath(fileName);
+        return new PathContent(path, getContentType(fileName));
+    }
+
+    private Path getPath(String fileName)
+    {
         Path path = null;
-        if (activeFile)
+        File active = _activeFilePath.toFile();
+        if (fileName.equals(active.getName()))
         {
-            path =  new File(fileName).toPath();
+            path =  active.toPath();
         }
         else if (_rolledFiles.contains(fileName))
         {
             path = _baseFolder.resolve(fileName);
         }
-        return new PathTypedContent(path, getContentType(fileName));
+        return path;
     }
 
     public Collection<String> getRolledFiles()
@@ -67,6 +87,44 @@ public class RolloverWatcher implements
         return _rolledFiles;
     }
 
+    public List<LogFileDetails> getLogFileDetails()
+    {
+        List<LogFileDetails> results = new ArrayList<>();
+        results.add(getFileDetails(_activeFilePath));
+        List<String> rolledFiles = new ArrayList<>(_rolledFiles);
+        for (String fileName : rolledFiles)
+        {
+            Path file = _baseFolder.resolve(fileName);
+            LogFileDetails details = getFileDetails(file);
+            results.add(details);
+        }
+        return results;
+    }
+
+    private LogFileDetails getFileDetails(Path path)
+    {
+        File file = path.toFile();
+        return new LogFileDetails(getDisplayName(path), file.lastModified(), 
file.length());
+    }
+
+    private String getDisplayName(Path path)
+    {
+        String displayName = path.getFileName().toString();
+        if (!_activeFilePath.equals(path) && (_baseFolder != null))
+        {
+            try
+            {
+                displayName = _baseFolder.relativize(path).toString();
+            }
+            catch (IllegalArgumentException e)
+            {
+                // active file might not be relative to root
+                // returning a file name
+            }
+        }
+        return displayName;
+    }
+
     public String getContentType(String fileName)
     {
         String fileNameLower = fileName.toLowerCase();
@@ -83,4 +141,27 @@ public class RolloverWatcher implements
             return "text/plain";
         }
     }
+
+    public ZippedContent getFilesAsZippedContent(Set<String> fileNames)
+    {
+        Map<String, Path> paths = new TreeMap<>();
+        for (String name: fileNames)
+        {
+            Path filePath = getPath(name);
+            if (filePath != null)
+            {
+                paths.put(name, filePath);
+            }
+        }
+
+        return new ZippedContent(paths);
+    }
+
+    public ZippedContent getAllFilesAsZippedContent()
+    {
+        Set<String> fileNames = new HashSet<>(_rolledFiles);
+        fileNames.add(getDisplayName(_activeFilePath));
+
+        return getFilesAsZippedContent(fileNames);
+    }
 }

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/SecurityManager.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/SecurityManager.java?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/SecurityManager.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/SecurityManager.java
 Thu Jul  2 13:30:52 2015
@@ -633,13 +633,16 @@ public class SecurityManager
         }
     }
 
-    public boolean authoriseLogsAccess()
+    public boolean authoriseLogsAccess(ConfiguredObject configuredObject)
     {
+        Class<? extends ConfiguredObject> categoryClass = 
configuredObject.getCategoryClass();
+        final ObjectType objectType = 
getACLObjectTypeManagingConfiguredObjectOfCategory(categoryClass);
+        final ObjectProperties objectProperties = objectType == BROKER ? 
ObjectProperties.EMPTY : new 
ObjectProperties((String)configuredObject.getAttribute(ConfiguredObject.NAME));
         return checkAllPlugins(new AccessCheck()
         {
             Result allowed(AccessControl plugin)
             {
-                return plugin.authorise(ACCESS_LOGS, BROKER, 
ObjectProperties.EMPTY);
+                return plugin.authorise(ACCESS_LOGS, objectType, 
objectProperties);
             }
         });
     }

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/access/ObjectType.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/access/ObjectType.java?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/access/ObjectType.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/access/ObjectType.java
 Thu Jul  2 13:30:52 2015
@@ -43,7 +43,7 @@ public enum ObjectType
 {
     ALL(Operation.ALL),
     VIRTUALHOSTNODE(Operation.ALL, CREATE, DELETE, UPDATE),
-    VIRTUALHOST(Operation.ALL, ACCESS, CREATE, DELETE, UPDATE),
+    VIRTUALHOST(Operation.ALL, ACCESS, CREATE, DELETE, UPDATE, ACCESS_LOGS),
     MANAGEMENT(Operation.ALL, ACCESS),
     QUEUE(Operation.ALL, CREATE, DELETE, PURGE, CONSUME, UPDATE),
     EXCHANGE(Operation.ALL, ACCESS, CREATE, DELETE, BIND, UNBIND, PUBLISH, 
UPDATE),

Modified: 
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/VirtualHostLoggerTest.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/VirtualHostLoggerTest.java?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/VirtualHostLoggerTest.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/VirtualHostLoggerTest.java
 Thu Jul  2 13:30:52 2015
@@ -25,12 +25,15 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import java.io.File;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.Appender;
 import org.apache.qpid.server.store.DurableConfigurationStore;
+import org.apache.qpid.util.FileUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -53,6 +56,7 @@ public class VirtualHostLoggerTest  exte
 {
     private VirtualHost<?,?,?> _virtualHost;
     private TaskExecutor _taskExecutor;
+    private File _baseFolder;
     private File _logFile;
 
     @Override
@@ -94,10 +98,11 @@ public class VirtualHostLoggerTest  exte
         _virtualHost = new TestMemoryVirtualHost(attributes, node);
         _virtualHost.open();
 
-        _logFile = new File(TMP_FOLDER, "tmp-virtual-host.log." + 
System.currentTimeMillis());
-        if (_logFile.exists())
+        _baseFolder = new File(TMP_FOLDER, "test-sub-folder");
+        _logFile = new File(_baseFolder, "tmp-virtual-host.log." + 
System.currentTimeMillis());
+        if (_baseFolder.exists())
         {
-            assertTrue(String.format("Log file '%s' is not deleted in setUp", 
_logFile.getPath()), _logFile.delete());
+            FileUtils.delete(_baseFolder, true);
         }
     }
 
@@ -108,9 +113,9 @@ public class VirtualHostLoggerTest  exte
         {
             _virtualHost.close();
             _taskExecutor.stopImmediately();
-            if (_logFile != null && _logFile.exists())
+            if (_baseFolder != null && _baseFolder.exists())
             {
-                _logFile.delete();
+                FileUtils.delete(_baseFolder, true);
             }
         }
         finally
@@ -119,13 +124,28 @@ public class VirtualHostLoggerTest  exte
         }
     }
 
-    public void testAddLogger()
+    public void testAddLoggerWithDefaultSettings()
     {
         VirtualHostLogger logger = createVirtualHostLogger();
 
         assertTrue("Unexpected logger created " + logger, logger instanceof 
VirtualHostFileLogger);
         assertEquals("Unexpected log file", _logFile.getPath(), 
((VirtualHostFileLogger<?>) logger).getFileName());
         assertEquals("Unexpected state on creation", State.ACTIVE, 
logger.getState());
+        assertTrue("Log file does not exists", _logFile.exists());
+
+        Appender<ILoggingEvent> appender = ((ch.qos.logback.classic.Logger) 
LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME))
+                .getAppender(logger.getName());
+        assertTrue("Appender was not started", appender.isStarted());
+    }
+
+    public void testAddLoggerWithRollDailyOn()
+    {
+        VirtualHostLogger logger = 
createVirtualHostLogger(Collections.<String, Object>singletonMap("rollDaily", 
true));
+
+        assertTrue("Unexpected logger created " + logger, logger instanceof 
VirtualHostFileLogger);
+        assertEquals("Unexpected log file", _logFile.getPath(), 
((VirtualHostFileLogger<?>) logger).getFileName());
+        assertEquals("Unexpected state on creation", State.ACTIVE, 
logger.getState());
+        assertTrue("Log file does not exists", _logFile.exists());
 
         Appender<ILoggingEvent> appender = ((ch.qos.logback.classic.Logger) 
LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME))
                 .getAppender(logger.getName());
@@ -168,10 +188,29 @@ public class VirtualHostLoggerTest  exte
         assertNull("Appender was not deleted", appender);
     }
 
+    public void testGetLogFiles()
+    {
+        VirtualHostFileLogger logger = 
(VirtualHostFileLogger)createVirtualHostLogger();
+
+        Collection<LogFileDetails> logFileDetails = logger.getLogFiles();
+        assertEquals("File details should not be empty", 1, 
logFileDetails.size());
+
+        for(LogFileDetails logFile : logFileDetails)
+        {
+            assertEquals("Unexpected log name", _logFile.getName(), 
logFile.getName());
+            assertEquals("Unexpected log name", 0, logFile.getSize());
+            assertEquals("Unexpected log name", _logFile.lastModified(), 
logFile.getLastModified());
+        }
+    }
 
     private VirtualHostLogger createVirtualHostLogger()
     {
-        Map<String, Object> attributes = new HashMap<>();
+        return createVirtualHostLogger(Collections.<String,Object>emptyMap());
+    }
+
+    private VirtualHostLogger createVirtualHostLogger(Map<String, Object> 
additionalAttributes)
+    {
+        Map<String, Object> attributes = new HashMap<>(additionalAttributes);
         attributes.put(VirtualHostLogger.NAME, getTestName());
         attributes.put(ConfiguredObject.TYPE, VirtualHostFileLogger.TYPE);
         attributes.put(VirtualHostFileLogger.FILE_NAME, _logFile.getPath());

Modified: 
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/logback/RolloverWatcherTest.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/logback/RolloverWatcherTest.java?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/logback/RolloverWatcherTest.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/logback/RolloverWatcherTest.java
 Thu Jul  2 13:30:52 2015
@@ -21,14 +21,15 @@
 
 package org.apache.qpid.server.logging.logback;
 
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
+import java.io.*;
 import java.nio.file.Path;
-import java.util.Arrays;
-import java.util.HashSet;
-
+import java.util.*;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import org.apache.qpid.server.logging.LogFileDetails;
+import org.apache.qpid.server.logging.PathContent;
+import org.apache.qpid.server.logging.ZippedContent;
 import org.apache.qpid.server.model.Content;
 import org.apache.qpid.test.utils.QpidTestCase;
 import org.apache.qpid.test.utils.TestFileUtils;
@@ -38,12 +39,14 @@ public class RolloverWatcherTest extends
 {
     private RolloverWatcher _rolloverWatcher;
     private File _baseFolder;
+    private File _activeFile;
 
     public void setUp() throws Exception
     {
         super.setUp();
-        _rolloverWatcher = new RolloverWatcher();
         _baseFolder = TestFileUtils.createTestDirectory("rollover", true);
+        _activeFile = new File(_baseFolder, "test.log");
+        _rolloverWatcher = new RolloverWatcher(_activeFile.toString());
     }
 
     @Override
@@ -70,21 +73,20 @@ public class RolloverWatcherTest extends
     {
         _rolloverWatcher.onRollover(_baseFolder.toPath(), new String[]{});
 
-        final File activeFile = new File(_baseFolder, "test.log");
-        TestFileUtils.saveTextContentInFile("test", activeFile);
-        PathTypedContent content = 
_rolloverWatcher.getTypedContent(activeFile.getAbsolutePath(), true);
+        TestFileUtils.saveTextContentInFile("test", _activeFile);
+        PathContent content = 
_rolloverWatcher.getFileContent(_activeFile.getName());
 
         assertEquals("Unexpected content type", "text/plain", 
content.getContentType());
         assertEquals("Unexpected data", "test", readContent(content));
         assertEquals("Unexpected size", 4, content.getContentLength());
-        assertEquals("Unexpected content disposition", "attachment; 
filename=\"" + activeFile.getName().toString() + "\"", 
content.getContentDisposition());
+        assertEquals("Unexpected content disposition", "attachment; 
filename=\"" + _activeFile.getName().toString() + "\"", 
content.getContentDisposition());
     }
 
     public void testGetTypedForNullFile() throws Exception
     {
         try
         {
-            _rolloverWatcher.getTypedContent(null, true);
+            _rolloverWatcher.getFileContent(null);
             fail("IllegalArgumentException is expected for null file name");
         }
         catch (IllegalArgumentException e)
@@ -100,7 +102,7 @@ public class RolloverWatcherTest extends
 
         TestFileUtils.saveTextContentInFile("test.gz", new File(_baseFolder, 
"test1.gz"));
 
-        PathTypedContent content = 
_rolloverWatcher.getTypedContent("test1.gz", false);
+        PathContent content = _rolloverWatcher.getFileContent("test1.gz");
 
         assertEquals("Unexpected content type", "application/x-gzip", 
content.getContentType());
         assertEquals("Unexpected data", "test.gz", readContent(content));
@@ -114,7 +116,7 @@ public class RolloverWatcherTest extends
         Path baseFolder = new File(getTestName()).toPath();
         _rolloverWatcher.onRollover(baseFolder, files);
 
-        PathTypedContent content = 
_rolloverWatcher.getTypedContent("test3.zip", false);
+        PathContent content = _rolloverWatcher.getFileContent("test3.zip");
 
         assertEquals("Unexpected content type", "application/x-zip", 
content.getContentType());
         assertEquals("Unexpected content disposition", "attachment", 
content.getContentDisposition());
@@ -137,6 +139,117 @@ public class RolloverWatcherTest extends
         assertEquals("Unexpected content type for zip file", 
"application/x-zip", _rolloverWatcher.getContentType("test.zip"));
     }
 
+    public void testGetLogFileDetails() throws Exception
+    {
+        String[] files = createTestRolledFilesAndNotifyWatcher();
+
+        List<LogFileDetails> logFileDetails = 
_rolloverWatcher.getLogFileDetails();
+        final int expectedNumberOfEntries = files.length + 1; // add one for 
the active file
+        assertEquals("getLogFileDetails returned unexpected number of 
entries", expectedNumberOfEntries, logFileDetails.size());
+
+        List<String> expectedFiles = new ArrayList<>(Arrays.asList(files));
+        expectedFiles.add(_activeFile.getName());
+
+        for (String expectedFileName : expectedFiles)
+        {
+            boolean found = false;
+            for (LogFileDetails details : logFileDetails)
+            {
+                if (details.getName().equals(expectedFileName))
+                {
+                    found = true;
+                    final File file = new File(_baseFolder, expectedFileName);
+                    assertEquals("FileDetail for \"" + expectedFileName + "\" 
has unexpected lastModified time", file.lastModified(), 
details.getLastModified());
+                    assertEquals("FileDetail for \"" + expectedFileName + "\" 
has unexpected size", file.length(), details.getSize());
+                    break;
+                }
+            }
+            assertTrue("File \"" + expectedFileName + "\" expected but not 
found in logFileDetails", found);
+        }
+    }
+
+    public void testGetFilesAsZippedContentWithNonLogFile() throws Exception
+    {
+        String[] fileNames = createTestRolledFilesAndNotifyWatcher();
+        String nonLogFileName = "nonLogFile.txt";
+        TestFileUtils.saveTextContentInFile(nonLogFileName, new 
File(_baseFolder, nonLogFileName));
+
+        String[] requestedFiles = new String[]{ fileNames[0], fileNames[2], 
nonLogFileName };
+        String[] expectedFiles = new String[]{ fileNames[0], fileNames[2] };
+
+        ZippedContent content = _rolloverWatcher.getFilesAsZippedContent(new 
HashSet<>(Arrays.asList(requestedFiles)));
+        assertZippedContent(expectedFiles, content);
+    }
+
+    public void testGetFilesAsZippedContent() throws Exception
+    {
+        String[] fileNames = createTestRolledFilesAndNotifyWatcher();
+        String[] requestedFiles = new String[]{ fileNames[0], fileNames[2] };
+
+        ZippedContent content = _rolloverWatcher.getFilesAsZippedContent(new 
HashSet<>(Arrays.asList(requestedFiles)));
+        assertZippedContent(requestedFiles, content);
+    }
+
+    public void testGetFilesAsZippedContentWithNonExistingFile() throws 
Exception
+    {
+        String[] fileNames = createTestRolledFilesAndNotifyWatcher();
+        new File(_baseFolder, fileNames[2]).delete();
+        String[] requestedFiles = new String[]{ fileNames[0], fileNames[2] };
+        String[] expectedFiles = new String[]{ fileNames[0] };
+
+        ZippedContent content = _rolloverWatcher.getFilesAsZippedContent(new 
HashSet<>(Arrays.asList(requestedFiles)));
+        assertZippedContent(expectedFiles, content);
+    }
+
+    public void testGetAllFilesAsZippedContent() throws Exception
+    {
+        String[] fileNames = createTestRolledFilesAndNotifyWatcher();
+
+        ZippedContent content = _rolloverWatcher.getAllFilesAsZippedContent();
+        assertZippedContent(fileNames, content);
+    }
+
+    private String[] createTestRolledFilesAndNotifyWatcher()
+    {
+        String[] fileNames = {"test1.gz", "test2.gz", "test3.gz"};
+        for (String fileName : fileNames)
+        {
+            TestFileUtils.saveTextContentInFile(fileName, new 
File(_baseFolder, fileName));
+        }
+        _rolloverWatcher.onRollover(_baseFolder.toPath(), fileNames);
+        return fileNames;
+    }
+
+    private void assertZippedContent(String[] expectedZipEntries, 
ZippedContent zippedContent) throws IOException
+    {
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        zippedContent.write(outputStream);
+
+        byte[] zipFileContent = outputStream.toByteArray();
+        ZipInputStream zipInputStream = new ZipInputStream(new 
ByteArrayInputStream(zipFileContent));
+
+        byte[] buffer = new byte[10];
+        Map<String, String> unzippedContent = new HashMap<>();
+        ZipEntry zipEntry;
+        while ((zipEntry = zipInputStream.getNextEntry()) != null)
+        {
+            int len = 0;
+            ByteArrayOutputStream output = new ByteArrayOutputStream();
+            while ((len = zipInputStream.read(buffer)) > 0)
+            {
+                output.write(buffer, 0, len);
+            }
+            unzippedContent.put(zipEntry.getName(), new 
String(output.toByteArray()));
+        }
+
+        assertEquals("ZippedContent has unexpected number of entries.", 
expectedZipEntries.length, unzippedContent.size());
+        for (String fileName : expectedZipEntries)
+        {
+            assertTrue("ZippedContent does not contain expected file \"" + 
fileName + "\".", unzippedContent.containsKey(fileName));
+            assertEquals("ZippedContent entry \"" + fileName + "\" has 
unexpected content.", fileName, unzippedContent.get(fileName));
+        }
+    }
+
     private String readContent(Content content) throws IOException
     {
         ByteArrayOutputStream os = new ByteArrayOutputStream();

Modified: 
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/security/SecurityManagerTest.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/security/SecurityManagerTest.java?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/security/SecurityManagerTest.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/security/SecurityManagerTest.java
 Thu Jul  2 13:30:52 2015
@@ -21,6 +21,7 @@
 package org.apache.qpid.server.security;
 
 import static org.apache.qpid.server.security.access.ObjectType.BROKER;
+import static org.apache.qpid.server.security.access.ObjectType.VIRTUALHOST;
 import static org.apache.qpid.server.security.access.Operation.ACCESS_LOGS;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.eq;
@@ -964,7 +965,7 @@ public class SecurityManagerTest extends
         ObjectProperties properties = new OperationLoggingDetails(description);
 
         assertDeleteAuthorization(configuredObject, Operation.CONFIGURE, 
ObjectType.BROKER,
-                properties, parent );
+                properties, parent);
     }
 
     private void assertAuthorization(Operation operation, ConfiguredObject<?> 
configuredObject, Operation aclOperation, ObjectType aclObjectType, 
ObjectProperties expectedProperties, ConfiguredObject... objects)
@@ -1045,17 +1046,30 @@ public class SecurityManagerTest extends
         verify(_accessControl, times(2)).authorise(eq(aclOperation), 
eq(aclObjectType), eq(expectedProperties));
     }
 
-    public void testAuthoriseLogsAccess()
+    public void testAuthoriseLogsAccessOnBroker()
     {
         configureAccessPlugin(Result.ALLOWED);
-        assertTrue(_securityManager.authoriseLogsAccess());
+        assertTrue(_securityManager.authoriseLogsAccess(_broker));
+
         verify(_accessControl).authorise(ACCESS_LOGS, BROKER, 
ObjectProperties.EMPTY);
 
         configureAccessPlugin(Result.DENIED);
-        assertFalse(_securityManager.authoriseLogsAccess());
+        assertFalse(_securityManager.authoriseLogsAccess(_broker));
         verify(_accessControl, times(2)).authorise(ACCESS_LOGS, BROKER, 
ObjectProperties.EMPTY);
     }
 
+    public void testAuthoriseLogsAccessOnVirtualHost()
+    {
+        configureAccessPlugin(Result.ALLOWED);
+        assertTrue(_securityManager.authoriseLogsAccess(_virtualHost));
+        ObjectProperties expectedObjectProperties = new 
ObjectProperties((String)_virtualHost.getAttribute(ConfiguredObject.NAME));
+        verify(_accessControl).authorise(ACCESS_LOGS, VIRTUALHOST, 
expectedObjectProperties);
+
+        configureAccessPlugin(Result.DENIED);
+        assertFalse(_securityManager.authoriseLogsAccess(_virtualHost));
+        verify(_accessControl, times(2)).authorise(ACCESS_LOGS, VIRTUALHOST, 
expectedObjectProperties);
+    }
+
     private void configureAccessPlugin(Result result)
     {
         when(_accessControl.authorise(any(Operation.class), 
any(ObjectType.class), any(ObjectProperties.class))).thenReturn(result);

Modified: 
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
 (original)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
 Thu Jul  2 13:30:52 2015
@@ -337,9 +337,6 @@ public class HttpManagement extends Abst
         }
 
         root.addServlet(new ServletHolder(new TimeZoneServlet()), 
"/service/timezones");
-        // QPID-6516
-//        root.addServlet(new ServletHolder(new LogFileListingServlet()), 
"/service/logfilenames");
-//        root.addServlet(new ServletHolder(new Log FileServlet()), 
"/service/logfile");
 
         final SessionManager sessionManager = 
root.getSessionHandler().getSessionManager();
         
sessionManager.getSessionCookieConfig().setName(JSESSIONID_COOKIE_PREFIX + 
lastPort);

Modified: 
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsServlet.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsServlet.java?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsServlet.java
 (original)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsServlet.java
 Thu Jul  2 13:30:52 2015
@@ -43,7 +43,7 @@ public class LogRecordsServlet extends A
     @Override
     protected void doGetWithSubjectAndActor(HttpServletRequest request, 
HttpServletResponse response) throws IOException, ServletException
     {
-        if (!getBroker().getSecurityManager().authoriseLogsAccess())
+        if (!getBroker().getSecurityManager().authoriseLogsAccess(getBroker()))
         {
             response.sendError(HttpServletResponse.SC_FORBIDDEN, "Broker logs 
access is denied");
             return;

Modified: 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/common/CategoryTabExtension.js
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/common/CategoryTabExtension.js?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/common/CategoryTabExtension.js
 (original)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/common/CategoryTabExtension.js
 Thu Jul  2 13:30:52 2015
@@ -23,17 +23,20 @@ define(["qpid/common/util",
     "dojo/domReady!"],
   function (util, query)
   {
-    function CategoryTabExtension(containerNode, template, attributesNode, 
metadata, data, typeBaseFolder)
+    function CategoryTabExtension(params)
     {
       var that = this;
-      this.base = typeBaseFolder;
-      this.metadata = metadata;
-      util.parse(containerNode, template,
+      this.base = params.baseUrl;
+      this.metadata = params.metadata;
+      this.management = params.management;
+      this.typeSpecificDetailsContainer = params.typeSpecificDetailsNode;
+      this.modelObj = params.modelObj;
+      util.parse(params.containerNode, params.template,
         function()
         {
-          that.typeSpecificAttributesContainer = query("." + attributesNode, 
containerNode)[0];
-          that.postParse(containerNode);
-          that.update(data)
+          that.typeSpecificAttributesContainer = query("." + 
params.typeSpecificAttributesClassName, params.containerNode)[0];
+          that.postParse(params.containerNode);
+          that.update(params.data)
         });
     }
 
@@ -53,7 +56,15 @@ define(["qpid/common/util",
           require([this.base + data.type.toLowerCase() + "/show"],
             function(Details)
             {
-              that.details = new 
Details({containerNode:that.typeSpecificAttributesContainer, metadata: 
that.metadata, data:data});
+              that.details = new Details(
+                {
+                  containerNode: that.typeSpecificAttributesContainer,
+                  typeSpecificDetailsNode: that.typeSpecificDetailsContainer,
+                  metadata: that.metadata,
+                  data:data,
+                  management: that.management,
+                  modelObj: that.modelObj
+                });
             }
           );
         }

Modified: 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js
 (original)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js
 Thu Jul  2 13:30:52 2015
@@ -476,7 +476,8 @@ define(["dojo/_base/xhr",
                                 {
                                     postParseCallback();
                                 }
-                             });
+                             },
+                             function(e){console.error("Parse error:" + e);});
            }
            util.buildUI = function(containerNode, parent, 
htmlTemplateLocation, fieldNames, obj, postParseCallback)
            {

Modified: 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Logger.js
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Logger.js?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Logger.js
 (original)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Logger.js
 Thu Jul  2 13:30:52 2015
@@ -192,7 +192,7 @@ define(["dojo/parser",
         }
       }
 
-      storeNodes(["name", "state", "type", "loggerAttributes", 
"filterWarning", "durable"]);
+      storeNodes(["name", "state", "type", "loggerAttributes", 
"loggerTypeSpecificDetails", "filterWarning", "durable"]);
     }
 
     Updater.prototype.update = function (callback)
@@ -236,8 +236,11 @@ define(["dojo/parser",
           {
             that.details = new Details({
               containerNode: that.loggerAttributes,
+              typeSpecificDetailsNode: that.loggerTypeSpecificDetails,
               metadata: that.tabObject.management.metadata,
-              data: data
+              data: data,
+              management: that.tabObject.management,
+              modelObj: that.tabObject.modelObj
             });
           }
         );

Added: 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/FileBrowser.js
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/FileBrowser.js?rev=1688825&view=auto
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/FileBrowser.js
 (added)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/FileBrowser.js
 Thu Jul  2 13:30:52 2015
@@ -0,0 +1,157 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ *
+ */
+define(["qpid/common/util",
+    "dojo/query",
+    "dojo/number",
+    "dojo/_base/lang",
+    "dojo/_base/connect",
+    "dojox/html/entities",
+    "dojo/text!logger/file/fileBrowser.html",
+    "dojox/grid/EnhancedGrid",
+    "qpid/common/UpdatableStore",
+    "dijit/registry",
+    "dojo/domReady!"],
+  function (util, query, number, lang, connect, entities, template, 
EnhancedGrid, UpdatableStore, registry)
+  {
+    function FileBrowser(params)
+    {
+      var that = this;
+      this.management = params.management;
+      this.modelObj = params.modelObj;
+      util.parse(params.containerNode, template, function()
+      {
+        that.postParse(params);
+      });
+    }
+
+    FileBrowser.prototype.postParse = function(params)
+    {
+      var that = this;
+      var gridProperties = {
+          height: 400,
+          selectionMode: "extended",
+          plugins: {
+            indirectSelection: true,
+            pagination: {
+              pageSizes: [10, 25, 50, 100],
+              description: true,
+              sizeSwitch: true,
+              pageStepper: true,
+              gotoButton: true,
+              maxPageStep: 4,
+              position: "bottom"
+            }
+      }};
+
+      this.downloadButton = registry.byNode(query(".downloadButton", 
params.containerNode)[0]);
+      this.downloadButton.on("click", function(e) 
{that.downloadSelectedFiles()} );
+
+      this.downloadAllButton = registry.byNode(query(".downloadAllButton", 
params.containerNode)[0]);
+      this.downloadAllButton.on("click", function(e) {that.downloadAllFiles()} 
);
+
+      this.logFiles = this.addIdToFileObjects(params.data);
+      this.logFileGrid = new UpdatableStore(this.logFiles, 
query(".logFilesGrid", params.containerNode)[0],
+        [
+          { name: "Name", field: "name", width: "auto"},
+          { name: "Size", field: "size", width: "60px",
+            formatter: function(val)
+            {
+              return val > 1024 ? (val > 1048576? number.round(val/1048576) + 
"MB": number.round(val/1024) + "KB") : val + "bytes";
+            }
+          },
+          { name: "Last Modified", field: "lastModified", width: "250px",
+            formatter: function(val)
+            {
+              return that.management.userPreferences.formatDateTime(val, 
{addOffset: true, appendTimeZone: true});
+            }
+          }
+        ], function(obj) {
+          obj.grid.on("rowDblClick",
+            function(evt){
+              var idx = evt.rowIndex;
+              var theItem = this.getItem(idx);
+              that.download(theItem);
+            });
+        }, gridProperties, EnhancedGrid);
+    }
+
+    FileBrowser.prototype.download = function (item)
+    {
+      var parentModelObj = this.modelObj;
+      var modelObj = {type: parentModelObj.type, name: "getFile", parent: 
parentModelObj}
+      this.management.download(modelObj, {fileName: item.name});
+    }
+
+    FileBrowser.prototype.addIdToFileObjects = function(data)
+    {
+      var fileItems = [];
+      var logFiles = data.logFiles;
+      for (var idx in logFiles)
+      {
+        var item = lang.mixin(logFiles[idx], {id: logFiles[idx].name});
+        fileItems.push(item);
+      }
+      return fileItems;
+    }
+
+    FileBrowser.prototype.downloadSelectedFiles = function ()
+    {
+      var data = this.logFileGrid.grid.selection.getSelected();
+      this.downloadFiles(data);
+    }
+
+    FileBrowser.prototype.downloadAllFiles = function()
+    {
+      var parentModelObj = this.modelObj;
+      var modelObj = {type: parentModelObj.type, name: "getAllFiles", parent: 
parentModelObj}
+      this.management.download(modelObj, {});
+    }
+
+    FileBrowser.prototype.downloadFiles = function(fileItems)
+    {
+      if(fileItems.length)
+      {
+        var parentModelObj = this.modelObj;
+        var modelObj = {type: parentModelObj.type, name: "getFiles", parent: 
parentModelObj}
+        var items = [];
+        for(var i = 0; i < fileItems.length; i++)
+        {
+          items.push(fileItems[i].id);
+        }
+        this.management.download(modelObj, {fileName: items});
+      }
+    }
+
+    FileBrowser.prototype.update = function (restData)
+    {
+      if (this.logFileGrid)
+      {
+        this.logFiles = this.addIdToFileObjects(restData);
+        if (this.logFileGrid.update(this.logFiles))
+        {
+          //this.logFileGrid.grid._refresh();
+        }
+      }
+    }
+
+    return FileBrowser;
+  }
+);

Modified: 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/brokerlogger/file/show.js
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/brokerlogger/file/show.js?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/brokerlogger/file/show.js
 (original)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/brokerlogger/file/show.js
 Thu Jul  2 13:30:52 2015
@@ -19,18 +19,29 @@
  *
  */
 define(["qpid/common/util",
-    "dojo/query",
-    "dojox/html/entities",
     "dojo/text!logger/file/show.html",
     "qpid/common/TypeTabExtension",
+    "qpid/management/logger/FileBrowser",
     "dojo/domReady!"],
-  function (util, query, entities, template, TypeTabExtension)
+  function (util, template, TypeTabExtension, FileBrowser)
   {
     function BrokerFileLogger(params)
     {
+      this.fileBrowser = new FileBrowser({containerNode: 
params.typeSpecificDetailsNode,
+                                          management: params.management,
+                                          data: params.data,
+                                          modelObj: params.modelObj});
       TypeTabExtension.call(this, params.containerNode, template, 
"BrokerLogger", "File", params.metadata, params.data);
     }
 
-    return util.extend(BrokerFileLogger, TypeTabExtension);
+    util.extend(BrokerFileLogger, TypeTabExtension);
+
+    BrokerFileLogger.prototype.update = function (restData)
+    {
+      TypeTabExtension.prototype.update.call(this, restData);
+      this.fileBrowser.update(restData);
+    }
+
+    return BrokerFileLogger;
   }
 );

Modified: 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/brokerlogger/show.js
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/brokerlogger/show.js?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/brokerlogger/show.js
 (original)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/brokerlogger/show.js
 Thu Jul  2 13:30:52 2015
@@ -20,14 +20,20 @@
  */
  define(["qpid/common/util",
          "dojo/query",
+         "dojo/_base/lang",
          "dojo/text!logger/brokerlogger/show.html",
          "qpid/common/CategoryTabExtension",
          "dojo/domReady!"],
-   function (util, query, template, CategoryTabExtension)
+   function (util, query, lang, template, CategoryTabExtension)
    {
      function BrokerLogger(params)
      {
-       CategoryTabExtension.call(this, params.containerNode, template, 
"typeSpecificAttributes", params.metadata, params.data, 
"qpid/management/logger/brokerlogger/");
+       var categoryExtensionParams = lang.mixin(params, {
+                                                          template: template,
+                                                          
typeSpecificAttributesClassName: "typeSpecificAttributes",
+                                                          baseUrl: 
"qpid/management/logger/brokerlogger/"
+                                                        });
+       CategoryTabExtension.call(this, categoryExtensionParams);
      }
 
      util.extend(BrokerLogger, CategoryTabExtension);

Modified: 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/virtualhostlogger/file/show.js
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/virtualhostlogger/file/show.js?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/virtualhostlogger/file/show.js
 (original)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/virtualhostlogger/file/show.js
 Thu Jul  2 13:30:52 2015
@@ -19,18 +19,29 @@
  *
  */
 define(["qpid/common/util",
-    "dojo/query",
-    "dojox/html/entities",
     "dojo/text!logger/file/show.html",
     "qpid/common/TypeTabExtension",
+    "qpid/management/logger/FileBrowser",
     "dojo/domReady!"],
-  function (util, query, entities, template, TypeTabExtension)
+  function (util, template, TypeTabExtension, FileBrowser)
   {
     function VirtualHostFileLogger(params)
     {
+      this.fileBrowser = new FileBrowser({containerNode: 
params.typeSpecificDetailsNode,
+                                          management: params.management,
+                                          data: params.data,
+                                          modelObj: params.modelObj});
       TypeTabExtension.call(this, params.containerNode, template, 
"VirtualHostLogger", "File", params.metadata, params.data);
     }
 
-    return util.extend(VirtualHostFileLogger, TypeTabExtension);
+    util.extend(VirtualHostFileLogger, TypeTabExtension);
+
+    VirtualHostFileLogger.prototype.update = function (restData)
+    {
+      TypeTabExtension.prototype.update.call(this, restData);
+      this.fileBrowser.update(restData);
+    }
+
+    return VirtualHostFileLogger;
   }
 );

Modified: 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/virtualhostlogger/show.js
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/virtualhostlogger/show.js?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/virtualhostlogger/show.js
 (original)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logger/virtualhostlogger/show.js
 Thu Jul  2 13:30:52 2015
@@ -20,14 +20,20 @@
  */
 define(["qpid/common/util",
     "dojo/query",
+    "dojo/_base/lang",
     "dojo/text!logger/virtualhostlogger/show.html",
     "qpid/common/CategoryTabExtension",
     "dojo/domReady!"],
-  function (util, query, template, CategoryTabExtension)
+  function (util, query, lang, template, CategoryTabExtension)
   {
     function VirtualHostLogger(params)
     {
-      CategoryTabExtension.call(this, params.containerNode, template, 
"typeSpecificAttributes", params.metadata, params.data, 
"qpid/management/logger/virtualhostlogger/");
+      var categoryExtensionParams = lang.mixin(params, {
+                                                          template: template,
+                                                          
typeSpecificAttributesClassName: "typeSpecificAttributes",
+                                                          baseUrl: 
"qpid/management/logger/virtualhostlogger/"
+                                                        });
+      CategoryTabExtension.call(this, categoryExtensionParams);
     }
 
     return util.extend(VirtualHostLogger, CategoryTabExtension);

Modified: 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logs/LogViewer.js
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logs/LogViewer.js?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logs/LogViewer.js
 (original)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logs/LogViewer.js
 Thu Jul  2 13:30:52 2015
@@ -25,10 +25,9 @@ define(["dojo/_base/xhr",
         "dijit/registry",
         "qpid/common/grid/GridUpdater",
         "qpid/common/grid/UpdatableGrid",
-        "qpid/management/logs/LogFileDownloadDialog",
         "dojo/text!../../../logs/showLogViewer.html",
         "dojo/domReady!"],
-       function (xhr, parser, query, locale, registry, GridUpdater, 
UpdatableGrid, LogFileDownloadDialog, markup) {
+       function (xhr, parser, query, locale, registry, GridUpdater, 
UpdatableGrid, markup) {
 
            var defaulGridRowLimit = 4096;
            var currentTimeZone;
@@ -65,14 +64,6 @@ define(["dojo/_base/xhr",
            };
            LogViewer.prototype._postParse = function()
            {
-               var self = this;
-
-               this.downloadLogsButton = 
registry.byNode(query(".downloadLogs", this.contentPane.containerNode)[0]);
-               this.downloadLogDialog = new 
LogFileDownloadDialog({userPreferences:this.management.userPreferences});
-
-               this.downloadLogsButton.on("click", function(evt){
-                   self.downloadLogDialog.showDialog();
-               });
                this._buildGrid();
            };
 

Copied: 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/logger/file/fileBrowser.html
 (from r1688819, 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/logs/showLogFileDownloadDialog.html)
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/logger/file/fileBrowser.html?p2=qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/logger/file/fileBrowser.html&p1=qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/logs/showLogFileDownloadDialog.html&r1=1688819&r2=1688825&rev=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/logs/showLogFileDownloadDialog.html
 (original)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/logger/file/fileBrowser.html
 Thu Jul  2 13:30:52 2015
@@ -19,15 +19,11 @@
  -
  -->
 <div>
-  <div class="contentArea" style="height:320px;overflow:auto">
-     <div><b>Select log files to download</b></div>
-     <div class="logFilesGrid" style='height:300px;width: 580px'></div>
-  </div>
-  <div class="dijitDialogPaneActionBar qpidDialogPaneActionBar">
-     <button value="Download" data-dojo-type="dijit.form.Button"
-       class="downloadLogsButton"
-       data-dojo-props="iconClass: 'downloadLogsIcon', label: 'Download' 
"></button>
-     <button value="Close" data-dojo-type="dijit.form.Button" 
data-dojo-props="label: 'Close'"
-       class="downloadLogsDialogCloseButton"></button>
-  </div>
+    <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Log Files'" 
class="clear logFilesGridPanel">
+        <div class="logFilesGrid hidden"></div>
+        <div class="clear">
+            <button data-dojo-type="dijit.form.Button" 
class="downloadButton">Download Selected</button>
+            <button data-dojo-type="dijit.form.Button" 
class="downloadAllButton">Download All</button>
+        </div>
+    </div>
 </div>

Modified: 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/logs/showLogViewer.html
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/logs/showLogViewer.html?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/logs/showLogViewer.html
 (original)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/logs/showLogViewer.html
 Thu Jul  2 13:30:52 2015
@@ -22,8 +22,5 @@
 
     <div id="broker-logfile"></div>
     <br/>
-    <button data-dojo-type="dijit.form.Button" class="downloadLogs"
-                data-dojo-props="iconClass: 'downloadLogsIcon', 
title:'Download Log Files', name: 'downloadLogs'">Download Log Files</button>
-    <br/>
 </div>
 

Modified: 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/showLogger.html
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/showLogger.html?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/showLogger.html
 (original)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/showLogger.html
 Thu Jul  2 13:30:52 2015
@@ -53,6 +53,6 @@
         </div>
     </div>
     <br/>
-    <div class="loggerExtra"></div>
+    <div class="loggerTypeSpecificDetails"></div>
 </div>
 

Modified: 
qpid/java/trunk/systests/src/test/java/org/apache/qpid/systest/rest/acl/BrokerACLTest.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/systests/src/test/java/org/apache/qpid/systest/rest/acl/BrokerACLTest.java?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/systests/src/test/java/org/apache/qpid/systest/rest/acl/BrokerACLTest.java
 (original)
+++ 
qpid/java/trunk/systests/src/test/java/org/apache/qpid/systest/rest/acl/BrokerACLTest.java
 Thu Jul  2 13:30:52 2015
@@ -28,6 +28,7 @@ import java.util.Map;
 
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.qpid.server.logging.BrokerFileLogger;
 import org.apache.qpid.server.logging.BrokerMemoryLogger;
 import org.apache.qpid.server.logging.BrokerNameAndLevelFilter;
 import org.apache.qpid.server.management.plugin.servlet.rest.RestServlet;
@@ -74,6 +75,8 @@ public class BrokerACLTest extends QpidR
         AbstractACLTestCase.writeACLFileUtil(this, "ACL ALLOW-LOG ALL ACCESS 
MANAGEMENT",
                 "ACL ALLOW-LOG " + ALLOWED_USER + " CONFIGURE BROKER",
                 "ACL DENY-LOG " + DENIED_USER + " CONFIGURE BROKER",
+                "ACL ALLOW-LOG " + ALLOWED_USER + " ACCESS_LOGS BROKER",
+                "ACL DENY-LOG " + DENIED_USER + " ACCESS_LOGS BROKER",
                 "ACL DENY-LOG ALL ALL");
 
                 _secondaryAclFileContent =
@@ -867,6 +870,28 @@ public class BrokerACLTest extends QpidR
         getRestTestHelper().submitRequest("brokerlogger/memory", "GET", 
HttpServletResponse.SC_NOT_FOUND);
     }
 
+    public void testDownloadBrokerLoggerFileAllowedDenied() throws Exception
+    {
+        final String loggerName = "testFileLogger";
+        final String loggerPath = "brokerlogger/" + loggerName;
+
+        getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER);
+
+        Map<String, Object> attributes = new HashMap<>();
+        attributes.put(BrokerLogger.NAME, loggerName);
+        attributes.put(ConfiguredObject.TYPE, BrokerFileLogger.TYPE);
+        getRestTestHelper().submitRequest("brokerlogger", "PUT", attributes, 
HttpServletResponse.SC_CREATED);
+
+        getRestTestHelper().submitRequest(loggerPath + 
"/getFile?fileName=qpid.log", "GET", HttpServletResponse.SC_OK);
+        getRestTestHelper().submitRequest(loggerPath + 
"/getFiles?fileName=qpid.log", "GET", HttpServletResponse.SC_OK);
+        getRestTestHelper().submitRequest(loggerPath + "/getAllFiles", "GET", 
HttpServletResponse.SC_OK);
+
+        getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER);
+        getRestTestHelper().submitRequest(loggerPath + 
"/getFile?fileName=qpid.log", "GET", HttpServletResponse.SC_FORBIDDEN);
+        getRestTestHelper().submitRequest(loggerPath + 
"/getFiles?fileName=qpid.log", "GET", HttpServletResponse.SC_FORBIDDEN);
+        getRestTestHelper().submitRequest(loggerPath + "/getAllFiles", "GET", 
HttpServletResponse.SC_FORBIDDEN);
+    }
+
     /* === Broker Logger Filters === */
 
     public void testCreateBrokerLoggerFilterAllowedDenied() throws Exception

Modified: 
qpid/java/trunk/systests/src/test/java/org/apache/qpid/systest/rest/acl/VirtualHostACLTest.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/systests/src/test/java/org/apache/qpid/systest/rest/acl/VirtualHostACLTest.java?rev=1688825&r1=1688824&r2=1688825&view=diff
==============================================================================
--- 
qpid/java/trunk/systests/src/test/java/org/apache/qpid/systest/rest/acl/VirtualHostACLTest.java
 (original)
+++ 
qpid/java/trunk/systests/src/test/java/org/apache/qpid/systest/rest/acl/VirtualHostACLTest.java
 Thu Jul  2 13:30:52 2015
@@ -26,9 +26,12 @@ import java.util.Map;
 
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.qpid.server.logging.VirtualHostFileLogger;
 import org.apache.qpid.server.management.plugin.HttpManagement;
+import org.apache.qpid.server.model.ConfiguredObject;
 import org.apache.qpid.server.model.Plugin;
 import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.server.model.VirtualHostLogger;
 import org.apache.qpid.server.model.VirtualHostNode;
 import org.apache.qpid.server.security.acl.AbstractACLTestCase;
 import org.apache.qpid.server.virtualhost.ProvidedStoreVirtualHostImpl;
@@ -109,6 +112,31 @@ public class VirtualHostACLTest extends
         getRestTestHelper().submitRequest("virtualhost/" + TEST2_VIRTUALHOST + 
"/" + TEST2_VIRTUALHOST, "PUT", attributes, HttpServletResponse.SC_FORBIDDEN);
     }
 
+    public void testDownloadVirtualHostLoggerFileAllowedDenied() throws 
Exception
+    {
+        final String virtualHostName = "testVirtualHost";
+        final String loggerName = "testFileLogger";
+        final String loggerPath = "virtualhostlogger/" + VHN_WITHOUT_VH + "/" 
+ virtualHostName + "/" + loggerName;
+
+        getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER);
+
+        createVirtualHost(VHN_WITHOUT_VH, virtualHostName);
+
+        Map<String, Object> attributes = new HashMap<>();
+        attributes.put(VirtualHostLogger.NAME, loggerName);
+        attributes.put(ConfiguredObject.TYPE, VirtualHostFileLogger.TYPE);
+        getRestTestHelper().submitRequest("virtualhostlogger/" + 
VHN_WITHOUT_VH + "/" + virtualHostName, "PUT", attributes, 
HttpServletResponse.SC_CREATED);
+
+        getRestTestHelper().submitRequest(loggerPath + 
"/getFile?fileName=qpid.log", "GET", HttpServletResponse.SC_OK);
+        getRestTestHelper().submitRequest(loggerPath + 
"/getFiles?fileName=qpid.log", "GET", HttpServletResponse.SC_OK);
+        getRestTestHelper().submitRequest(loggerPath + "/getAllFiles", "GET", 
HttpServletResponse.SC_OK);
+
+        getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER);
+        getRestTestHelper().submitRequest(loggerPath + 
"/getFile?fileName=qpid.log", "GET", HttpServletResponse.SC_FORBIDDEN);
+        getRestTestHelper().submitRequest(loggerPath + 
"/getFiles?fileName=qpid.log", "GET", HttpServletResponse.SC_FORBIDDEN);
+        getRestTestHelper().submitRequest(loggerPath + "/getAllFiles", "GET", 
HttpServletResponse.SC_FORBIDDEN);
+    }
+
     /* === Utility Methods === */
 
     private int createVirtualHost(final String testVirtualHostNode, String 
virtualHostName) throws Exception



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org
For additional commands, e-mail: commits-h...@qpid.apache.org

Reply via email to