diff options
| author | Kim van der Riet <kpvdr@apache.org> | 2013-10-21 22:04:51 +0000 |
|---|---|---|
| committer | Kim van der Riet <kpvdr@apache.org> | 2013-10-21 22:04:51 +0000 |
| commit | 888581cb9781259073d190edede25e6253ec7dd9 (patch) | |
| tree | ca719eb54a498aebb5c59c527b08178491e4ad4c /qpid/java/broker-plugins/management-http | |
| parent | 6d5d782b504677fcc4392086cb628dbbb79c800a (diff) | |
| download | qpid-python-888581cb9781259073d190edede25e6253ec7dd9.tar.gz | |
QPID-4984: WIP - Merge from trunk r.1534385.
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/linearstore@1534394 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java/broker-plugins/management-http')
48 files changed, 2099 insertions, 678 deletions
diff --git a/qpid/java/broker-plugins/management-http/build.xml b/qpid/java/broker-plugins/management-http/build.xml index abf35d9c88..d921b91580 100644 --- a/qpid/java/broker-plugins/management-http/build.xml +++ b/qpid/java/broker-plugins/management-http/build.xml @@ -18,36 +18,35 @@ --> <project name="Qpid Broker-Plugins Management HTTP" default="build"> - <property name="module.depends" value="common broker" /> - <property name="module.test.depends" value="broker/tests common/tests management/common client" /> + <property name="module.depends" value="common broker-core" /> + <property name="module.test.depends" value="broker-core/tests qpid-test-utils management/common client" /> <property name="module.genpom" value="true" /> - <property name="module.genpom.args" value="-Sqpid-common=provided -Sqpid-broker=provided" /> + <property name="module.genpom.args" value="-Sqpid-common=provided -Sqpid-broker-core=provided" /> <property name="broker.plugin" value="true"/> - <property name="broker-plugins-management-http.libs" value="" /> - <import file="../../module.xml" /> - <!-- Flagfile used to determine if uwar needs to be done. ._ is part of Ant's defaultexcludes so wont appear bundles --> - <property name="dojo.uptodate.flagfile" value="${module.classes}/resources/dojo/._dojouptodate.timestamp" /> + <property name="module.manifest" value="${module.build}/MANIFEST.MF" /> + <property name="dojo.config.file" value="${module.classes}/dojoconfig.properties" /> - <target name="precompile" depends="unwardojo" /> + <target name="precompile" depends="generate-manifest, generate-dojo-config"/> - <target name="unwardojo" depends="check-unwardojo.done" unless="unwardojo.done"> - <unwar src="${project.root}/${dojo}" dest="${module.classes}/resources/dojo"> - <patternset> - <exclude name="META-INF/**" /> - <exclude name="WEB-INF/**" /> - <exclude name="**/*.uncompressed.js" /> - </patternset> - </unwar> - <touch file="${dojo.uptodate.flagfile}" /> + <target name="generate-manifest"> + <!-- Echos exactly as shown, so leave no spaces before/after lines --> + <echo file="${module.manifest}" append="false">Manifest-Version: 1.0 +Class-Path: dojo-${dojo-version}.zip +</echo> </target> - <target name="check-unwardojo.done"> - <uptodate property="unwardojo.done" targetfile="${dojo.uptodate.flagfile}" srcfile="${project.root}/${dojo}" /> + <target name="generate-dojo-config"> + <!-- Echos exactly as shown, so leave no spaces before/after lines --> + <echo file="${dojo.config.file}" append="false">dojo-version=${dojo-version} +dojo-path=/dojo-${dojo-version}/dojo +dijit-path=/dojo-${dojo-version}/dijit +dojox-path=/dojo-${dojo-version}/dojox +</echo> </target> <target name="bundle" depends="bundle-tasks" /> diff --git a/qpid/java/broker-plugins/management-http/pom.xml b/qpid/java/broker-plugins/management-http/pom.xml new file mode 100644 index 0000000000..36925369fe --- /dev/null +++ b/qpid/java/broker-plugins/management-http/pom.xml @@ -0,0 +1,204 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <parent> + <groupId>org.apache.qpid</groupId> + <artifactId>qpid-project</artifactId> + <version>0.26-SNAPSHOT</version> + <relativePath>../../pom.xml</relativePath> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>qpid-broker-plugins-management-http</artifactId> + + <dependencies> + <dependency> + <groupId>org.apache.qpid</groupId> + <artifactId>qpid-broker-core</artifactId> + <version>0.26-SNAPSHOT</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>org.apache.geronimo.specs</groupId> + <artifactId>geronimo-servlet_2.5_spec</artifactId> + <version>1.2</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-server</artifactId> + <version>7.6.10.v20130312</version> + <scope>compile</scope> + <exclusions> + <exclusion> + <groupId>org.eclipse.jetty.orbit</groupId> + <artifactId>javax.servlet</artifactId> + </exclusion> + <exclusion> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-continuation</artifactId> + </exclusion> + <exclusion> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-http</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-continuation</artifactId> + <version>7.6.10.v20130312</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-security</artifactId> + <version>7.6.10.v20130312</version> + <scope>compile</scope> + <exclusions> + <exclusion> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-server</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-http</artifactId> + <version>7.6.10.v20130312</version> + <scope>compile</scope> + <exclusions> + <exclusion> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-io</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-io</artifactId> + <version>7.6.10.v20130312</version> + <scope>compile</scope> + <exclusions> + <exclusion> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-util</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-servlet</artifactId> + <version>7.6.10.v20130312</version> + <scope>compile</scope> + <exclusions> + <exclusion> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-security</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-util</artifactId> + <version>7.6.10.v20130312</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-websocket</artifactId> + <version>7.6.10.v20130312</version> + <scope>compile</scope> + <exclusions> + <exclusion> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-util</artifactId> + </exclusion> + <exclusion> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-io</artifactId> + </exclusion> + <exclusion> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-http</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.dojotoolkit</groupId> + <artifactId>dojo</artifactId> + <version>${dojo-version}</version> + <type>zip</type> + </dependency> + + <!-- test dependencies --> + <dependency> + <groupId>org.apache.qpid</groupId> + <artifactId>qpid-test-utils</artifactId> + <version>0.26-SNAPSHOT</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <directory>src/main/resources</directory> + </resource> + <resource> + <directory>src/main/java</directory> + <includes> + <include>resources/</include> + </includes> + </resource> + <resource> + <directory>src/main/resources-maven</directory> + <filtering>true</filtering> + </resource> + </resources> + + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <!--version specified in parent pluginManagement --> + <configuration> + <archive> + <!-- add the dojo zip to the manifest Class-Path so that + it gets picked up when using classpath wildcard + expansion, which only collects .jar files --> + <manifestEntries> + <Class-Path>dojo-${dojo-version}.zip</Class-Path> + </manifestEntries> + </archive> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/DojoHelper.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/DojoHelper.java new file mode 100644 index 0000000000..2349bb48a7 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/DojoHelper.java @@ -0,0 +1,116 @@ +/* + * 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. + * + * + */ +package org.apache.qpid.server.management.plugin; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import java.util.Properties; + +public class DojoHelper +{ + private static final Logger _logger = LoggerFactory.getLogger(DojoHelper.class); + + public static final String VERSION_FILE = "dojoconfig.properties"; + public static final String DOJO_VERSION_PROPERTY = "dojo-version"; + public static final String DOJO_PATH_PROPERTY = "dojo-path"; + public static final String DIJIT_PATH_PROPERTY = "dijit-path"; + public static final String DOJOX_PATH_PROPERTY = "dojox-path"; + + private static String _version = "undefined"; + private static String _dojoPath = "/dojo-undefined/dojo"; + private static String _dijitPath = "/dojo-undefined/dijit"; + private static String _dojoxPath = "/dojo-undefined/dojox"; + + // Loads the value from the properties file. + static + { + Properties props = new Properties(); + + try + { + InputStream propertyStream = DojoHelper.class.getClassLoader().getResourceAsStream(VERSION_FILE); + if (propertyStream == null) + { + _logger.warn("Unable to find resource " + VERSION_FILE + " from classloader"); + } + else + { + props.load(propertyStream); + + if (_logger.isDebugEnabled()) + { + _logger.debug("Dumping Dojo Config:"); + for (Map.Entry<Object, Object> entry : props.entrySet()) + { + _logger.debug("Property: " + entry.getKey() + " Value: " + entry.getValue()); + } + + _logger.debug("End of property dump"); + } + + _version = readPropertyValue(props, DOJO_VERSION_PROPERTY, _version); + _dojoPath = readPropertyValue(props, DOJO_PATH_PROPERTY, _dojoPath); + _dijitPath = readPropertyValue(props, DIJIT_PATH_PROPERTY, _dijitPath); + _dojoxPath = readPropertyValue(props, DOJOX_PATH_PROPERTY, _dojoxPath); + } + } + catch (IOException e) + { + // Log a warning about this and leave the values initialized to unknown. + _logger.error("Exception loading " + VERSION_FILE + " resource:", e); + } + } + + private static String readPropertyValue(Properties props, String propertyName, String defaultValue) + { + String value = props.getProperty(propertyName); + if (value == null) + { + return defaultValue; + } + + return value; + } + + public static String getDojoVersion() + { + return _version; + } + + public static String getDojoPath() + { + return _dojoPath; + } + + public static String getDijitPath() + { + return _dijitPath; + } + + public static String getDojoxPath() + { + return _dojoxPath; + } +} diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java index c6623aefcf..76090b9484 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java +++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java @@ -47,7 +47,7 @@ import org.apache.qpid.server.management.plugin.servlet.rest.LogRecordsServlet; import org.apache.qpid.server.management.plugin.servlet.rest.LogoutServlet; import org.apache.qpid.server.management.plugin.servlet.rest.MessageContentServlet; import org.apache.qpid.server.management.plugin.servlet.rest.MessageServlet; -import org.apache.qpid.server.management.plugin.servlet.rest.PreferencesServlet; +import org.apache.qpid.server.management.plugin.servlet.rest.LoggedOnUserPreferencesServlet; import org.apache.qpid.server.management.plugin.servlet.rest.UserPreferencesServlet; import org.apache.qpid.server.management.plugin.servlet.rest.RestServlet; import org.apache.qpid.server.management.plugin.servlet.rest.SaslServlet; @@ -300,7 +300,7 @@ public class HttpManagement extends AbstractPluginAdapter implements HttpManagem addRestServlet(root, "preferencesprovider", AuthenticationProvider.class, PreferencesProvider.class); root.addServlet(new ServletHolder(new UserPreferencesServlet()), "/rest/userpreferences/*"); - root.addServlet(new ServletHolder(new PreferencesServlet()), "/rest/preferences"); + root.addServlet(new ServletHolder(new LoggedOnUserPreferencesServlet()), "/rest/preferences"); root.addServlet(new ServletHolder(new StructureServlet()), "/rest/structure"); root.addServlet(new ServletHolder(new MessageServlet()), "/rest/message/*"); root.addServlet(new ServletHolder(new MessageContentServlet()), "/rest/message-content/*"); @@ -313,6 +313,10 @@ public class HttpManagement extends AbstractPluginAdapter implements HttpManagem root.addServlet(new ServletHolder(new DefinedFileServlet("index.html")), "/"); root.addServlet(new ServletHolder(new LogoutServlet()), "/logout"); + root.addServlet(new ServletHolder(new FileServlet(DojoHelper.getDojoPath(), true)), "/dojo/dojo/*"); + root.addServlet(new ServletHolder(new FileServlet(DojoHelper.getDijitPath(), true)), "/dojo/dijit/*"); + root.addServlet(new ServletHolder(new FileServlet(DojoHelper.getDojoxPath(), true)), "/dojo/dojox/*"); + root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.js"); root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.css"); root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.html"); @@ -324,16 +328,9 @@ public class HttpManagement extends AbstractPluginAdapter implements HttpManagem root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.txt"); root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.xsl"); root.addServlet(new ServletHolder(new HelperServlet()), "/rest/helper"); - root.addServlet(new ServletHolder(new LogFileListingServlet()), "/rest/logfiles"); + root.addServlet(new ServletHolder(new LogFileListingServlet()), "/rest/logfilenames"); root.addServlet(new ServletHolder(new LogFileServlet()), "/rest/logfile"); - String[] timeZoneFiles = {"africa", "antarctica", "asia", "australasia", "backward", - "etcetera", "europe", "northamerica", "pacificnew", "southamerica"}; - for (String timeZoneFile : timeZoneFiles) - { - root.addServlet(new ServletHolder(FileServlet.INSTANCE), "/dojo/dojox/date/zoneinfo/" + timeZoneFile); - } - final SessionManager sessionManager = root.getSessionHandler().getSessionManager(); sessionManager.setSessionCookie(JSESSIONID_COOKIE_PREFIX + lastPort); sessionManager.setMaxInactiveInterval((Integer)getAttribute(TIME_OUT)); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/log/LogFileHelper.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/log/LogFileHelper.java index 03d98d020b..4104661017 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/log/LogFileHelper.java +++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/log/LogFileHelper.java @@ -55,14 +55,23 @@ public class LogFileHelper Map<String, List<LogFileDetails>> cache = new HashMap<String, List<LogFileDetails>>(); for (int i = 0; i < requestedFiles.length; i++) { - String[] paths = requestedFiles[i].split("/"); - if (paths.length != 2) + String logFile = requestedFiles[i]; + if ("".equals(logFile)) { - throw new IllegalArgumentException("Log file name '" + requestedFiles[i] + "' does not include an appender name"); + throw new IllegalArgumentException("Log file parameter is empty"); + } + int pos = logFile.indexOf("/"); + if (pos == -1) + { + throw new IllegalArgumentException("Log file parameter '" + logFile + "' does not include an appender name"); + } + if (pos == logFile.length()) + { + throw new IllegalArgumentException("Log file parameter '" + logFile + "' does not include an file name"); } - String appenderName = paths[0]; - String fileName = paths[1]; + String appenderName = logFile.substring(0, pos); + String fileName = logFile.substring(pos + 1); List<LogFileDetails> appenderFiles = cache.get(appenderName); if (appenderFiles == null) @@ -92,6 +101,7 @@ public class LogFileHelper if (logFileDetails.getName().equals(fileName)) { logFiles.add(logFileDetails); + break; } } } @@ -147,16 +157,16 @@ public class LogFileHelper { if (appender instanceof QpidCompositeRollingAppender) { - return listAppenderFiles((QpidCompositeRollingAppender) appender, includeLogFileLocation); + return listQpidCompositeRollingAppenderFiles((QpidCompositeRollingAppender) appender, includeLogFileLocation); } else if (appender instanceof FileAppender) { - return listAppenderFiles((FileAppender) appender, includeLogFileLocation); + return listFileAppenderFiles((FileAppender) appender, includeLogFileLocation); } return null; } - private List<LogFileDetails> listAppenderFiles(FileAppender appender, boolean includeLogFileLocation) + private List<LogFileDetails> listFileAppenderFiles(FileAppender appender, boolean includeLogFileLocation) { String appenderFilePath = appender.getFile(); File appenderFile = new File(appenderFilePath); @@ -167,17 +177,17 @@ public class LogFileHelper return Collections.emptyList(); } - private List<LogFileDetails> listAppenderFiles(QpidCompositeRollingAppender appender, boolean includeLogFileLocation) + private List<LogFileDetails> listQpidCompositeRollingAppenderFiles(QpidCompositeRollingAppender appender, boolean includeLogFileLocation) { - List<LogFileDetails> files = listAppenderFiles((FileAppender) appender, includeLogFileLocation); + List<LogFileDetails> files = listFileAppenderFiles((FileAppender) appender, includeLogFileLocation); String appenderFilePath = appender.getFile(); File appenderFile = new File(appenderFilePath); File backupFolder = new File(appender.getBackupFilesToPath()); if (backupFolder.exists()) { - String backFolderName = backupFolder.getName() + "/"; + String backupFolderName = backupFolder.getName() + "/"; List<LogFileDetails> backedUpFiles = listLogFiles(backupFolder, appenderFile.getName(), appender.getName(), - backFolderName, includeLogFileLocation); + backupFolderName, includeLogFileLocation); files.addAll(backedUpFiles); } return files; @@ -192,7 +202,12 @@ public class LogFileHelper String name = file.getName(); if (name.startsWith(baseFileName)) { - files.add(new LogFileDetails(name, appenderName, includeLogFileLocation ? file : null, getMimeType(name), file.length(), + String diplayPath = name; + if (!relativePath.equals("")) + { + diplayPath = relativePath + name; + } + files.add(new LogFileDetails(diplayPath, appenderName, includeLogFileLocation ? file : null, getMimeType(name), file.length(), file.lastModified())); } } diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/FileServlet.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/FileServlet.java index 24e5e7c049..7e97b32c0c 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/FileServlet.java +++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/FileServlet.java @@ -26,6 +26,7 @@ import java.net.URL; import java.util.Collections; import java.util.HashMap; import java.util.Map; + import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; @@ -34,6 +35,8 @@ import javax.servlet.http.HttpServletResponse; public class FileServlet extends HttpServlet { + private static final String RESOURCES_PREFIX = "/resources"; + public static final FileServlet INSTANCE = new FileServlet(); private static final Map<String, String> CONTENT_TYPES; @@ -52,14 +55,33 @@ public class FileServlet extends HttpServlet CONTENT_TYPES = Collections.unmodifiableMap(contentTypes); } + private final String _resourcePathPrefix; + private boolean _usePathInfo; public FileServlet() { + _resourcePathPrefix = RESOURCES_PREFIX; + _usePathInfo = false; + } + + public FileServlet(String resourcePathPrefix, boolean usePathInfo) + { + _resourcePathPrefix = resourcePathPrefix; + _usePathInfo = usePathInfo; } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - String filename = request.getServletPath(); + String filename = null; + if(_usePathInfo) + { + filename = request.getPathInfo(); + } + else + { + filename = request.getServletPath(); + } + if(filename.contains(".")) { String suffix = filename.substring(filename.lastIndexOf('.')+1); @@ -69,7 +91,8 @@ public class FileServlet extends HttpServlet response.setContentType(contentType); } } - URL resourceURL = getClass().getResource("/resources" + filename); + + URL resourceURL = getClass().getResource(_resourcePathPrefix + filename); if(resourceURL != null) { response.setStatus(HttpServletResponse.SC_OK); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/LogFileServlet.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/LogFileServlet.java index 1fa03dc3dc..321cfae66c 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/LogFileServlet.java +++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/LogFileServlet.java @@ -35,14 +35,13 @@ import org.apache.qpid.server.management.plugin.servlet.rest.AbstractServlet; public class LogFileServlet extends AbstractServlet { + private static final String PARAMETER_LOG_FILE = "l"; + private static final long serialVersionUID = 1L; public static final String LOGS_FILE_NAME = "qpid-logs-%s.zip"; public static final String DATE_FORMAT = "yyyy-MM-dd-mmHHss"; - @SuppressWarnings("unchecked") - private LogFileHelper _helper = new LogFileHelper(Collections.list(LogManager.getRootLogger().getAllAppenders())); - @Override protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException @@ -57,7 +56,7 @@ public class LogFileServlet extends AbstractServlet return; } - String[] requestedFiles = request.getParameterValues("l"); + String[] requestedFiles = request.getParameterValues(PARAMETER_LOG_FILE); if (requestedFiles == null || requestedFiles.length == 0) { @@ -65,11 +64,14 @@ public class LogFileServlet extends AbstractServlet return; } + @SuppressWarnings("unchecked") + LogFileHelper helper = new LogFileHelper(Collections.list(LogManager.getRootLogger().getAllAppenders())); + List<LogFileDetails> logFiles = null; try { - logFiles = _helper.findLogFileDetails(requestedFiles); + logFiles = helper.findLogFileDetails(requestedFiles); } catch(IllegalArgumentException e) { @@ -91,7 +93,7 @@ public class LogFileServlet extends AbstractServlet OutputStream os = response.getOutputStream(); try { - _helper.writeLogFiles(logFiles, os); + helper.writeLogFiles(logFiles, os); } finally { diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java index c0f4b55f64..a08d6496bf 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java +++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java @@ -275,4 +275,14 @@ public abstract class AbstractServlet extends HttpServlet mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true); mapper.writeValue(writer, object); } + + protected String[] getPathInfoElements(HttpServletRequest request) + { + String pathInfo = request.getPathInfo(); + if (pathInfo != null && pathInfo.length() > 0) + { + return pathInfo.substring(1).split("/"); + } + return null; + } } diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/HelperServlet.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/HelperServlet.java index 9ba36bb5c2..80ce338d0a 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/HelperServlet.java +++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/HelperServlet.java @@ -35,6 +35,7 @@ import org.apache.qpid.server.management.plugin.servlet.rest.action.ListAccessCo import org.apache.qpid.server.management.plugin.servlet.rest.action.ListAuthenticationProviderAttributes; import org.apache.qpid.server.management.plugin.servlet.rest.action.ListBrokerAttribute; import org.apache.qpid.server.management.plugin.servlet.rest.action.ListGroupProviderAttributes; +import org.apache.qpid.server.management.plugin.servlet.rest.action.ListTimeZones; import org.apache.qpid.server.model.Broker; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.SerializationConfig; @@ -61,7 +62,8 @@ public class HelperServlet extends AbstractServlet new ListBrokerAttribute(Broker.PRODUCT_VERSION, "version"), new ListGroupProviderAttributes(), new ListAccessControlProviderAttributes(), - new PluginClassProviderAction() + new PluginClassProviderAction(), + new ListTimeZones() }; _actions = new HashMap<String, Action>(); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogFileListingServlet.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogFileListingServlet.java index b6face18e3..8b88e51e9c 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogFileListingServlet.java +++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogFileListingServlet.java @@ -36,9 +36,6 @@ public class LogFileListingServlet extends AbstractServlet { private static final long serialVersionUID = 1L; - @SuppressWarnings("unchecked") - private LogFileHelper _helper = new LogFileHelper(Collections.list(LogManager.getRootLogger().getAllAppenders())); - @Override protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException @@ -49,11 +46,13 @@ public class LogFileListingServlet extends AbstractServlet if (!getBroker().getSecurityManager().authoriseLogsAccess()) { - response.sendError(HttpServletResponse.SC_FORBIDDEN, "Log files download is denied"); + response.sendError(HttpServletResponse.SC_FORBIDDEN, "Log files access is denied"); return; } - List<LogFileDetails> logFiles = _helper.getLogFileDetails(false); + @SuppressWarnings("unchecked") + LogFileHelper helper = new LogFileHelper(Collections.list(LogManager.getRootLogger().getAllAppenders())); + List<LogFileDetails> logFiles = helper.getLogFileDetails(false); response.setContentType("application/json"); response.setStatus(HttpServletResponse.SC_OK); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/PreferencesServlet.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LoggedOnUserPreferencesServlet.java index bf2a88a2c1..29cc881be7 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/PreferencesServlet.java +++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LoggedOnUserPreferencesServlet.java @@ -39,7 +39,7 @@ import org.apache.qpid.server.model.PreferencesProvider; import org.apache.qpid.server.security.auth.AuthenticatedPrincipal; import org.codehaus.jackson.map.ObjectMapper; -public class PreferencesServlet extends AbstractServlet +public class LoggedOnUserPreferencesServlet extends AbstractServlet { private static final long serialVersionUID = 1L; @@ -101,7 +101,8 @@ public class PreferencesServlet extends AbstractServlet PreferencesProvider preferencesProvider = getPreferencesProvider(request); if (preferencesProvider == null) { - throw new IllegalStateException("Preferences provider is not configured"); + response.sendError(HttpServletResponse.SC_NOT_FOUND, "Preferences provider is not configured"); + return; } String userName = getAuthenticatedUserName(request); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageContentServlet.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageContentServlet.java index d61c48bb2c..4d85d52997 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageContentServlet.java +++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageContentServlet.java @@ -44,8 +44,8 @@ public class MessageContentServlet extends AbstractServlet @Override protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { - - if(request.getPathInfo() != null && request.getPathInfo().length()>0 && request.getPathInfo().substring(1).split("/").length > 2) + String[] pathInfoElements = getPathInfoElements(request); + if(pathInfoElements != null && pathInfoElements.length > 2) { getMessageContent(request, response); } @@ -55,7 +55,7 @@ public class MessageContentServlet extends AbstractServlet private void getMessageContent(HttpServletRequest request, HttpServletResponse response) throws IOException { Queue queue = getQueueFromRequest(request); - String path[] = request.getPathInfo().substring(1).split("/"); + String path[] = getPathInfoElements(request); MessageFinder finder = new MessageFinder(Long.parseLong(path[2])); queue.visit(finder); if(finder.isFound()) @@ -70,15 +70,15 @@ public class MessageContentServlet extends AbstractServlet private Queue getQueueFromRequest(HttpServletRequest request) { - List<String> names = new ArrayList<String>(); // TODO - validation that there is a vhost and queue and only those in the path - if(request.getPathInfo() != null && request.getPathInfo().length()>0) + + String[] pathInfoElements = getPathInfoElements(request); + if(pathInfoElements == null || pathInfoElements.length < 2) { - String path = request.getPathInfo().substring(1); - names.addAll(Arrays.asList(path.split("/"))); + throw new IllegalArgumentException("Invalid path is specified"); } - String vhostName = names.get(0); - String queueName = names.get(1); + String vhostName = pathInfoElements[0]; + String queueName = pathInfoElements[1]; VirtualHost vhost = null; diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java index 83208516c7..ac0d369402 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java +++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java @@ -56,8 +56,8 @@ public class MessageServlet extends AbstractServlet @Override protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { - - if(request.getPathInfo() != null && request.getPathInfo().length()>0 && request.getPathInfo().substring(1).split("/").length > 2) + String[] pathInfoElements = getPathInfoElements(request); + if(pathInfoElements != null && pathInfoElements.length > 2) { getMessageContent(request, response); } @@ -71,7 +71,7 @@ public class MessageServlet extends AbstractServlet private void getMessageContent(HttpServletRequest request, HttpServletResponse response) throws IOException { Queue queue = getQueueFromRequest(request); - String path[] = request.getPathInfo().substring(1).split("/"); + String path[] = getPathInfoElements(request); MessageFinder messageFinder = new MessageFinder(Long.parseLong(path[2])); queue.visit(messageFinder); @@ -124,15 +124,15 @@ public class MessageServlet extends AbstractServlet private Queue getQueueFromRequest(HttpServletRequest request) { - List<String> names = new ArrayList<String>(); // TODO - validation that there is a vhost and queue and only those in the path - if(request.getPathInfo() != null && request.getPathInfo().length()>0) + + String[] pathInfoElements = getPathInfoElements(request); + if(pathInfoElements == null || pathInfoElements.length < 2) { - String path = request.getPathInfo().substring(1); - names.addAll(Arrays.asList(path.split("/"))); + throw new IllegalArgumentException("Invalid path is specified"); } - String vhostName = names.get(0); - String queueName = names.get(1); + String vhostName = pathInfoElements[0]; + String queueName = pathInfoElements[1]; VirtualHost vhost = null; diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java index 8ea0aa538a..c05b4e30d6 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java +++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java @@ -115,16 +115,15 @@ public class RestServlet extends AbstractServlet protected Collection<ConfiguredObject> getObjects(HttpServletRequest request) { + String[] pathInfoElements = getPathInfoElements(request); List<String> names = new ArrayList<String>(); - if(request.getPathInfo() != null && request.getPathInfo().length()>0) + if(pathInfoElements != null) { - String path = request.getPathInfo().substring(1); - names.addAll(Arrays.asList(path.split("/"))); - - if(names.size() > _hierarchy.length) + if(pathInfoElements.length > _hierarchy.length) { throw new IllegalArgumentException("Too many entries in path. Expected " + _hierarchy.length + "; path: " + names); } + names.addAll(Arrays.asList(pathInfoElements)); } Collection<ConfiguredObject> parents = Collections.singleton((ConfiguredObject) getBroker()); @@ -329,16 +328,15 @@ public class RestServlet extends AbstractServlet List<String> names = new ArrayList<String>(); - if(request.getPathInfo() != null && request.getPathInfo().length()>0) + String[] pathInfoElements = getPathInfoElements(request); + if(pathInfoElements != null ) { - String path = request.getPathInfo().substring(1); - names.addAll(Arrays.asList(path.split("/"))); - - if(names.size() != _hierarchy.length) + if(pathInfoElements.length != _hierarchy.length) { throw new IllegalArgumentException("Path to object to create must be fully specified. " + "Found " + names + " of size " + names.size() + " expecting " + _hierarchy.length); } + names.addAll(Arrays.asList(pathInfoElements)); } if (names.isEmpty()) diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/UserPreferencesServlet.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/UserPreferencesServlet.java index 808e3210dd..355b5df177 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/UserPreferencesServlet.java +++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/UserPreferencesServlet.java @@ -25,7 +25,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; -import java.util.Iterator; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -50,11 +50,7 @@ public class UserPreferencesServlet extends AbstractServlet protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { - String[] pathElements = null; - if (request.getPathInfo() != null && request.getPathInfo().length() > 0) - { - pathElements = request.getPathInfo().substring(1).split("/"); - } + String[] pathElements = getPathInfoElements(request); if (pathElements != null && pathElements.length > 1) { getUserPreferences(pathElements[0], pathElements[1], response); @@ -70,7 +66,7 @@ public class UserPreferencesServlet extends AbstractServlet { if (!userPreferencesOperationAuthorized(userId)) { - response.sendError(HttpServletResponse.SC_FORBIDDEN, "Vieweing of preferences is not allowed"); + response.sendError(HttpServletResponse.SC_FORBIDDEN, "Viewing of preferences is not allowed"); return; } Map<String, Object> preferences = null; @@ -161,53 +157,75 @@ public class UserPreferencesServlet extends AbstractServlet @Override protected void doDeleteWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws IOException { - final List<String[]> userData = new ArrayList<String[]>(); - for (String name : request.getParameterValues("user")) + Broker broker = getBroker(); + Collection<AuthenticationProvider> authenticationProviders = broker.getAuthenticationProviders(); + Map<String, Set<String>> providerUsers = new HashMap<String, Set<String>>(); + Map<String, AuthenticationProvider> requestProviders = new HashMap<String, AuthenticationProvider>(); + for (String path : request.getParameterValues("user")) { - String[] elements = name.split("/"); + String[] elements = path.split("/"); if (elements.length != 2) { - throw new IllegalArgumentException("Illegal parameter"); + throw new IllegalArgumentException("Illegal user parameter " + path); } - userData.add(elements); + + String userId = elements[1]; + + if (!userPreferencesOperationAuthorized(userId)) + { + response.sendError(HttpServletResponse.SC_FORBIDDEN, "Deletion of preferences is not allowed"); + return; + } + String providerName = elements[0]; + Set<String> users = providerUsers.get(providerName); + + if (users == null) + { + AuthenticationProvider provider = findAuthenticationProviderByName(providerName, authenticationProviders); + if (provider == null) + { + throw new IllegalArgumentException("Cannot find provider with name '" + providerName + "'"); + } + users = new HashSet<String>(); + providerUsers.put(providerName, users); + requestProviders.put(providerName, provider); + } + users.add(userId); } - if (!userData.isEmpty()) + if (!providerUsers.isEmpty()) { - Broker broker = getBroker(); - Collection<AuthenticationProvider> authenticationProviders = broker.getAuthenticationProviders(); - for (Iterator<String[]> it = userData.iterator(); it.hasNext();) + for (Map.Entry<String, Set<String>> entry : providerUsers.entrySet()) { - String[] data = (String[]) it.next(); - String authenticationProviderName = data[0]; - String userId = data[1]; + String providerName = entry.getKey(); + AuthenticationProvider provider = requestProviders.get(providerName); + Set<String> usersToDelete = entry.getValue(); + PreferencesProvider preferencesProvider = provider.getPreferencesProvider(); - for (AuthenticationProvider authenticationProvider : authenticationProviders) + if (preferencesProvider != null && !usersToDelete.isEmpty()) { - if (authenticationProviderName.equals(authenticationProvider.getName())) - { - PreferencesProvider preferencesProvider = authenticationProvider.getPreferencesProvider(); - if (preferencesProvider != null) - { - Set<String> usernames = preferencesProvider.listUserIDs(); - if (usernames.contains(userId)) - { - if (!userPreferencesOperationAuthorized(userId)) - { - response.sendError(HttpServletResponse.SC_FORBIDDEN, "Deletion of preferences is not allowed"); - return; - } - preferencesProvider.deletePreferences(userId); - } - } - break; - } + String[] users = usersToDelete.toArray(new String[usersToDelete.size()]); + preferencesProvider.deletePreferences(users); } } } } + protected AuthenticationProvider findAuthenticationProviderByName(String providerName, Collection<AuthenticationProvider> authenticationProviders) + { + AuthenticationProvider provider = null; + for (AuthenticationProvider authenticationProvider : authenticationProviders) + { + if(authenticationProvider.getName().equals(providerName)) + { + provider = authenticationProvider; + break; + } + } + return provider; + } + private boolean userPreferencesOperationAuthorized(String userId) { return getBroker().getSecurityManager().authoriseUserOperation(Operation.UPDATE, userId); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/action/ListTimeZones.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/action/ListTimeZones.java new file mode 100644 index 0000000000..56bc7b1bf7 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/action/ListTimeZones.java @@ -0,0 +1,117 @@ +/* + * + * 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. + * + */ + +package org.apache.qpid.server.management.plugin.servlet.rest.action; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; + +import org.apache.qpid.server.management.plugin.servlet.rest.Action; +import org.apache.qpid.server.model.Broker; + +public class ListTimeZones implements Action +{ + + private static final String[] TIMEZONE_REGIONS = { "Africa", "America", "Antarctica", "Arctic", "Asia", "Atlantic", "Australia", + "Europe", "Indian", "Pacific" }; + + @Override + public String getName() + { + return ListTimeZones.class.getSimpleName(); + } + + @Override + public Object perform(Map<String, Object> request, Broker broker) + { + List<TimeZoneDetails> timeZoneDetails = new ArrayList<TimeZoneDetails>(); + String[] ids = TimeZone.getAvailableIDs(); + long currentTime = System.currentTimeMillis(); + Date currentDate = new Date(currentTime); + for (String id : ids) + { + int cityPos = id.indexOf("/"); + if (cityPos > 0 && cityPos < id.length() - 1) + { + String region = id.substring(0, cityPos); + for (int i = 0; i < TIMEZONE_REGIONS.length; i++) + { + if (region.equals(TIMEZONE_REGIONS[i])) + { + TimeZone tz = TimeZone.getTimeZone(id); + int offset = tz.getOffset(currentTime)/60000; + String city = id.substring(cityPos + 1).replace('_', ' '); + timeZoneDetails.add(new TimeZoneDetails(id, tz.getDisplayName(tz.inDaylightTime(currentDate), TimeZone.SHORT), offset, city, region)); + break; + } + } + } + } + return timeZoneDetails; + } + + public static class TimeZoneDetails + { + private String id; + private String name; + private int offset; + private String city; + private String region; + + public TimeZoneDetails(String id, String name, int offset, String city, String region) + { + super(); + this.id = id; + this.name = name; + this.offset = offset; + this.city = city; + this.region = region; + } + + public String getId() + { + return id; + } + + public String getName() + { + return name; + } + + public int getOffset() + { + return offset; + } + + public String getCity() + { + return city; + } + + public String getRegion() + { + return region; + } + } +} diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/addAuthenticationProvider.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/addAuthenticationProvider.html index f4846ac556..8e2e068b93 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/addAuthenticationProvider.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/addAuthenticationProvider.html @@ -17,7 +17,7 @@ <div class="dijitHidden"> <div data-dojo-type="dijit.Dialog" data-dojo-props="title:'Authentication Provider'" id="addAuthenticationProvider"> <form id="formAddAuthenticationProvider" method="post" dojoType="dijit.form.Form"> - <div style="height:100px; width:420px; overflow: auto"> + <div style="width:420px; overflow: auto"> <table class="tableContainer-table tableContainer-table-horiz" width="100%" cellspacing="1"> <tr> <td class="tableContainer-labelCell" style="width: 200px;">Type*:</td> @@ -32,6 +32,10 @@ </table> <input type="hidden" id="formAddAuthenticationProvider.id" name="id"/> <div id="addAuthenticationProvider.fieldSets"></div> + <br/> + <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Preferences Provider', open: true" id="addAuthenticationProvider.preferencesProviderPanel"> + <div id="addAuthenticationProvider.preferencesProvider"></div> + </div> </div> <div class="dijitDialogPaneActionBar"> <!-- submit buttons --> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/addPreferencesProvider.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/addPreferencesProvider.html index ac5dd32119..bca2320888 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/addPreferencesProvider.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/addPreferencesProvider.html @@ -18,24 +18,8 @@ <div data-dojo-type="dijit.Dialog" data-dojo-props="title:'Preferences Provider'" id="addPreferencesProvider"> <form id="formAddPreferencesProvider" method="post" data-dojo-type="dijit.form.Form"> <input type="hidden" id="preferencesProvider.id" name="id"/> - <div style="height:100px; width:420px; overflow: auto"> - <table class="tableContainer-table tableContainer-table-horiz" width="100%" cellspacing="1"> - <tr> - <td class="tableContainer-labelCell" style="width: 200px;"><strong>Type*:</strong></td> - <td class="tableContainer-valueCell"><div id="addPreferencesProvider.selectPreferencesProviderDiv"></div></td> - </tr> - <tr> - <td class="tableContainer-labelCell" style="width: 200px;"><strong>Name*:</strong></td> - <td class="tableContainer-valueCell"><input type="text" name="name" - id="preferencesProvider.name" data-dojo-type="dijit.form.ValidationTextBox" - data-dojo-props="placeHolder: 'Name', - required: true, - missingMessage: 'A name must be supplied', - title: 'Enter name', - pattern: '^[\x20-\x2e\x30-\x7F]{1,255}$'" /></td> - </tr> - </table> - <div id="preferencesProvider.fieldsContainer"></div> + <div style="width:420px; overflow: auto"> + <div id="addPreferencesProvider.preferencesProvider"></div> </div> <div class="dijitDialogPaneActionBar"> <!-- submit buttons --> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/authenticationprovider/preferences/filesystempreferences/add.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/authenticationprovider/preferences/filesystempreferences/add.html index f46da4b017..7196493e7c 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/authenticationprovider/preferences/filesystempreferences/add.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/authenticationprovider/preferences/filesystempreferences/add.html @@ -18,7 +18,7 @@ <tr> <td class="tableContainer-labelCell" style="width: 200px;"><strong>Path*: </strong></td> <td class="tableContainer-valueCell" > - <input type="text" name="path" + <input type="text" name="preferencesProviderPath" id="preferencesProvider.path" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="placeHolder: 'Path/to/file', diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/common/TimeZoneSelector.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/common/TimeZoneSelector.html index 7027a4555c..2b2fca7d8a 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/common/TimeZoneSelector.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/common/TimeZoneSelector.html @@ -20,36 +20,47 @@ --> <table cellpadding="0" cellspacing="2"> <tr> - <td>Region</td> + <td class="labelClass"><strong>Use UTC time:</strong></td> <td> - <select class='timezoneRegion' name="region" data-dojo-type="dijit/form/FilteringSelect" data-dojo-props=" - placeholder: 'Select region', - required: true, - missingMessage: 'A region must be supplied', - title: 'Select region', - autoComplete: true, - value:'undefined'"> - <option value="undefined">Undefined</option> - <option value="Africa">Africa</option> - <option value="America">America</option> - <option value="Antarctica">Antarctica</option> - <option value="Arctic">Arctic</option> - <option value="Asia">Asia</option> - <option value="Atlantic">Atlantic</option> - <option value="Australia">Australia</option> - <option value="Europe">Europe</option> - <option value="Indian">Indian</option> - <option value="Pacific">Pacific</option> - </select> + <input type="checkbox" class='utcSelector' name="utc" data-dojo-type="dijit/form/CheckBox" value="UTC"></input> </td> - <td>City</td> + </tr> + <tr> + <td class="labelClass"><strong>Time Zone:</strong></td> <td> - <select class='timezoneCity' name="city" data-dojo-type="dijit/form/FilteringSelect" data-dojo-props=" - placeholder: 'Select city', - required: true, - missingMessage: 'A city must be supplied', - title: 'Select city'"> - </select> - </td> + <table cellpadding="0" cellspacing="2"> + <tr> + <td>Region</td> + <td><select class='timezoneRegion' name="region" data-dojo-type="dijit/form/FilteringSelect" + data-dojo-props=" + placeholder: 'Select region', + required: true, + missingMessage: 'A region must be supplied', + title: 'Select region', + autoComplete: true, + value:'undefined'"> + <option value="undefined">Undefined</option> + <option value="Africa">Africa</option> + <option value="America">America</option> + <option value="Antarctica">Antarctica</option> + <option value="Arctic">Arctic</option> + <option value="Asia">Asia</option> + <option value="Atlantic">Atlantic</option> + <option value="Australia">Australia</option> + <option value="Europe">Europe</option> + <option value="Indian">Indian</option> + <option value="Pacific">Pacific</option> + </select></td> + <td>City</td> + <td><select class='timezoneCity' name="city" data-dojo-type="dijit/form/FilteringSelect" + data-dojo-props=" + placeholder: 'Select city', + required: true, + missingMessage: 'A city must be supplied', + title: 'Select city'"> + </select></td> + </tr> + </table> + </td> </tr> </table>
\ No newline at end of file diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/index.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/index.html index 4fc961ec12..f17e8d8bba 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/index.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/index.html @@ -57,32 +57,24 @@ </script> <script> - var qpidHelpLocation = "http://qpid.apache.org/releases/qpid-"; - var qpidHelpURL = null; - var qpidPreferences = null; + var qpidManagementHelper = null; require([ - "dojo/_base/xhr", "dojo/parser", - "qpid/management/Preferences", + "qpid/authorization/checkUser", + "qpid/common/ConsoleHelper", "dijit/layout/BorderContainer", "dijit/layout/TabContainer", "dijit/layout/ContentPane", "dijit/TitlePane", - "dojo/parser", + "dijit/Menu", + "dijit/MenuItem", "qpid/management/treeView", "qpid/management/controller", - "qpid/common/footer", - "qpid/authorization/checkUser"], function(xhr, parser, Preferences){ + "qpid/common/footer" + ], function(parser, User, ConsoleHelper){ parser.parse(); - qpidPreferences = new Preferences(); - xhr.get({ - sync: true, - url: "rest/helper?action=version", - handleAs: "json" - }).then(function(qpidVersion) { - qpidHelpURL = qpidHelpLocation + qpidVersion + "/java-broker/book/index.html"; - }); - + qpidManagementHelper = ConsoleHelper; + User.getUserAndUpdateUI(); }); </script> @@ -93,25 +85,17 @@ <div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'top'"> <div id="header" class="header" style="float: left; width: 300px"></div> <div style="float: right;"> - <div id="login" style="display:none"><strong>User: </strong> <span id="authenticatedUser"></span><a href="logout">[logout]</a></div> - <div id="preferencesButton" style="float: right; margin-top: 0px;" data-dojo-type="dijit.form.DropDownButton" data-dojo-props="iconClass: 'preferencesIcon', title: 'Preferences', showLabel:false"> + <div id="login" style="display:none"><span id="authenticatedUser" style="display:none"></span> + <div id="authenticatedUserControls" data-dojo-type="dijit.form.DropDownButton" data-dojo-props="iconClass: 'preferencesIcon', style:{'max-width': '100px'}"> <div data-dojo-type="dijit.Menu"> - <div data-dojo-type="dijit.MenuItem" data-dojo-props=" - iconClass: 'dijitIconFunction', - onClick: function(){ qpidPreferences.showDialog(); } "> - Preferences - </div> - <!-- - <div data-dojo-type="dijit.MenuItem" data-dojo-props="iconClass: 'dijitIconMail', onClick: function(){ console.log('TODO'); }"> - Contacts - </div> - --> - <div data-dojo-type="dijit.MenuItem" data-dojo-props="iconClass: 'helpIcon', onClick: function(){ - var newWindow = window.open(qpidHelpURL,'QpidHelp','height=600,width=600,scrollbars=1,location=1,resizable=1,status=0,toolbar=0,titlebar=1,menubar=0',true); newWindow.focus(); } "> - Help - </div> + <div data-dojo-type="dijit.MenuItem" data-dojo-props="onClick: function(){window.location='logout';}" >Log out</div> + <div data-dojo-type="dijit.MenuItem" + data-dojo-props="iconClass:'dijitIconFunction',onClick: function(){qpidManagementHelper.showPreferencesDialog();}">Preferences</div> + <div data-dojo-type="dijit.MenuItem" + data-dojo-props="iconClass: 'helpIcon', onClick: function(){qpidManagementHelper.showHelp();}">Help</div> </div> - </div> + </div> + </div> </div> </div> <div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'leading', splitter: true" style="width:20%"> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/checkUser.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/checkUser.js index d65e6c6e07..be9bef3519 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/checkUser.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/checkUser.js @@ -19,19 +19,27 @@ * */ -require(["dojo/dom", +define(["dojo/dom", "qpid/authorization/sasl", + "dijit/registry", "dojox/html/entities", - "dojo/domReady!"], function(dom, sasl, entities){ + "dojo/domReady!"], function(dom, sasl, registry, entities){ var updateUI = function updateUI(data) { if(data.user) { - dom.byId("authenticatedUser").innerHTML = entities.encode(String(data.user)); - dom.byId("login").style.display = "inline"; + var userName = entities.encode(String(data.user)); + var controlButton = registry.byId("authenticatedUserControls"); + if (controlButton) + { + controlButton.set("label", userName); + } + dom.byId("authenticatedUser").innerHTML = userName; + dom.byId("login").style.display = "inline"; } }; -sasl.getUser(updateUI); +return {getUserAndUpdateUI: function(){sasl.getUser(updateUI);}} + }); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/sasl.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/sasl.js index 33e736322f..2d99f886ed 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/sasl.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/sasl.js @@ -18,7 +18,8 @@ * under the License. * */ -define(["dojo/_base/xhr", "dojox/encoding/base64", "dojox/encoding/digests/_base", "dojox/encoding/digests/MD5"], function () { +define(["dojo/_base/xhr", "dojox/encoding/base64", "dojox/encoding/digests/_base", "dojox/encoding/digests/MD5"], + function (xhr, base64, digestsBase, MD5) { var encodeUTF8 = function encodeUTF8(str) { var byteArray = []; @@ -65,7 +66,7 @@ var errorHandler = function errorHandler(error) var saslPlain = function saslPlain(user, password, callbackFunction) { var responseArray = [ 0 ].concat(encodeUTF8( user )).concat( [ 0 ] ).concat( encodeUTF8( password ) ); - var plainResponse = dojox.encoding.base64.encode(responseArray); + var plainResponse = base64.encode(responseArray); // Using dojo.xhrGet, as very little information is being sent dojo.xhrPost({ @@ -95,19 +96,19 @@ var saslCramMD5 = function saslCramMD5(user, password, saslMechanism, callbackFu }).then(function(data) { - var challengeBytes = dojox.encoding.base64.decode(data.challenge); + var challengeBytes = base64.decode(data.challenge); var wa=[]; var bitLength = challengeBytes.length*8; for(var i=0; i<bitLength; i+=8) { wa[i>>5] |= (challengeBytes[i/8] & 0xFF)<<(i%32); } - var challengeStr = dojox.encoding.digests.wordToString(wa).substring(0,challengeBytes.length); + var challengeStr = digestsBase.wordToString(wa).substring(0,challengeBytes.length); - var digest = user + " " + dojox.encoding.digests.MD5._hmac(challengeStr, password, dojox.encoding.digests.outputTypes.Hex); + var digest = user + " " + MD5._hmac(challengeStr, password, digestsBase.outputTypes.Hex); var id = data.id; - var response = dojox.encoding.base64.encode(encodeUTF8( digest )); + var response = base64.encode(encodeUTF8( digest )); dojo.xhrPost({ // The URL of the request @@ -162,7 +163,7 @@ SaslClient.authenticate = function(username, password, callbackFunction) } else if (containsMechanism(mechMap, "CRAM-MD5-HEX")) { - var hashedPassword = dojox.encoding.digests.MD5(password, dojox.encoding.digests.outputTypes.Hex); + var hashedPassword = MD5(password, digestsBase.outputTypes.Hex); saslCramMD5(username, hashedPassword, "CRAM-MD5-HEX", callbackFunction); } else if (containsMechanism(mechMap, "PLAIN")) diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/ConsoleHelper.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/ConsoleHelper.js new file mode 100644 index 0000000000..fdc07f27ca --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/ConsoleHelper.js @@ -0,0 +1,73 @@ +/* + * + * 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(["dojo/_base/xhr", "dojo/domReady!"], function (xhr) { + + var qpidHelpLocation = "http://qpid.apache.org/releases/qpid-"; + var preferencesDialog = null; + var helpURL = null; + var qpidVersion = null; + + return { + showPreferencesDialog: function () { + if (preferencesDialog == null) + { + require(["qpid/management/Preferences", "dojo/ready"], function(PreferencesDialog, ready){ + ready(function(){ + preferencesDialog = new PreferencesDialog(); + preferencesDialog.showDialog(); + }); + }); + } + else + { + preferencesDialog.showDialog(); + } + }, + getVersion: function() + { + if (!qpidVersion) + { + xhr.get({ + sync: true, + url: "rest/helper?action=version", + handleAs: "json" + }).then(function(version) { + qpidVersion = version; + }); + } + return qpidVersion; + }, + getHelpUrl: function() + { + if (!helpURL) + { + helpURL = qpidHelpLocation + this.getVersion() + "/java-broker/book/index.html"; + } + return helpURL; + }, + showHelp: function() + { + var newWindow = window.open(this.getHelpUrl(),'QpidHelp','height=600,width=600,scrollbars=1,location=1,resizable=1,status=0,toolbar=0,titlebar=1,menubar=0', true); + newWindow.focus(); + } + }; + +}); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/TimeZoneSelector.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/TimeZoneSelector.js index 287fbc9619..fa4bd8c873 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/TimeZoneSelector.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/TimeZoneSelector.js @@ -24,43 +24,22 @@ define([ "dojo/dom-construct", "dojo/parser", "dojo/query", + "dojo/dom-style", "dojo/store/Memory", "dijit/_WidgetBase", "dijit/registry", "dojo/text!common/TimeZoneSelector.html", + "qpid/common/timezone", "dijit/form/ComboBox", "dijit/form/FilteringSelect", - "dojox/date/timezone", + "dijit/form/CheckBox", "dojox/validate/us", "dojox/validate/web", "dojo/domReady!"], -function (declare, array, domConstruct, parser, query, Memory, _WidgetBase, registry, template) { +function (declare, array, domConstruct, parser, query, domStyle, Memory, _WidgetBase, registry, template, timezone) { var preferencesRegions = ["Africa","America","Antarctica","Arctic","Asia","Atlantic","Australia","Europe","Indian","Pacific"]; - function initSupportedTimeZones() - { - var supportedTimeZones = []; - var allTimeZones = dojox.date.timezone.getAllZones(); - for(var i = 0; i < allTimeZones.length; i++) - { - var timeZone = allTimeZones[i]; - var elements = timeZone.split("/"); - if (elements.length > 1) - { - for(var j = 0; j<preferencesRegions.length; j++) - { - if (elements[0] == preferencesRegions[j]) - { - supportedTimeZones.push({id: timeZone, region: elements[0], city: elements.slice(1).join("/").replace("_", " ") }) - break; - } - } - } - } - return supportedTimeZones; - } - function initSupportedRegions() { var supportedRegions = [{"id": "undefined", "name": "Undefined"}]; @@ -77,6 +56,7 @@ function (declare, array, domConstruct, parser, query, Memory, _WidgetBase, regi domNode: null, _regionSelector: null, _citySelector: null, + _utcSelector: null, constructor: function(args) { @@ -91,8 +71,17 @@ function (declare, array, domConstruct, parser, query, Memory, _WidgetBase, regi postCreate: function(){ this.inherited(arguments); - var supportedTimeZones = initSupportedTimeZones(); + var self = this; + if (this._args.labelStyle) + { + var nl = query(".labelClass", this.domNode); + array.forEach(nl, function(entry, i){ + domStyle.set(entry, self._args.labelStyle) + }); + } + var supportedTimeZones = timezone.getAllTimeZones(); + this._utcSelector = registry.byNode(query(".utcSelector", this.domNode)[0]); this._citySelector = registry.byNode(query(".timezoneCity", this.domNode)[0]); this._citySelector.set("searchAttr", "city"); this._citySelector.set("query", {region: /.*/}); @@ -105,8 +94,28 @@ function (declare, array, domConstruct, parser, query, Memory, _WidgetBase, regi this._regionSelector = registry.byNode(query(".timezoneRegion", this.domNode)[0]); var supportedRegions = initSupportedRegions(); this._regionSelector.set("store", new Memory({ data: supportedRegions })); - var self = this; + this._utcSelector.on("change", function(value){ + var checked = this.get("checked"); + if (checked) + { + self.value ="UTC"; + } + else + { + if (self._citySelector.value && self._regionSelector.value) + { + self.value = self._citySelector.value; + } + else + { + self.value = null; + } + } + self._citySelector.set("disabled", checked); + self._regionSelector.set("disabled", checked); + self._handleOnChange(self.value); + }); this._regionSelector.on("change", function(value){ if (value=="undefined") { @@ -114,6 +123,7 @@ function (declare, array, domConstruct, parser, query, Memory, _WidgetBase, regi self._citySelector.query.region = /.*/; self.value = null; self._citySelector.set("value", null); + self._handleOnChange(self.value); } else { @@ -133,6 +143,7 @@ function (declare, array, domConstruct, parser, query, Memory, _WidgetBase, regi this._citySelector.on("change", function(value){ self.value = value; + self._handleOnChange(value); }); this._setValueAttr(this._args.value); @@ -142,23 +153,33 @@ function (declare, array, domConstruct, parser, query, Memory, _WidgetBase, regi { if (value) { - var elements = value.split("/"); - if (elements.length > 1) + if (value == "UTC") { - this._regionSelector.timeZone = value; - this._regionSelector.set("value", elements[0]); - this._citySelector.set("value", value); + this._utcSelector.set("checked", true); } else { - this._regionSelector.set("value", "undefined"); + this._utcSelector.set("checked", false); + var elements = value.split("/"); + if (elements.length > 1) + { + this._regionSelector.timeZone = value; + this._regionSelector.set("value", elements[0]); + this._citySelector.set("value", value); + } + else + { + this._regionSelector.set("value", "undefined"); + } } } else { + this._utcSelector.set("checked", false); this._regionSelector.set("value", "undefined"); } this.value = value; + this._handleOnChange(value); }, destroy: function() @@ -170,6 +191,26 @@ function (declare, array, domConstruct, parser, query, Memory, _WidgetBase, regi } _regionSelector: null; _citySelector: null; + _utcSelector: null; + }, + + onChange: function(newValue){}, + + _handleOnChange: function(newValue) + { + if (this._lastValueReported != newValue) + { + this._lastValueReported = newValue; + if(this._onChangeHandle) + { + this._onChangeHandle.remove(); + } + this._onChangeHandle = this.defer(function() + { + this._onChangeHandle = null; + this.onChange(newValue); + }); + } } }); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/EnhancedFilter.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/EnhancedFilter.js index 9c0baf3111..262210f879 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/EnhancedFilter.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/EnhancedFilter.js @@ -89,16 +89,14 @@ define([ if(typeof args.ruleCount != 'number' || args.ruleCount < 0){ args.ruleCount = 0; } - var rc = this.ruleCountToConfirmClearFilter = args.ruleCountToConfirmClearFilter; - if(rc === undefined){ - this.ruleCountToConfirmClearFilter = 5; - } + this.ruleCountToConfirmClearFilter = args.ruleCountToConfirmClearFilter || 5; if (args.filterHidden){ this.filterHidden = args.filterHidden; } this.defaulGridRowLimit = args.defaulGridRowLimit; this.disableFiltering = args.disableFiltering; + this.displayLastUpdateTime = args.displayLastUpdateTime; //Install UI components var obj = { "plugin": this }; @@ -117,6 +115,7 @@ define([ }); this.filterDefDialog = new FilterDefDialog(obj); + this.filterDefDialog.filterDefPane._clearFilterBtn.set("label", "Clear Filter"); nls["statusTipTitleNoFilter"] = "Filter is not set"; nls["statusTipMsg"] = "Click on 'Set Filter' button to specify filtering conditions"; @@ -149,7 +148,9 @@ define([ filterDefDialog: this.filterDefDialog, defaulGridRowLimit: this.defaulGridRowLimit, disableFiltering: this.disableFiltering, - nls: nls + displayLastUpdateTime: this.displayLastUpdateTime, + nls: nls, + ruleCountToConfirmClearFilter: this.ruleCountToConfirmClearFilter }); this.filterBar.placeAt(this.grid.viewsHeaderNode, "before"); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/EnhancedFilterTools.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/EnhancedFilterTools.js index b1645b4905..187ed8cfc6 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/EnhancedFilterTools.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/EnhancedFilterTools.js @@ -22,12 +22,15 @@ define([ "dojo/_base/declare", "dojo/_base/event", + "dojo/dom-construct", + "dojo/date/locale", "dijit/form/Button", "dijit/form/ToggleButton", "qpid/common/grid/RowNumberLimitDialog", "qpid/common/grid/ColumnDefDialog", - "qpid/common/grid/FilterSummary" -], function(declare, event, Button, ToggleButton, RowNumberLimitDialog, ColumnDefDialog, FilterSummary){ + "qpid/common/grid/FilterSummary", + "qpid/management/UserPreferences" +], function(declare, event, domConstruct, locale, Button, ToggleButton, RowNumberLimitDialog, ColumnDefDialog, FilterSummary, UserPreferences){ var _stopEvent = function (evt){ try{ @@ -64,6 +67,8 @@ define([ this.filterStatusTip= params.filterStatusTip; this.clearFilterDialog = params.clearFilterDialog; this.filterDefDialog = params.filterDefDialog; + this.ruleCountToConfirmClearFilter = params.ruleCountToConfirmClearFilter; + this.displayLastUpdateTime = params.hasOwnProperty("displayLastUpdateTime")?params.displayLastUpdateTime:true; this._addRefreshButtons(); this._addRowLimitButton(params.defaulGridRowLimit); @@ -167,6 +172,38 @@ define([ this.filterBar.addChild(this.autoRefreshButton); this.filterBar.addChild(this.refreshButton); + + if (this.displayLastUpdateTime) + { + var updateStatusPanel = domConstruct.create("div"); + var updateTimeLabel = domConstruct.create("span", {innerHTML: "Update time: ", "class": "formLabel-labelCell", "style": "padding-right: 5px;padding-left: 5px"}, updateStatusPanel); + var updateTimeLabelPreferredTZ = domConstruct.create("span", {innerHTML: "Preferred timezone:", "style": "padding-right: 5px"}, updateStatusPanel); + var updateTimePreferredTZ = domConstruct.create("span", {"style": "padding-right: 5px"}, updateStatusPanel); + var updateTimeLabelBrowserTZ = domConstruct.create("span", {innerHTML: "Browser timezone:", "style": "padding-right: 5px"}, updateStatusPanel); + var updateTimeBrowserTZ = domConstruct.create("span", {"style": "padding-right: 5px"}, updateStatusPanel); + + var lastUpdateTimeUpdater = function(data) + { + var userTimeZone = UserPreferences.timeZone; + var displayStyle = userTimeZone? "inline" : "none"; + updateTimeLabelPreferredTZ.style.display = displayStyle; + updateTimePreferredTZ.style.display = displayStyle; + var formatOptions = {selector: "time", timePattern: "HH:mm:ss.SSS", appendTimeZone: true, addOffset: true}; + var updateTime = new Date(); + updateTimePreferredTZ.innerHTML = UserPreferences.formatDateTime(updateTime.getTime(), formatOptions); + updateTimeBrowserTZ.innerHTML = locale.format(updateTime, formatOptions); + }; + + if (self.grid.updater.store) + { + // data have been already provided/or fetched + // set last update time to current time + lastUpdateTimeUpdater(); + } + + self.grid.updater.addOnUpdate(lastUpdateTimeUpdater); + domConstruct.place(updateStatusPanel, this.grid.viewsHeaderNode, "before"); + } }, _addRowLimitButton: function(defaulGridRowLimit) @@ -240,6 +277,9 @@ define([ this.filterDefButton.on("click", function(e){ _stopEvent(e); + + // a bit of a hack to force dialog to rebuild the criteria controls in order to get rid from empty rule controls + self.filterDefDialog._criteriasChanged = true; self.filterDefDialog.showDialog(); }); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/GridUpdater.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/GridUpdater.js index 7016e4eb5b..8d58b6dec0 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/GridUpdater.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/grid/GridUpdater.js @@ -39,7 +39,12 @@ define(["dojo/_base/xhr", this.updatable = args.hasOwnProperty("updatable") ? args.updatable : true ; this.serviceUrl = args.serviceUrl; - this.onUpdate = args.onUpdate; + this.onUpdate = []; + if (args.onUpdate) + { + this.onUpdate.push(args.onUpdate); + } + this.dataTransformer = args.dataTransformer; this.appendData = args.append; this.appendLimit = args.appendLimit; @@ -122,6 +127,10 @@ define(["dojo/_base/xhr", function processData(data) { + if (self.dataTransformer) + { + data = self.dataTransformer(data); + } var dataSet = false; if (!store) { @@ -141,17 +150,10 @@ define(["dojo/_base/xhr", if (data) { - try - { - if ((dataSet || self.updateOrAppend(data)) && self.onUpdate) - { - self.onUpdate(data); - } - } - catch(e) - { - console.error(e); - } + if ((dataSet || self.updateOrAppend(data)) && self.onUpdate.length > 0) + { + self.fireUpdate(data); + } } }; @@ -186,6 +188,7 @@ define(["dojo/_base/xhr", this.store = null; this.memoryStore = null; this.grid = null; + this.onUpdate = null; }; GridUpdater.prototype.updateOrAppend = function(data) @@ -197,6 +200,10 @@ define(["dojo/_base/xhr", GridUpdater.prototype.refresh = function(data) { + if (this.dataTransformer && data) + { + data = this.dataTransformer(data); + } this.updating = true; try { @@ -223,10 +230,7 @@ define(["dojo/_base/xhr", finally { this.updating = false; - if (this.onUpdate) - { - this.onUpdate(data); - } + this.fireUpdate(data); } } @@ -254,5 +258,40 @@ define(["dojo/_base/xhr", } }; + GridUpdater.prototype.fireUpdate=function(data) + { + if (this.onUpdate.length > 0) + { + for(var i=0; i<this.onUpdate.length;i++) + { + var onUpdate= this.onUpdate[i]; + try + { + onUpdate(data); + } + catch(e) + { + if (console && console.error) + { + console.error(e); + } + } + } + } + }; + + GridUpdater.prototype.addOnUpdate = function(obj) { + this.onUpdate.push(obj); + }; + + GridUpdater.prototype.removeOnUpdate = function(obj) { + for(var i = 0; i < this.onUpdate.length; i++) { + if(this.onUpdate[i] === obj) { + this.onUpdate.splice(i,1); + return; + } + } + }; + return GridUpdater; }); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/timezone.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/timezone.js new file mode 100644 index 0000000000..d03b44843a --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/timezone.js @@ -0,0 +1,95 @@ +/* + * + * 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(["dojo/_base/xhr"], function (xhr) { + + var timezones = {}; + + var timeZoneSortFunction = function(a, b){ + if (a.region == b.region) + { + if (a.city == b.city) + { + return 0; + } + return a.city < b.city ? -1 : 1; + } + return a.region < b.region ? -1 : 1; + } + + function loadTimezones() + { + xhr.get({ + url: "rest/helper?action=ListTimeZones", + sync: true, + handleAs: "json", + load: function(zones) + { + zones.sort(timeZoneSortFunction); + timezones.data = zones; + }, + error: function(error) + { + if (console && console.error) + { + console.error(error); + } + } + }); + } + + return { + getAllTimeZones: function() + { + if (!timezones.data) + { + loadTimezones(); + } + return timezones.data; + }, + getTimeZoneInfo: function(timeZone) { + if (timeZone == "UTC") + { + return { + "id" : "UTC", + "name" : "UTC", + "offset" : 0 + } + } + var tzi = timezones[timeZone]; + if (!tzi) + { + var data = this.getAllTimeZones(); + for(var i = 0; i < data.length; i++) + { + var zone = data[i]; + if (zone.id == timeZone) + { + tzi = zone; + timezones[timeZone] = zone; + break; + } + } + } + return tzi; + } + }; +});
\ No newline at end of file diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/updater.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/updater.js index 86bbaa46ba..f31fd1aa1f 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/updater.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/updater.js @@ -18,15 +18,35 @@ * under the License. * */ -define(function () { +define(["qpid/management/UserPreferences"], function (UserPreferences) { var updateList = new Array(); - setInterval(function() { - for(var i = 0; i < updateList.length; i++) { - var obj = updateList[i]; - obj.update(); - } - }, 5000); // TODO: Should make this configurable + function invokeUpdates() + { + for(var i = 0; i < updateList.length; i++) + { + var obj = updateList[i]; + obj.update(); + } + } + + var updatePeriod = UserPreferences.updatePeriod ? UserPreferences.updatePeriod: 5; + + var timer = setInterval(invokeUpdates, updatePeriod * 1000); + + var updateIntervalListener = { + onPreferencesChange: function(preferences) + { + if (preferences.updatePeriod && preferences.updatePeriod != updatePeriod) + { + updatePeriod = preferences.updatePeriod; + clearInterval(timer); + timer = setInterval(invokeUpdates, updatePeriod * 1000); + } + } + }; + + UserPreferences.addListener(updateIntervalListener); return { add: function(obj) { diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/AuthenticationProvider.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/AuthenticationProvider.js index b5b4380a0d..4e96f2e5a4 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/AuthenticationProvider.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/AuthenticationProvider.js @@ -237,18 +237,15 @@ define(["dojo/_base/xhr", } } var preferencesProviderData = that.authProviderData.preferencesproviders? that.authProviderData.preferencesproviders[0]: null; - if (preferencesProviderData) + try { - try - { - that.updatePreferencesProvider(preferencesProviderData); - } - catch(e) + that.updatePreferencesProvider(preferencesProviderData); + } + catch(e) + { + if (console) { - if (console) - { - console.error(e); - } + console.error(e); } } }); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Preferences.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Preferences.js index 735a657c61..64299d62f6 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Preferences.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Preferences.js @@ -34,6 +34,7 @@ define([ "qpid/common/TimeZoneSelector", "dojo/text!../../showPreferences.html", "qpid/common/util", + "qpid/management/UserPreferences", "dijit/Dialog", "dijit/form/NumberSpinner", "dijit/form/CheckBox", @@ -43,26 +44,26 @@ define([ "dijit/form/DropDownButton", "dijit/form/Button", "dijit/form/Form", + "dijit/layout/BorderContainer", "dijit/layout/TabContainer", "dijit/layout/ContentPane", "dojox/grid/EnhancedGrid", "dojox/validate/us", "dojox/validate/web", "dojo/domReady!"], -function (declare, xhr, event, connect, dom, domConstruct, parser, json, Memory, ObjectStore, entities, registry, TimeZoneSelector, markup, util) { +function (declare, xhr, event, connect, dom, domConstruct, parser, json, Memory, ObjectStore, entities, registry, TimeZoneSelector, markup, util, UserPreferences) { - var preferenceNames = ["timeZone", "updatePeriod", "saveTabs"]; + var preferenceNames = ["timeZone", "updatePeriod"]; return declare("qpid.management.Preferences", null, { preferencesDialog: null, - saveButton: null, - cancelButton: null, constructor: function() { var that = this; + this.userPreferences = {}; this.domNode = domConstruct.create("div", {innerHTML: markup}); this.preferencesDialog = parser.parse(this.domNode)[0]; @@ -70,84 +71,41 @@ function (declare, xhr, event, connect, dom, domConstruct, parser, json, Memory, { var name = preferenceNames[i]; this[name] = registry.byId("preferences." + name); + this[name].on("change", function(val){that._toggleSetButtons();}); } - this.saveButton = registry.byId("preferences.saveButton"); - this.cancelButton = registry.byId("preferences.cancelButton"); + this.setButton = registry.byId("preferences.setButton"); + this.setAndCloseButton = registry.byId("preferences.setAndCloseButton"); + this.setButton.on("click", function(e){that._savePreferences(e, false);}); + this.setAndCloseButton.on("click", function(e){that._savePreferences(e, true);}); this.theForm = registry.byId("preferences.preferencesForm"); - this.users = registry.byId("preferences.users"); - this.users.set("structure", [ { name: "User", field: "name", width: "50%"}, + this.usersGrid = registry.byId("preferences.users"); + this.usersGrid.set("structure", [ { name: "User", field: "name", width: "50%"}, { name: "Authentication Provider", field: "authenticationProvider", width: "50%"}]); - this.cancelButton.on("click", function(){that.preferencesDialog.hide();}); - this.deletePreferencesButton = registry.byId("preferences.deletePreeferencesButton"); - this.deletePreferencesButton.on("click", function(){ - if (util.deleteGridSelections( - null, - that.users, - "rest/userpreferences", - "Are you sure you want to delete preferences for user", - "user")) - { - that._updateUsersWithPreferences(); - } - }); + this.deleteButton = registry.byId("preferences.deleteButton"); + this.deleteAndCloseButton = registry.byId("preferences.deleteAndCloseButton"); + this.deleteButton.on("click", function(e){that._deletePreferences(false);}); + this.deleteAndCloseButton.on("click", function(e){that._deletePreferences(true);}); + var deletePreferencesButtonToggler = function(rowIndex){ - var data = that.users.selection.getSelected(); - that.deletePreferencesButton.set("disabled",!data.length ); + var data = that.usersGrid.selection.getSelected(); + that.deleteButton.set("disabled",!data.length ); + that.deleteAndCloseButton.set("disabled",!data.length ); }; - connect.connect(this.users.selection, 'onSelected', deletePreferencesButtonToggler); - connect.connect(this.users.selection, 'onDeselected', deletePreferencesButtonToggler); - this.theForm.on("submit", function(e){ - event.stop(e); - if(that.theForm.validate()){ - var preferences = {}; - for(var i=0; i<preferenceNames.length; i++) - { - var name = preferenceNames[i]; - var preferenceWidget = that[name]; - if (preferenceWidget) - { - preferences[name] = preferenceWidget.get("value"); - } - } - xhr.post({ - url: "rest/preferences", - sync: true, - handleAs: "json", - headers: { "Content-Type": "application/json"}, - postData: json.stringify(preferences), - load: function(x) {that.success = true; }, - error: function(error) {that.success = false; that.failureReason = error;} - }); - if(that.success === true) - { - that.preferencesDialog.hide(); - } - else - { - alert("Error:" + that.failureReason); - } - } - return false; - }); + connect.connect(this.usersGrid.selection, 'onSelected', deletePreferencesButtonToggler); + connect.connect(this.usersGrid.selection, 'onDeselected', deletePreferencesButtonToggler); + this.theForm.on("submit", function(e){event.stop(e); return false;}); + + this._setValues(); + + deletePreferencesButtonToggler(); this.preferencesDialog.startup(); }, showDialog: function(){ - var that = this; - xhr.get({ - url: "rest/preferences", - sync: true, - handleAs: "json", - load: function(data) { - that._updatePreferencesWidgets(data); - that._updateUsersWithPreferences(); - that.preferencesDialog.show(); - }, - error: function(error){ - alert("Cannot load user preferences : " + error); - } - }); + this._setValues(); + this._loadUserPreferences(); + this.preferencesDialog.show(); }, destroy: function() @@ -159,24 +117,114 @@ function (declare, xhr, event, connect, dom, domConstruct, parser, json, Memory, } }, - _updatePreferencesWidgets: function(data) + _savePreferences: function(e, hideDialog) { - for(var i=0; i<preferenceNames.length; i++) + var that =this; + event.stop(e); + if(this.theForm.validate()){ + var preferences = {}; + for(var i=0; i<preferenceNames.length; i++) + { + var name = preferenceNames[i]; + var preferenceWidget = this[name]; + if (preferenceWidget) + { + preferences[name] = preferenceWidget.hasOwnProperty("checked") ? preferenceWidget.checked : preferenceWidget.get("value"); + } + } + + UserPreferences.setPreferences( + preferences, + function(preferences) + { + success = true; + if (hideDialog) + { + that.preferencesDialog.hide(); + } + else + { + var reloadUsers = true; + if (that.users) + { + var authenticatedUser = dom.byId("authenticatedUser").innerHTML; + for(var i=0; i<that.users.length; i++) + { + if (that.users[i].name == authenticatedUser) + { + reloadUsers = false; + break; + } + } + } + if (reloadUsers) + { + that._loadUserPreferences(); + } + } + that._toggleSetButtons(); + }, + function(error){alert("Error:" + error);} + ); + } + }, + + _deletePreferences: function(hideDialog){ + var data = this.usersGrid.selection.getSelected(); + if (util.deleteGridSelections( + null, + this.usersGrid, + "rest/userpreferences", + "Are you sure you want to delete preferences for user", + "user")) + { + this._loadUserPreferences(); + var authenticatedUser = dom.byId("authenticatedUser").innerHTML; + for(i = 0; i<data.length; i++) + { + if (data[i].name == authenticatedUser) + { + UserPreferences.resetPreferences(); + this._setValues(); + break; + } + } + if (hideDialog) + { + this.preferencesDialog.hide(); + } + } + }, + + _setValues: function() + { + for(var i = 0; i < preferenceNames.length; i++) { - var preference = preferenceNames[i]; - if (this.hasOwnProperty(preference)) + var name = preferenceNames[i]; + var preferenceWidget = this[name]; + if (preferenceWidget) { - var value = data ? data[preference] : null; + var value = UserPreferences[name] if (typeof value == "string") { value = entities.encode(String(value)) } - this[preference].set("value", value); + if (!value && name == "updatePeriod") + { + // set to default + value = 5; + } + preferenceWidget.set("value", value); + if (preferenceWidget.hasOwnProperty("checked")) + { + preferenceWidget.set("checked", UserPreferences[name] ? true : false); + } } } + this._toggleSetButtons(); }, - _updateUsersWithPreferences: function() + _loadUserPreferences : function() { var that = this; xhr.get({ @@ -189,15 +237,37 @@ function (declare, xhr, event, connect, dom, domConstruct, parser, json, Memory, { users[i].id = users[i].authenticationProvider + "/" + users[i].name; } + that.users = users; var usersStore = new Memory({data: users, idProperty: "id"}); var usersDataStore = new ObjectStore({objectStore: usersStore}); - if (that.users.store) + if (that.usersGrid.store) { - that.users.store.close(); + that.usersGrid.store.close(); } - that.users.set("store", usersDataStore); - that.users._refresh(); + that.usersGrid.set("store", usersDataStore); + that.usersGrid._refresh(); }); + }, + + _toggleSetButtons: function() + { + var changed = false; + for(var i=0; i<preferenceNames.length; i++) + { + var name = preferenceNames[i]; + var preferenceWidget = this[name]; + if (preferenceWidget) + { + var value = preferenceWidget.hasOwnProperty("checked") ? preferenceWidget.checked : preferenceWidget.get("value"); + if (value != UserPreferences[name]) + { + changed = true; + break; + } + } + } + this.setButton.set("disabled", !changed); + this.setAndCloseButton.set("disabled", !changed); } }); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/PreferencesProviderFields.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/PreferencesProviderFields.js new file mode 100644 index 0000000000..ebf06377f4 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/PreferencesProviderFields.js @@ -0,0 +1,189 @@ +/* + * + * 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(["dojo/_base/xhr", + "dojo/dom", + "dojo/query", + "dojo/parser", + "dojo/string", + "dojo/json", + "dojo/store/Memory", + "dijit/registry", + "dijit/form/FilteringSelect", + "dijit/form/ValidationTextBox", + "dojox/html/entities", + "dojo/text!../../showPreferencesProviderFields.html", + "dojo/text!rest/helper?action=ListPreferencesProvidersTypes", + "dojox/validate/us", + "dojox/validate/web", + "dojo/domReady!"], function (xhr, dom, query, parser, string, json, Memory, registry, FilteringSelect, ValidationTextBox, entities, template, preferencesProvidersTypes) { + + var PreferencesProviderFields = {}; + + var types = [{id: "", name: "None"}]; + var typesArray = json.parse(preferencesProvidersTypes); + for (var i =0 ; i < typesArray.length; i++) + { + types.push({id: typesArray[i], name: typesArray[i]}); + } + + var selectPreferencesProviderType = function(type) + { + if(type && string.trim(type) != "") + { + var disableOnEditing = PreferencesProviderFields.data? true: false; + PreferencesProviderFields.name.set("disabled", disableOnEditing); + PreferencesProviderFields.type.set("disabled", disableOnEditing); + if (PreferencesProviderFields.currentType != type) + { + require(["qpid/management/authenticationprovider/preferences/" + type.toLowerCase() + "/add"], + function(typeFields) + { + PreferencesProviderFields.currentType = null; + if (PreferencesProviderFields.details ) + { + PreferencesProviderFields.details.destroy(); + } + PreferencesProviderFields.details = typeFields; + typeFields.show(PreferencesProviderFields.fieldsContainer, PreferencesProviderFields.data); + PreferencesProviderFields.currentType = type; + }); + } + else + { + PreferencesProviderFields.details.disable(false); + } + } + else + { + PreferencesProviderFields.disable(true); + } + }; + + PreferencesProviderFields.init = function(data) + { + this.data = data; + this.id.value = data.id; + this.name.set("value", data.name); + this.type.set("value", data.type); + selectPreferencesProviderType(data.type); + }; + + PreferencesProviderFields.show = function(node, provider, authenticationProviderName) + { + this.currentType = null; + this.data = null; + node.innerHTML = template; + try + { + parser.parse(node); + } + catch(e) + { + console.error(e); + return; + } + + if (this.container) + { + this.container.destroyRecursive(); + } + if (this.details ) + { + this.details.destroy(); + delete this["details"]; + } + this.container = registry.byNode(query(".preferencesProviderContainer", node)[0]); + this.fieldsContainer = query(".preferencesProviderFieldsContainer", node)[0]; + this.type = registry.byNode(query(".preferencesProviderType", node)[0]); + this.name = registry.byNode(query(".preferencesProviderName", node)[0]); + this.id = query("input[name='preferencesProviderId']", node)[0]; + this.id.value = null; + this.type.set("store", new Memory({ data: types, idProperty: "id"})); + this.type.on("change", selectPreferencesProviderType ); + this.type.startup(); + + if (provider) + { + if (typeof provider == "object") + { + this.init(provider); + } + else if (typeof provider == "string") + { + var that = this; + xhr.get({ + url: "rest/preferencesprovider/" +encodeURIComponent(authenticationProviderName) + "/" + encodeURIComponent(provider), + sync: true, + handleAs: "json" + }).then(function(data){if (data && data[0]) { that.init(data[0]);}}); + } + } + else + { + this.disable(true); + } + }; + + PreferencesProviderFields.disable = function(val) + { + this.name.set("disabled", val); + if (this.details) + { + this.details.disable(val); + } + }; + + PreferencesProviderFields.getValues = function() + { + var values = {}; + if (this.details) + { + values = this.details.getValues() || {}; + } + values.name = this.name.get("value"); + if (this.id.value) + { + values.id = this.id.value; + } + values.type = this.type.get("value"); + return values; + }; + + PreferencesProviderFields.save = function(authenticationProviderName) + { + var success = true; + if (this.type.value) + { + var data = this.getValues(); + xhr.put({url: "rest/preferencesprovider/" +encodeURIComponent(authenticationProviderName) + "/" + encodeURIComponent(data.name), + sync: true, + handleAs: "json", + headers: { "Content-Type": "application/json"}, + putData: json.stringify(data), + load: function(x) {success = true;}, + error: function(error) {success = false; alert("Preferences Provider Error: " + error);}}); + } + return success; + }; + + return PreferencesProviderFields; + +});
\ No newline at end of file diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Queue.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Queue.js index a47b24d1ab..83974535a1 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Queue.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Queue.js @@ -33,6 +33,7 @@ define(["dojo/_base/xhr", "qpid/management/addBinding", "qpid/management/moveCopyMessages", "qpid/management/showMessage", + "qpid/management/UserPreferences", "dojo/store/JsonRest", "dojox/grid/EnhancedGrid", "dojo/data/ObjectStore", @@ -41,7 +42,7 @@ define(["dojo/_base/xhr", "dojox/grid/enhanced/plugins/IndirectSelection", "dojo/domReady!"], function (xhr, parser, query, registry, connect, event, json, properties, updater, util, formatter, - UpdatableStore, addBinding, moveMessages, showMessage, JsonRest, EnhancedGrid, ObjectStore, entities) { + UpdatableStore, addBinding, moveMessages, showMessage, UserPreferences, JsonRest, EnhancedGrid, ObjectStore, entities) { function Queue(name, parent, controller) { this.name = name; @@ -98,10 +99,7 @@ define(["dojo/_base/xhr", {name:"Arrival", field:"arrivalTime", width: "100%", formatter: function(val) { - var d = new Date(0); - d.setUTCSeconds(val/1000); - - return d.toLocaleString(); + return UserPreferences.formatDateTime(val, {addOffset: true, appendTimeZone: true}); } } ], plugins: { @@ -164,6 +162,7 @@ define(["dojo/_base/xhr", event.stop(evt); that.deleteQueue(); }); + UserPreferences.addListener(that); }}); @@ -237,6 +236,12 @@ define(["dojo/_base/xhr", Queue.prototype.close = function() { updater.remove( this.queueUpdater ); + UserPreferences.removeListener(this); + }; + + Queue.prototype.onPreferencesChange = function(data) + { + this.grid._refresh(); }; var queueTypeKeys = { @@ -385,10 +390,12 @@ define(["dojo/_base/xhr", var bindings = thisObj.queueData[ "bindings" ]; var consumers = thisObj.queueData[ "consumers" ]; - for(i=0; i < bindings.length; i++) { + if (bindings) + { + for(i=0; i < bindings.length; i++) { bindings[i].argumentString = json.stringify(bindings[i].arguments); + } } - thisObj.updateHeader(); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/UserPreferences.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/UserPreferences.js new file mode 100644 index 0000000000..89a22a9e6e --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/UserPreferences.js @@ -0,0 +1,252 @@ +/* + * + * 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(["dojo/_base/xhr", + "dojo/json", + "dojo/date", + "dojo/date/locale", + "dojo/number", + "qpid/common/timezone"], function (xhr, json, date, locale, number, timezone) { + + var listeners = []; + + var UserPreferences = { + + /* set time zone to 'UTC' by default*/ + timeZone: "UTC", + + loadPreferences : function(callbackSuccessFunction, callbackErrorFunction) + { + var that = this; + xhr.get({ + url: "rest/preferences", + sync: true, + handleAs: "json", + load: function(data) + { + for(var name in data) + { + that[name] = data[name]; + } + if (callbackSuccessFunction) + { + callbackSuccessFunction(); + } + }, + error: function(error) + { + if (callbackErrorFunction) + { + callbackErrorFunction(error); + } + } + }); + }, + + setPreferences : function(preferences, callbackSuccessFunction, callbackErrorFunction) + { + var that = this; + xhr.post({ + url: "rest/preferences", + sync: true, + handleAs: "json", + headers: { "Content-Type": "application/json"}, + postData: json.stringify(preferences), + load: function(x) + { + for(var name in preferences) + { + if (preferences.hasOwnProperty(name)) + that[name] = preferences[name]; + } + that._notifyListeners(preferences); + if (callbackSuccessFunction) + { + callbackSuccessFunction(preferences); + } + }, + error: function(error) + { + if (callbackErrorFunction) + { + callbackErrorFunction(error); + } + } + }); + }, + + resetPreferences : function() + { + var preferences = {}; + for(var name in this) + { + if (this.hasOwnProperty(name) && typeof this[name] != "function") + { + if (name == "preferencesError") + { + continue; + } + this[name] = null; + preferences[name] = undefined; + delete preferences[name]; + } + } + this._notifyListeners(preferences); + }, + + addListener : function(obj) + { + listeners.push(obj); + }, + + removeListener : function(obj) + { + for(var i = 0; i < listeners.length; i++) + { + if(listeners[i] === obj) + { + listeners.splice(i,1); + return; + } + } + }, + + _notifyListeners : function(preferences) + { + for(var i = 0; i < listeners.length; i++) + { + try + { + listeners[i].onPreferencesChange(preferences); + } + catch(e) + { + if (console && console.warn) + { + console.warn(e); + } + } + } + }, + + getTimeZoneInfo : function(timeZoneName) + { + if (!timeZoneName && this.timeZone) + { + timeZoneName = this.timeZone; + } + + if (!timeZoneName) + { + return null; + } + + return timezone.getTimeZoneInfo(timeZoneName); + }, + + addTimeZoneOffsetToUTC : function(utcTimeInMilliseconds, timeZone) + { + var tzi = null; + if (timeZone && timeZone.hasOwnProperty("offset")) + { + tzi = timeZone; + } + else + { + tzi = this.getTimeZoneInfo(timeZone); + } + + if (tzi) + { + var browserTimeZoneOffsetInMinutes = -new Date().getTimezoneOffset(); + return utcTimeInMilliseconds + ( tzi.offset - browserTimeZoneOffsetInMinutes ) * 60000; + } + return utcTimeInMilliseconds; + }, + + getTimeZoneDescription : function(timeZone) + { + var tzi = null; + if (timeZone && timeZone.hasOwnProperty("offset")) + { + tzi = timeZone; + } + else + { + tzi = this.getTimeZoneInfo(timeZone); + } + + if (tzi) + { + var timeZoneOfsetInMinutes = tzi.offset; + return (timeZoneOfsetInMinutes>0? "+" : "") + + number.format(timeZoneOfsetInMinutes/60, {pattern: "00"}) + + ":" + number.format(timeZoneOfsetInMinutes%60, {pattern: "00"}) + + " " + tzi.name; + } + return date.getTimezoneName(new Date()); + }, + + formatDateTime : function(utcTimeInMilliseconds, options) + { + var dateTimeOptions = options || {}; + var tzi = this.getTimeZoneInfo(dateTimeOptions.timeZoneName); + var timeInMilliseconds = utcTimeInMilliseconds; + + if (tzi && dateTimeOptions.addOffset) + { + timeInMilliseconds = this.addTimeZoneOffsetToUTC(utcTimeInMilliseconds, tzi); + } + + var d = new Date(timeInMilliseconds); + + var formatOptions = { + datePattern: dateTimeOptions.datePattern || "yyyy-MM-dd", + timePattern: dateTimeOptions.timePattern || "HH:mm:ss.SSS" + }; + + if ("date" == dateTimeOptions.selector) + { + formatOptions.selector = "date"; + } + else if ("time" == dateTimeOptions.selector) + { + formatOptions.selector = "time"; + } + + var result = locale.format(d, formatOptions); + if(dateTimeOptions.appendTimeZone) + { + result += " (" + this.getTimeZoneDescription(tzi) + ")"; + } + return result; + } + + }; + + UserPreferences.loadPreferences(null, + function(error) + { + UserPreferences.preferencesError = error; + } + ); + + return UserPreferences; +});
\ No newline at end of file diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAuthenticationProvider.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAuthenticationProvider.js index 3737e41da4..428a26c3c9 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAuthenticationProvider.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAuthenticationProvider.js @@ -31,7 +31,7 @@ define(["dojo/_base/xhr", "dijit/form/FilteringSelect", "dojo/_base/connect", "dojo/dom-style", - "qpid/management/addPreferencesProvider", + "qpid/management/PreferencesProviderFields", /* dojox/ validate resources */ "dojox/validate/us", "dojox/validate/web", /* basic dijit classes */ @@ -45,7 +45,7 @@ define(["dojo/_base/xhr", "dojox/form/BusyButton", "dojox/form/CheckedMultiSelect", "dojox/layout/TableContainer", "dojo/domReady!"], - function (xhr, dom, construct, win, registry, parser, array, event, json, Memory, FilteringSelect, connect, domStyle, addPreferencesProvider) { + function (xhr, dom, construct, win, registry, parser, array, event, json, Memory, FilteringSelect, connect, domStyle, PreferencesProviderFields) { var addAuthenticationProvider = {}; @@ -66,6 +66,10 @@ define(["dojo/_base/xhr", { if(formValues.hasOwnProperty(propName)) { + if (propName.indexOf("preferencesProvider") == 0) + { + continue; + } if(formValues[ propName ] !== "") { newProvider[ propName ] = formValues[propName]; } @@ -101,6 +105,21 @@ define(["dojo/_base/xhr", return "ap_" + providerType + "Field" + attribute; } + var showPreferencesProviderFields = function showPreferencesProviderFields(provider) + { + var preferencesProviderDiv = dojo.byId("addAuthenticationProvider.preferencesProvider"); + var preferencesProviderPanel = dijit.byId("addAuthenticationProvider.preferencesProviderPanel"); + if (provider && provider.type == "Anonymous") + { + preferencesProviderPanel.domNode.style.display = 'none'; + } + else + { + preferencesProviderPanel.domNode.style.display = 'block'; + PreferencesProviderFields.show(preferencesProviderDiv, provider && provider.preferencesproviders ? provider.preferencesproviders[0] : null); + } + } + var loadProviderAndDisplayForm = function loadProviderAndDisplayForm(providerName, dialog) { if (providerName) @@ -129,11 +148,13 @@ define(["dojo/_base/xhr", } } } + showPreferencesProviderFields(provider); registry.byId("addAuthenticationProvider").show(); }); } else { + showPreferencesProviderFields(); registry.byId("addAuthenticationProvider").show(); } } @@ -163,15 +184,14 @@ define(["dojo/_base/xhr", if(this.success === true) { + if (PreferencesProviderFields.save(newAuthenticationManager.name)) + { registry.byId("addAuthenticationProvider").hide(); - if (newAuthenticationManager.type != "Anonymous" && dojo.byId("formAddAuthenticationProvider.id").value == "") - { - addPreferencesProvider.show(newAuthenticationManager.name); - } + } } else { - alert("Error:" + this.failureReason); + alert("Authentication Provider Error:" + this.failureReason); } return false; }else{ @@ -251,9 +271,10 @@ define(["dojo/_base/xhr", name: "type", store: providersStore, searchAttr: "name"}, input); - connect.connect(that.providerChooser, "onChange", - function(event) + that.providerChooser.on("change", + function(value) { + dijit.byId("addAuthenticationProvider.preferencesProviderPanel").domNode.style.display = (value == "Anonymous" ? "none" : "block"); showFieldSets(that.providerChooser.value, that.providerFieldSets); } ); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addPreferencesProvider.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addPreferencesProvider.js index 818dc32366..40f8f83fbb 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addPreferencesProvider.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addPreferencesProvider.js @@ -34,6 +34,7 @@ define(["dojo/_base/xhr", "dojo/dom-style", "dojo/string", "dojox/html/entities", + "qpid/management/PreferencesProviderFields", "dojox/validate/us", "dojox/validate/web", "dijit/Dialog", @@ -47,47 +48,12 @@ define(["dojo/_base/xhr", "dojox/form/CheckedMultiSelect", "dojox/layout/TableContainer", "dojo/domReady!"], - function (xhr, dom, construct, query, win, registry, parser, array, event, json, Memory, FilteringSelect, connect, domStyle, string, entities) { + function (xhr, dom, construct, query, win, registry, parser, array, event, json, Memory, FilteringSelect, connect, domStyle, string, entities, PreferencesProviderFields) { var addPreferencesProvider = {}; var node = construct.create("div", null, win.body(), "last"); - var convertToPreferencesProvider = function convertToPreferencesProvider(formValues) - { - var newProvider = {}; - - newProvider.name = dijit.byId("preferencesProvider.name").value; - newProvider.type = dijit.byId("preferencesProvider.type").value; - var id = dojo.byId("preferencesProvider.id").value; - if (id) - { - newProvider.id = id; - } - for(var propName in formValues) - { - if(formValues.hasOwnProperty(propName)) - { - if(formValues[ propName ] !== "") { - newProvider[ propName ] = formValues[propName]; - } - - } - } - return newProvider; - } - - var selectPreferencesProviderType = function(type) { - if(type && string.trim(type) != "") - { - require(["qpid/management/authenticationprovider/preferences/" + type.toLowerCase() + "/add"], - function(addType) - { - addType.show(dom.byId("preferencesProvider.fieldsContainer"), addPreferencesProvider.data) - }); - } - } - xhr.get({url: "addPreferencesProvider.html", sync: true, load: function(data) { @@ -104,94 +70,24 @@ define(["dojo/_base/xhr", event.stop(e); if(theForm.validate()){ - var newProvider = convertToPreferencesProvider(theForm.getValues()); - var that = this; - var nameWidget = registry.byId("preferencesProvider.name") - xhr.put({url: "rest/preferencesprovider/" +encodeURIComponent(addPreferencesProvider.authenticationProviderName) + "/" + encodeURIComponent(nameWidget.value), - sync: true, handleAs: "json", - headers: { "Content-Type": "application/json"}, - putData: json.toJson(newProvider), - load: function(x) {that.success = true; }, - error: function(error) {that.success = false; that.failureReason = error;}}); - if(this.success === true) + if(PreferencesProviderFields.save(addPreferencesProvider.authenticationProviderName)) { registry.byId("addPreferencesProvider").hide(); } - else - { - alert("Error:" + this.failureReason); - } return false; }else{ alert('Form contains invalid data. Please correct first'); return false; } }); - xhr.get({ - sync: true, - url: "rest/helper?action=ListPreferencesProvidersTypes", - handleAs: "json" - }).then( - function(data) { - var preferencesProvidersTypes = data; - var storeData = []; - for (var i =0 ; i < preferencesProvidersTypes.length; i++) - { - storeData[i]= {id: preferencesProvidersTypes[i], name: preferencesProvidersTypes[i]}; - } - var store = new Memory({ data: storeData }); - var preferencesProviderTypesDiv = dom.byId("addPreferencesProvider.selectPreferencesProviderDiv"); - var input = construct.create("input", {id: "preferencesProviderType", required: true}, preferencesProviderTypesDiv); - addPreferencesProvider.preferencesProviderTypeChooser = new FilteringSelect({ id: "preferencesProvider.type", - name: "type", - store: store, - searchAttr: "name", - required: true, - onChange: selectPreferencesProviderType }, input); - addPreferencesProvider.preferencesProviderTypeChooser.startup(); - }); }}); addPreferencesProvider.show = function(authenticationProviderName, providerName) { this.authenticationProviderName = authenticationProviderName; - this.data = null; - var that = this; - var theForm = registry.byId("formAddPreferencesProvider"); - theForm.reset(); - dojo.byId("preferencesProvider.id").value=""; - var nameWidget = registry.byId("preferencesProvider.name"); - nameWidget.set("disabled", false); - registry.byId("preferencesProvider.type").set("disabled", false); - if (this.preferencesProviderTypeChooser) - { - this.preferencesProviderTypeChooser.set("disabled", false); - this.preferencesProviderTypeChooser.set("value", null); - } + PreferencesProviderFields.show(dom.byId("addPreferencesProvider.preferencesProvider"), providerName, authenticationProviderName) var dialog = registry.byId("addPreferencesProvider"); - dialog.set("title", (providerName ? "Edit preference provider '" + entities.encode(String(providerName)) + "' " : "Add preferences provider ") + " for authentication provider '" + entities.encode(String(authenticationProviderName)) + "' ") - if (providerName) - { - xhr.get({ - url: "rest/preferencesprovider/" +encodeURIComponent(authenticationProviderName) + "/" + encodeURIComponent(providerName), - sync: false, - handleAs: "json" - }).then( - function(data) { - var provider = data[0]; - var providerType = provider.type; - that.data = provider; - nameWidget.set("value", entities.encode(String(provider.name))); - nameWidget.set("disabled", true); - that.preferencesProviderTypeChooser.set("value", providerType); - that.preferencesProviderTypeChooser.set("disabled", true); - dojo.byId("preferencesProvider.id").value=provider.id; - dialog.show(); - }); - } - else - { - dialog.show(); - } + dialog.set("title", (providerName ? "Edit preferences provider '" + entities.encode(String(providerName)) + "' " : "Add preferences provider ") + " for '" + entities.encode(String(authenticationProviderName)) + "' ") + dialog.show(); } return addPreferencesProvider; diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/authenticationprovider/preferences/filesystempreferences/add.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/authenticationprovider/preferences/filesystempreferences/add.js index 80b50fbbb8..06dd9dd0e3 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/authenticationprovider/preferences/filesystempreferences/add.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/authenticationprovider/preferences/filesystempreferences/add.js @@ -33,10 +33,10 @@ define(["dojo/_base/xhr", "dojo/domReady!"], function (xhr, dom, domConstruct, win, registry, parser, array, event, json, string, entities, template) { return { - show: function(node, data) { - dojo.forEach(dijit.findWidgets(node), function(w) { - w.destroyRecursive(); - }); + show: function(node, data) + { + this.destroy(); + this.node = node; node.innerHTML = template; parser.parse(node); var pathWidget = registry.byId("preferencesProvider.path") @@ -44,6 +44,23 @@ define(["dojo/_base/xhr", { pathWidget.set("value", entities.encode(String(data["path"]))); } + }, + destroy: function() + { + if (this.node) + { + dojo.forEach(dijit.findWidgets(this.node), function(w) {w.destroyRecursive();}); + this.node = null; + } + }, + disable: function(val) + { + var pathWidget = registry.byId("preferencesProvider.path"); + pathWidget.set("disabled", val); + }, + getValues: function() + { + return {path: registry.byId("preferencesProvider.path").value}; } }; }); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logs/LogFileDownloadDialog.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logs/LogFileDownloadDialog.js index c25fd7c609..95870dadf7 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logs/LogFileDownloadDialog.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logs/LogFileDownloadDialog.js @@ -28,7 +28,7 @@ define([ "dojo/parser", "dojo/store/Memory", "dojo/data/ObjectStore", - "dojo/date/locale", + "qpid/management/UserPreferences", "dojo/number", "dijit/registry", "dijit/Dialog", @@ -36,7 +36,7 @@ define([ "dojox/grid/EnhancedGrid", "dojo/text!../../../logs/showLogFileDownloadDialog.html", "dojo/domReady!" -], function(declare, event, xhr, connect, domConstruct, query, parser, Memory, ObjectStore, locale, number, +], function(declare, event, xhr, connect, domConstruct, query, parser, Memory, ObjectStore, UserPreferences, number, registry, Dialog, Button, EnhancedGrid, template){ @@ -79,8 +79,7 @@ return declare("qpid.management.logs.LogFileDownloadDialog", null, { }, { name: "Last Modified", field: "lastModified", width: "250px", formatter: function(val) { - var d = new Date(val); - return locale.format(d, {selector:"date", datePattern: "EEE, MMM d yy, HH:mm:ss z (ZZZZ)"}); + return UserPreferences.formatDateTime(val, {addOffset: true, appendTimeZone: true}); } } ]; @@ -152,7 +151,7 @@ return declare("qpid.management.logs.LogFileDownloadDialog", null, { showDialog: function(){ var self = this; - var requestArguments = {url: "rest/logfiles", sync: true, handleAs: "json"}; + var requestArguments = {url: "rest/logfilenames", sync: true, handleAs: "json"}; xhr.get(requestArguments).then(function(data){ try { diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logs/LogViewer.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logs/LogViewer.js index 56b37d0167..364d5403a3 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logs/LogViewer.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/logs/LogViewer.js @@ -23,14 +23,25 @@ define(["dojo/_base/xhr", "dojo/query", "dojo/date/locale", "dijit/registry", + "qpid/management/UserPreferences", "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, UserPreferences, GridUpdater, UpdatableGrid, LogFileDownloadDialog, markup) { var defaulGridRowLimit = 4096; + var currentTimeZone; + + function dataTransformer(data) + { + for(var i=0; i < data.length; i++) + { + data[i].time = UserPreferences.addTimeZoneOffsetToUTC(data[i].timestamp); + } + return data; + } function LogViewer(name, parent, controller) { var self = this; @@ -64,10 +75,11 @@ define(["dojo/_base/xhr", LogViewer.prototype._buildGrid = function() { var self = this; + currentTimeZone = UserPreferences.getTimeZoneDescription(); var gridStructure = [ { - hidden: true, + hidden: false, name: "ID", field: "id", width: "50px", @@ -75,28 +87,27 @@ define(["dojo/_base/xhr", filterable: true }, { - name: "Date", field: "timestamp", width: "100px", datatype: "date", + name: "Date", field: "time", width: "100px", datatype: "date", formatter: function(val) { - var d = new Date(0); - d.setUTCSeconds(val/1000); - return locale.format(d, {selector:"date", datePattern: "EEE, MMM d yy"}); - }, - dataTypeArgs: { - selector: "date", - datePattern: "EEE MMMM d yyy" + return UserPreferences.formatDateTime(val, {selector:"date"}); } }, - { name: "Time", field: "timestamp", width: "150px", datatype: "time", + { name: "Time ", field: "time", width: "100px", datatype: "time", formatter: function(val) { - var d = new Date(0); - d.setUTCSeconds(val/1000); - return locale.format(d, {selector:"time", timePattern: "HH:mm:ss z (ZZZZ)"}); - }, - dataTypeArgs: { - selector: "time", - timePattern: "HH:mm:ss ZZZZ" + return UserPreferences.formatDateTime(val, {selector:"time"}); } }, + { + name: "Time zone", + field: "time", + width: "80px", + datatype: "string", + hidden: true, + filterable: false, + formatter: function(val) { + return currentTimeZone; + }, + }, { name: "Level", field: "level", width: "50px", datatype: "string", autoComplete: true, hidden: true}, { name: "Logger", field: "logger", width: "150px", datatype: "string", autoComplete: false, hidden: true}, { name: "Thread", field: "thread", width: "100px", datatype: "string", hidden: true}, @@ -132,18 +143,20 @@ define(["dojo/_base/xhr", } }, append: true, - appendLimit: defaulGridRowLimit + appendLimit: defaulGridRowLimit, + dataTransformer: dataTransformer }); this.grid = new UpdatableGrid(updater.buildUpdatableGridArguments({ structure: gridStructure, selectable: true, selectionMode: "none", sortInfo: -1, - sortFields: [{attribute: 'timestamp', descending: true}], + sortFields: [{attribute: 'id', descending: true}], plugins:{ nestedSorting:true, - enhancedFilter:{defaulGridRowLimit: defaulGridRowLimit}, - indirectSelection: false + enhancedFilter:{defaulGridRowLimit: defaulGridRowLimit,displayLastUpdateTime:true}, + indirectSelection: false, + pagination: {defaultPageSize: 10} } }), gridNode); var onStyleRow = function(row) @@ -170,14 +183,19 @@ define(["dojo/_base/xhr", }; this.grid.on("styleRow", onStyleRow); this.grid.startup(); + UserPreferences.addListener(this); } catch(err) { - console.error(err); + if (console && console.error) + { + console.error(err); + } } }; LogViewer.prototype.close = function() { + UserPreferences.removeListener(this); if (this.grid) { this.grid.destroy(); @@ -195,5 +213,12 @@ define(["dojo/_base/xhr", } }; + LogViewer.prototype.onPreferencesChange = function(data) + { + currentTimeZone = UserPreferences.getTimeZoneDescription(); + dataTransformer(this.grid.updater.memoryStore.data); + this.grid._refresh(); + }; + return LogViewer; }); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/showMessage.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/showMessage.js index 59822ec535..1281e44166 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/showMessage.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/showMessage.js @@ -29,8 +29,9 @@ define(["dojo/_base/xhr", "dojo/_base/connect", "qpid/common/properties", "dojox/html/entities", + "qpid/management/UserPreferences", "dojo/domReady!"], - function (xhr, dom, construct, domClass, win, registry, parser, array, event, json, query, connect, properties, entities) { + function (xhr, dom, construct, domClass, win, registry, parser, array, event, json, query, connect, properties, entities, UserPreferences) { function encode(val){ @@ -88,9 +89,7 @@ define(["dojo/_base/xhr", } tableStr += "</table>"; } else if(domClass.contains(field,"datetime")) { - var d = new Date(0); - d.setUTCSeconds(val/1000); - field.innerHTML = d.toLocaleString(); + field.innerHTML = UserPreferences.formatDateTime(val, {addOffset: true, appendTimeZone: true}); } else { field.innerHTML = encode(val); } diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/logs/showLogViewer.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/logs/showLogViewer.html index 10ac09a406..ab927153fa 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/logs/showLogViewer.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/logs/showLogViewer.html @@ -23,7 +23,7 @@ <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</button> + data-dojo-props="iconClass: 'downloadLogsIcon', title:'Download Log Files', name: 'downloadLogs'">Download Log Files</button> <br/> </div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/showExchange.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/showExchange.html index f33b029026..cdc88ece6a 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/showExchange.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/showExchange.html @@ -19,24 +19,43 @@ - --> <div class="exchange"> - <span style="">Name:</span><span class="name" style="position:absolute; left:6em"></span> - <br/> - <span style="">State:</span><span class="state" style="position:absolute; left:6em"></span> - <br/> - <span style="">Durable:</span><span class="durable" style="position:absolute; left:6em"></span> - <span style="position:absolute; left:26em">Inbound:</span> - <span class="msgInRate" style="position:absolute; right:9.5em"></span> - <span style="position:absolute; right: 5em; width: 4em"> msg/s</span> - <span class="bytesInRate" style="position:absolute; right: 3.3em"></span> - <span class="bytesInRateUnits" style="position:absolute; right: 0em; width: 3em"></span> - <br/> - <span style="">Lifespan:</span><span style="position:absolute; left:6em" class="lifetimePolicy"></span> - <span style="position:absolute; left:26em">Dropped:</span> - <span class="msgDropRate" style="position:absolute; right:9.5em"></span> - <span style="position:absolute; right: 5em; width: 4em"> msg/s</span> - <span class="bytesDropRate" style="position:absolute; right: 3.3em"></span> - <span class="bytesDropRateUnits" style="position:absolute; right: 0em; width: 3em"></span> - <br/> + <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Exchange Attributes', open: true"> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 100px;">Name:</div> + <div class="name" style="float:left;"></div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 100px;">State:</div> + <div class="state" style="float:left;"></div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 100px;">Durable:</div> + <div class="durable" style="float:left;"></div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 100px;">Lifespan:</div> + <div class="lifetimePolicy" style="float:left;"></div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 100px;">Inbound:</div> + <div style="float:left;"> + <span class="msgInRate"></span> + <span> msg/s</span> + <span class="bytesInRate">(</span> + <span class="bytesInRateUnits">)</span> + </div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 100px;">Dropped:</div> + <div style="float:left;"> + <span class="msgDropRate"></span> + <span> msg/s</span> + <span class="bytesDropRate">(</span> + <span class="bytesDropRateUnits">)</span> + </div> + </div> + <div style="clear:both"></div> + </div> <br/> <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Bindings'"> <div class="bindings"></div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/showPreferences.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/showPreferences.html index ede111272a..ada919f5a5 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/showPreferences.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/showPreferences.html @@ -22,15 +22,13 @@ <div data-dojo-type="dijit/layout/TabContainer" style="width: 600px; height: 400px"> <div data-dojo-type="dijit/layout/ContentPane" title="Own Preferences" data-dojo-props="selected:true" id="preferences.preferencesTab"> <form method="post" data-dojo-type="dijit/form/Form" id="preferences.preferencesForm"> - <table cellpadding="0" cellspacing="2" style="overflow: auto; height: 300px;"> + <div style="height:300px"> + <table cellpadding="0" cellspacing="2"> <tr> - <td><strong>Time zone: </strong></td> - <td> - <span id="preferences.timeZone" data-dojo-type="qpid/common/TimeZoneSelector" data-dojo-props="name: 'timeZone'"></span> - </td> + <td colspan="2"><span id="preferences.timeZone" data-dojo-type="qpid/common/TimeZoneSelector" data-dojo-props="name: 'timeZone', labelStyle: {width: '105px'}"></span></td> </tr> <tr> - <td><strong>Update period:</strong></td> + <td style="width: 105px"><strong>Update period:</strong></td> <td><input id="preferences.updatePeriod" name="updatePeriod" data-dojo-type="dijit/form/NumberSpinner" data-dojo-props=" invalidMessage: 'Invalid value', required: false, @@ -40,14 +38,11 @@ "/> </td> </tr> - <tr> - <td><strong>Save tabs:</strong></td> - <td><input id="preferences.saveTabs" type="checkbox" data-dojo-type="dijit/form/CheckBox" name="saveTabs"/></td> - </tr> </table> + </div> <div class="dijitDialogPaneActionBar"> - <input type="submit" value="Save Preferences" data-dojo-type="dijit/form/Button" data-dojo-props="label: 'Save Preferences'" id="preferences.saveButton"/> - <button value="Cancel" data-dojo-type="dijit/form/Button" data-dojo-props="label: 'Cancel'" id="preferences.cancelButton"></button> + <button data-dojo-type="dijit/form/Button" data-dojo-props="label: 'Set'" id="preferences.setButton">Set</button> + <button data-dojo-type="dijit/form/Button" data-dojo-props="label: 'Set and Close'" id="preferences.setAndCloseButton">Set and Close</button> </div> </form> </div> @@ -76,7 +71,8 @@ </thead> </table> <div class="dijitDialogPaneActionBar"> - <button id="preferences.deletePreeferencesButton" data-dojo-type="dijit/form/Button" data-dojo-props="label:'Delete Preferences', title:'Delete preferences for selected users'">Delete Preferences</button> + <button id="preferences.deleteButton" data-dojo-type="dijit/form/Button" data-dojo-props="label:'Delete', title:'Delete preferences for selected users'">Delete</button> + <button id="preferences.deleteAndCloseButton" data-dojo-type="dijit/form/Button" data-dojo-props="label: 'Delete and Close', title:'Delete preferences for selected users and close the dialog'">Delete and Close</button> </div> </div> </div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/showPreferencesProviderFields.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/showPreferencesProviderFields.html new file mode 100644 index 0000000000..0da104821b --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/showPreferencesProviderFields.html @@ -0,0 +1,41 @@ +<!-- + - + - 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. + - + --> +<div data-dojo-type="dijit/layout/ContentPane" class="preferencesProviderContainer"> + <table class="tableContainer-table tableContainer-table-horiz" width="100%" cellspacing="1"> + <tr> + <td class="tableContainer-labelCell" style="width: 200px;"><strong>Type*:</strong></td> + <td class="tableContainer-valueCell"> + <select class="preferencesProviderType" data-dojo-type="dijit/form/FilteringSelect" + data-dojo-props="name:'preferencesProviderType',label:'Type:', searchAttr: 'name', placeHolder: 'Select Provider Type', required: true"> + <option value="">None</option> + </select> + </td> + </tr> + <tr> + <td class="tableContainer-labelCell" style="width: 200px;"><strong>Name*:</strong></td> + <td class="tableContainer-valueCell"><input type="text" name="preferencesProviderName" + class="preferencesProviderName" data-dojo-type="dijit/form/ValidationTextBox" + data-dojo-props="placeHolder: 'Name', required: true, missingMessage: 'A name must be supplied', title: 'Enter name', pattern: '^[\x20-\x2e\x30-\x7F]{1,255}$'" /></td> + </tr> + </table> + <div class="preferencesProviderFieldsContainer"></div> + <input type="hidden" name="preferencesProviderId"/> +</div>
\ No newline at end of file diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/showQueue.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/showQueue.html index c31cae6f8a..8d6741a981 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/showQueue.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/showQueue.html @@ -19,41 +19,81 @@ - --> <div class="queue"> - <span style="">Name:</span><span class="name" style="position:absolute; left:6em"></span> - <span style="position:absolute; left:26em">Size:</span> - <span class="queueDepthMessages" style="position:absolute; right:9.5em"></span> - <span style="position:absolute; right: 5em; width: 4em"> msgs</span> - <span class="queueDepthBytes" style="position:absolute; right: 3.3em">(</span> - <span class="queueDepthBytesUnits" style="position:absolute; right: 0em; width: 3em">)</span> - <br/> - <span style="">State:</span><span class="state" style="position:absolute; left:6em"></span> - <span style="position:absolute; left:26em">Pre-fetched:</span> - <span class="unacknowledgedMessages" style="position:absolute; right:9.5em"></span> - <span style="position:absolute; right: 5em; width: 4em"> msgs</span> - <span class="unacknowledgedBytes" style="position:absolute; right: 3.3em"></span> - <span class="unacknowledgedBytesUnits" style="position:absolute; right: 0em; width: 3em"></span> - <br/> - <span style="">Durable:</span><span class="durable" style="position:absolute; left:6em"></span> - <span style="position:absolute; left:26em">Inbound:</span> - <span class="msgInRate" style="position:absolute; right:9.5em"></span> - <span style="position:absolute; right: 5em; width: 4em"> msg/s</span> - <span class="bytesInRate" style="position:absolute; right: 3.3em"></span> - <span class="bytesInRateUnits" style="position:absolute; right: 0em; width: 3em"></span> - <br/> - <span style="">Lifespan:</span><span style="position:absolute; left:6em" class="lifetimePolicy"></span> - <span style="position:absolute; left:26em">Outbound:</span> - <span class="msgOutRate" style="position:absolute; right:9.5em"></span> - <span style="position:absolute; right: 5em; width: 4em"> msg/s</span> - <span class="bytesOutRate" style="position:absolute; right: 3.3em"></span> - <span class="bytesOutRateUnits" style="position:absolute; right: 0em; width: 3em"></span> - <br/> - <span style="">AlternateExchange:</span><span class="alternateExchange" style="position:absolute; left:10em"></span> - <span style="position:absolute; left:26em">Type:</span><span style="position:absolute; left:29em" class="type"></span> - <span style="position:absolute; right:1em" class="typeQualifier"></span> - <br/> - <div class="messageGroups"> - <span style="" class="messageGroupKeyLabel">Message Group Key:</span><span class="messageGroupKey" style="position:absolute; left:11em"></span> - <span style="position:absolute; left:26em" class="messageGroupSharedGroupsLabel">Shared Message Groups:</span><span style="position:absolute; left:39em" class="messageGroupSharedGroups"></span> + <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Queue Attributes', open: true"> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 150px;">Name:</div> + <div class="name" style="float:left;"></div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 150px;">State:</div> + <div class="state" style="float:left;"></div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 150px;">Durable:</div> + <div class="durable" style="float:left;"></div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 150px;">Lifespan:</div> + <div class="lifetimePolicy" style="float:left;"></div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 150px;">Type:</div> + <div style="float:left;"> + <span class="type"></span> + <span class="typeQualifier"></span> + </div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 150px;">Size:</div> + <div style="float:left;"> + <span class="queueDepthMessages"></span> + <span> msgs</span> + <span class="queueDepthBytes">(</span> + <span class="queueDepthBytesUnits">)</span> + </div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 150px;">Pre-fetched:</div> + <div style="float:left;"> + <span class="unacknowledgedMessages"></span> + <span> msgs</span> + <span class="unacknowledgedBytes">(</span> + <span class="unacknowledgedBytesUnits">)</span> + </div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 150px;">Inbound:</div> + <div style="float:left;"> + <span class="msgInRate"></span> + <span> msg/s</span> + <span class="bytesInRate">(</span> + <span class="bytesInRateUnits">)</span> + </div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 150px;">Outbound:</div> + <div style="float:left;"> + <span class="msgOutRate"></span> + <span> msg/s</span> + <span class="bytesOutRate">(</span> + <span class="bytesOutRateUnits">)</span> + </div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 150px;">AlternateExchange:</div> + <div class="alternateExchange" style="float:left;"></div> + </div> + <div class="messageGroups" style="clear:both"> + <div style="clear:both"> + <div style="float:left; width: 150px;" class="messageGroupKeyLabel formLabel-labelCell ">Message Group Key:</div> + <div style="float:left;" class="messageGroupKey"></div> + </div> + <div style="clear:both"> + <div style="float:left; width: 150px;" class="messageGroupSharedGroupsLabel formLabel-labelCell">Shared Message Groups:</div> + <div style="float:left;" class="messageGroupSharedGroups"></div> + </div> + </div> + <div style="clear:both"></div> </div> <br/> <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Bindings'"> @@ -73,31 +113,42 @@ </div> <br/> <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Alerting Thresholds', open: false"> - <span style="">Queue Depth:</span> - <span class="alertThresholdQueueDepthMessages" - style="position:absolute; left:4em; width:8em; text-align:right"></span> - <span style="position:absolute; left:12.2em">msgs</span> - - <span style="position:absolute; left:21em">Queue Depth:</span> - <span class="alertThresholdQueueDepthBytes" - style="position:absolute; left:22em; width:8em; text-align:right"></span> - <span class="alertThresholdQueueDepthBytesUnits" style="position:absolute; left:30.2em"></span> - <br> - <span style="">Message Age:</span> - <span class="alertThresholdMessageAge" - style="position:absolute; left:4em; width:8em; text-align:right"></span> - <span class="alertThresholdMessageAgeUnits" style="position:absolute; left:12.2em"></span> - - <span style="position:absolute; left:21em">Message Size: </span> - <span class="alertThresholdMessageSize" - style="position:absolute; left:25em; width:5em; text-align:right"></span> - <span class="alertThresholdMessageSizeUnits" style="position:absolute; left:30.2em"></span> - <br/> - <br/> - <span style="">Alert frequency:</span> - <span class="alertRepeatGap" - style="position:absolute; left:4em; width:8em; text-align:right"></span> - <span class="alertRepeatGapUnits" style="position:absolute; left:12.2em"></span> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 150px;">Queue Depth:</div> + <div style="float:left;"> + <span class="alertThresholdQueueDepthMessages"></span> + <span>msgs</span> + </div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 150px;">Queue Depth:</div> + <div style="float:left;"> + <span class="alertThresholdQueueDepthBytes"></span> + <span class="alertThresholdQueueDepthBytesUnits"></span> + </div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 150px;">Message Age:</div> + <div style="float:left;"> + <span class="alertThresholdMessageAge"></span> + <span class="alertThresholdMessageAgeUnits"></span> + </div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 150px;">Message Size:</div> + <div style="float:left;"> + <span class="alertThresholdMessageSize"></span> + <span class="alertThresholdMessageSizeUnits"></span> + </div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 150px;">Alert frequency:</div> + <div style="float:left;"> + <span class="alertRepeatGap"></span> + <span class="alertRepeatGapUnits"></span> + </div> + </div> + <div style="clear:both"></div> </div> <div class="dijitDialogPaneActionBar"> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/showVirtualHost.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/showVirtualHost.html index 14833e0d2e..69856365db 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/showVirtualHost.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/showVirtualHost.html @@ -21,31 +21,55 @@ --> <div class="virtualhost"> - <span style="">Name:</span><span class="name" style="position:absolute; left:6em"></span> - <br/> - <span style="">State:</span><span class="state" style="position:absolute; left:6em"></span> - <br/> - <span style="">Durable:</span><span class="durable" style="position:absolute; left:6em"></span> - <span style="position:absolute; left:26em">Inbound:</span> - <span class="msgInRate" style="position:absolute; right:9.5em"></span> - <span style="position:absolute; right: 5em; width: 4em"> msg/s</span> - <span class="bytesInRate" style="position:absolute; right: 3.3em"></span> - <span class="bytesInRateUnits" style="position:absolute; right: 0em; width: 3em"></span> - <br/> - <span style="">Lifespan:</span><span style="position:absolute; left:6em" class="lifetimePolicy"></span> - <span style="position:absolute; left:26em">Outbound:</span> - <span class="msgOutRate" style="position:absolute; right:9.5em"></span> - <span style="position:absolute; right: 5em; width: 4em"> msg/s</span> - <span class="bytesOutRate" style="position:absolute; right: 3.3em"></span> - <span class="bytesOutRateUnits" style="position:absolute; right: 0em; width: 3em"></span> - <br/> - <span style="">Store Type:</span><span style="position:absolute; left:6em" class="storeType"></span> - <span style="position:absolute; left:26em">Store Path:</span> - <span class="storePath" style="position:absolute; right: 1em"></span> - <div class="configPathDiv"> - <span style="">ConfigPath:</span><span style="position:absolute; left:6em" class="configPath"></span> - </div> - + <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Virtual Host Attributes', open: true"> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 100px;">Name:</div> + <div class="name" style="float:left;"></div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 100px;">State:</div> + <div class="state" style="float:left;"></div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 100px;">Durable:</div> + <div class="durable" style="float:left;"></div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 100px;">Lifespan:</div> + <div class="lifetimePolicy" style="float:left;"></div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 100px;">Inbound:</div> + <div style="float:left;"> + <span class="msgInRate"></span> + <span> msg/s</span> + <span class="bytesInRate"></span> + <span class="bytesInRateUnits"></span> + </div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 100px;">Outbound:</div> + <div style="float:left;"> + <span class="msgOutRate"></span> + <span> msg/s</span> + <span class="bytesOutRate"></span> + <span class="bytesOutRateUnits"></span> + </div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 100px;">Store Type:</div> + <div class="storeType" style="float:left;"></div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 100px;">Store Path:</div> + <div class="storePath" style="float:left;"></div> + </div> + <div class="configPathDiv" style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 100px;">Config Path:</div> + <div class="configPath" style="float:left;"></div> + </div> + <div style="clear:both"></div> + </div> <br/> <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Exchanges'"> <div class="exchanges"></div> @@ -64,31 +88,42 @@ </div> <br/> <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Alerting Thresholds', open: false"> - <span style="">Queue Depth:</span> - <span class="alertThresholdQueueDepthMessages" - style="position:absolute; left:4em; width:8em; text-align:right"></span> - <span style="position:absolute; left:12.2em">msgs</span> - - <span style="position:absolute; left:21em">Queue Depth:</span> - <span class="alertThresholdQueueDepthBytes" - style="position:absolute; left:22em; width:8em; text-align:right"></span> - <span class="alertThresholdQueueDepthBytesUnits" style="position:absolute; left:30.2em"></span> - <br> - <span style="">Message Age:</span> - <span class="alertThresholdMessageAge" - style="position:absolute; left:4em; width:8em; text-align:right"></span> - <span class="alertThresholdMessageAgeUnits" style="position:absolute; left:12.2em"></span> - - <span style="position:absolute; left:21em">Message Size: </span> - <span class="alertThresholdMessageSize" - style="position:absolute; left:25em; width:5em; text-align:right"></span> - <span class="alertThresholdMessageSizeUnits" style="position:absolute; left:30.2em"></span> - <br/> - <br/> - <span style="">Alert frequency:</span> - <span class="alertRepeatGap" - style="position:absolute; left:4em; width:8em; text-align:right"></span> - <span class="alertRepeatGapUnits" style="position:absolute; left:12.2em"></span> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 150px;">Queue Depth:</div> + <div style="float:left;"> + <span class="alertThresholdQueueDepthMessages"></span> + <span>msgs</span> + </div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 150px;">Queue Depth:</div> + <div style="float:left;"> + <span class="alertThresholdQueueDepthBytes"></span> + <span class="alertThresholdQueueDepthBytesUnits"></span> + </div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 150px;">Message Age:</div> + <div style="float:left;"> + <span class="alertThresholdMessageAge"></span> + <span class="alertThresholdMessageAgeUnits"></span> + </div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 150px;">Message Size:</div> + <div style="float:left;"> + <span class="alertThresholdMessageSize"></span> + <span class="alertThresholdMessageSizeUnits"></span> + </div> + </div> + <div style="clear:both"> + <div class="formLabel-labelCell" style="float:left; width: 150px;">Alert frequency:</div> + <div style="float:left;"> + <span class="alertRepeatGap"></span> + <span class="alertRepeatGapUnits"></span> + </div> + </div> + <div style="clear:both"></div> </div> </div> diff --git a/qpid/java/broker-plugins/management-http/src/main/resources-maven/dojoconfig.properties b/qpid/java/broker-plugins/management-http/src/main/resources-maven/dojoconfig.properties new file mode 100644 index 0000000000..153b568482 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/resources-maven/dojoconfig.properties @@ -0,0 +1,5 @@ +dojo-version=${dojo-version} +dojo-path=/dojo-${dojo-version}/dojo +dijit-path=/dojo-${dojo-version}/dijit +dojox-path=/dojo-${dojo-version}/dojox + |
