diff options
Diffstat (limited to 'qpid/java/broker-plugins')
48 files changed, 1962 insertions, 834 deletions
diff --git a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AbstractConfiguration.java b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AbstractConfiguration.java deleted file mode 100644 index e15361acfe..0000000000 --- a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AbstractConfiguration.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * - * 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.security.access.config; - -import org.apache.qpid.server.logging.EventLogger; -import org.apache.qpid.server.logging.EventLoggerProvider; - -import java.io.File; - -public abstract class AbstractConfiguration implements ConfigurationFile -{ - private File _file; - private RuleSet _config; - private final EventLoggerProvider _eventLogger; - - public AbstractConfiguration(File file, final EventLoggerProvider eventLogger) - { - _file = file; - _eventLogger = eventLogger; - } - - public File getFile() - { - return _file; - } - - public RuleSet load() - { - _config = new RuleSet(_eventLogger); - return _config; - } - - public RuleSet getConfiguration() - { - return _config; - } - - public boolean save(RuleSet configuration) - { - return true; - } - - public RuleSet reload() - { - RuleSet oldRules = _config; - - try - { - RuleSet newRules = load(); - _config = newRules; - } - catch (Exception e) - { - _config = oldRules; - } - - return _config; - } -} diff --git a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ConfigurationFile.java b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ConfigurationFile.java index 966c32e24e..3405b6c155 100644 --- a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ConfigurationFile.java +++ b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ConfigurationFile.java @@ -20,35 +20,20 @@ */ package org.apache.qpid.server.security.access.config; -import java.io.File; +import java.io.Reader; import org.apache.qpid.server.configuration.IllegalConfigurationException; public interface ConfigurationFile { /** - * Return the actual {@link File} object containing the configuration. - */ - File getFile(); - - /** * Load this configuration file's contents into a {@link RuleSet}. * @throws IllegalConfigurationException if the configuration file has errors. * @throws IllegalArgumentException if individual tokens cannot be parsed. + * @param configReader */ - RuleSet load() throws IllegalConfigurationException; - - /** - * Reload this configuration file's contents. - * @throws IllegalConfigurationException if the configuration file has errors. - * @throws IllegalArgumentException if individual tokens cannot be parsed. - */ - RuleSet reload() throws IllegalConfigurationException; - + RuleSet load(final Reader configReader) throws IllegalConfigurationException; + RuleSet getConfiguration(); - - /** - * TODO document me. - */ - boolean save(RuleSet configuration); + } diff --git a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/PlainConfiguration.java b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/PlainConfiguration.java index 8a5dae8244..5ed28b679a 100644 --- a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/PlainConfiguration.java +++ b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/PlainConfiguration.java @@ -21,10 +21,9 @@ package org.apache.qpid.server.security.access.config; import java.io.BufferedReader; -import java.io.File; import java.io.FileNotFoundException; -import java.io.FileReader; import java.io.IOException; +import java.io.Reader; import java.io.StreamTokenizer; import java.util.HashMap; import java.util.Iterator; @@ -34,14 +33,14 @@ import java.util.Stack; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; + import org.apache.qpid.server.configuration.IllegalConfigurationException; -import org.apache.qpid.server.logging.EventLogger; import org.apache.qpid.server.logging.EventLoggerProvider; import org.apache.qpid.server.security.access.ObjectType; import org.apache.qpid.server.security.access.Operation; import org.apache.qpid.server.security.access.Permission; -public class PlainConfiguration extends AbstractConfiguration +public class PlainConfiguration implements ConfigurationFile { private static final Logger _logger = Logger.getLogger(PlainConfiguration.class); @@ -66,30 +65,30 @@ public class PlainConfiguration extends AbstractConfiguration static final String PROPERTY_KEY_ONLY_MSG = "Incomplete property (key only) at line %d"; static final String PROPERTY_NO_EQUALS_MSG = "Incomplete property (no equals) at line %d"; static final String PROPERTY_NO_VALUE_MSG = "Incomplete property (no value) at line %d"; + private final EventLoggerProvider _eventLogger; + private final String _name; private StreamTokenizer _st; + private RuleSet _config; - public PlainConfiguration(File file, final EventLoggerProvider eventLogger) + public PlainConfiguration(String name, final EventLoggerProvider eventLogger) { - super(file, eventLogger); + _eventLogger = eventLogger; + _name = name; } @Override - public RuleSet load() + public RuleSet load(final Reader configReader) { - RuleSet ruleSet = super.load(); - - File file = getFile(); - FileReader fileReader = null; + _config = new RuleSet(_eventLogger); - try + try(Reader fileReader = configReader) { if(_logger.isDebugEnabled()) { - _logger.debug("About to load ACL file " + file); + _logger.debug("About to load ACL file"); } - fileReader = new FileReader(file); _st = new StreamTokenizer(new BufferedReader(fileReader)); _st.resetSyntax(); // setup the tokenizer @@ -209,29 +208,14 @@ public class PlainConfiguration extends AbstractConfiguration } catch (FileNotFoundException fnfe) { - throw new IllegalConfigurationException(String.format(CONFIG_NOT_FOUND_MSG, file.getName()), fnfe); + throw new IllegalConfigurationException(String.format(CONFIG_NOT_FOUND_MSG, _name), fnfe); } catch (IOException ioe) { - throw new IllegalConfigurationException(String.format(CANNOT_LOAD_MSG, file.getName()), ioe); - } - finally - { - if(fileReader != null) - { - try - { - fileReader.close(); - } - catch (IOException e) - { - throw new IllegalConfigurationException(String.format(CANNOT_CLOSE_MSG, file.getName()), e); - } - } + throw new IllegalConfigurationException(String.format(CANNOT_LOAD_MSG, _name), ioe); } - - return ruleSet; + return _config; } private void parseAcl(Integer number, List<String> args) @@ -333,4 +317,10 @@ public class PlainConfiguration extends AbstractConfiguration { return _st.lineno() - 1; } + + public RuleSet getConfiguration() + { + return _config; + } + } diff --git a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImpl.java b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImpl.java index 1adc6561c7..00b42094b1 100644 --- a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImpl.java +++ b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImpl.java @@ -39,6 +39,7 @@ import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.StateTransition; import org.apache.qpid.server.security.AccessControl; import org.apache.qpid.server.security.access.Operation; +import org.apache.qpid.server.util.urlstreamhandler.data.Handler; public class ACLFileAccessControlProviderImpl extends AbstractConfiguredObject<ACLFileAccessControlProviderImpl> @@ -46,10 +47,15 @@ public class ACLFileAccessControlProviderImpl { private static final Logger LOGGER = Logger.getLogger(ACLFileAccessControlProviderImpl.class); + static + { + Handler.register(); + } + protected DefaultAccessControl _accessControl; protected final Broker _broker; - @ManagedAttributeField + @ManagedAttributeField( afterSet = "reloadAclFile") private String _path; @ManagedObjectFactoryConstructor @@ -112,6 +118,26 @@ public class ACLFileAccessControlProviderImpl _accessControl = new DefaultAccessControl(getPath(), _broker); } + @SuppressWarnings("unused") + private void reloadAclFile() + { + try + { + DefaultAccessControl accessControl = new DefaultAccessControl(getPath(), _broker); + accessControl.open(); + DefaultAccessControl oldAccessControl = _accessControl; + _accessControl = accessControl; + if(oldAccessControl != null) + { + oldAccessControl.close(); + } + } + catch(RuntimeException e) + { + throw new IllegalConfigurationException(e.getMessage(), e); + } + } + @Override public String getPath() { diff --git a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControl.java b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControl.java index c42dc88d53..2998252b51 100644 --- a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControl.java +++ b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControl.java @@ -21,9 +21,14 @@ package org.apache.qpid.server.security.access.plugins; import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; import java.net.InetAddress; import java.net.InetSocketAddress; +import java.net.MalformedURLException; import java.net.SocketAddress; +import java.net.URL; import java.security.AccessController; import java.util.Set; @@ -47,46 +52,81 @@ import org.apache.qpid.server.security.access.config.RuleSet; public class DefaultAccessControl implements AccessControl { private static final Logger _logger = Logger.getLogger(DefaultAccessControl.class); + private final String _fileName; private RuleSet _ruleSet; - private File _aclFile; private final EventLoggerProvider _eventLogger; - public DefaultAccessControl(String fileName, final EventLoggerProvider eventLogger) + public DefaultAccessControl(String name, final EventLoggerProvider eventLogger) { + _fileName = name; _eventLogger = eventLogger; if (_logger.isDebugEnabled()) { - _logger.debug("Creating AccessControl instance using file: " + fileName); + _logger.debug("Creating AccessControl instance"); } - - _aclFile = new File(fileName); } DefaultAccessControl(RuleSet rs) { + _fileName = null; _ruleSet = rs; _eventLogger = rs; } public void open() { - if(_aclFile != null) + if(_fileName != null) { - if (!validate()) - { - throw new IllegalConfigurationException("ACL file '" + _aclFile + "' is not found"); - } - - ConfigurationFile configFile = new PlainConfiguration(_aclFile, _eventLogger); - _ruleSet = configFile.load(); + ConfigurationFile configFile = new PlainConfiguration(_fileName, _eventLogger); + _ruleSet = configFile.load(getReaderFromURLString(_fileName)); } } @Override public boolean validate() { - return _aclFile.exists(); + try + { + getReaderFromURLString(_fileName); + return true; + } + catch(IllegalConfigurationException e) + { + return false; + } + } + + + private static Reader getReaderFromURLString(String urlString) + { + try + { + URL url; + + try + { + url = new URL(urlString); + } + catch (MalformedURLException e) + { + File file = new File(urlString); + try + { + url = file.toURI().toURL(); + } + catch (MalformedURLException notAFile) + { + throw new IllegalConfigurationException("Cannot convert " + urlString + " to a readable resource"); + } + + } + return new InputStreamReader(url.openStream()); + } + catch (IOException e) + { + throw new IllegalConfigurationException("Cannot convert " + urlString + " to a readable resource"); + } } @Override @@ -104,16 +144,10 @@ public class DefaultAccessControl implements AccessControl @Override public void onCreate() { - if(_aclFile != null) + if(_fileName != null) { - //verify it exists - if (!validate()) - { - throw new IllegalConfigurationException("ACL file '" + _aclFile + "' is not found"); - } - //verify it is parsable - new PlainConfiguration(_aclFile, _eventLogger).load(); + new PlainConfiguration(_fileName, _eventLogger).load(getReaderFromURLString(_fileName)); } } diff --git a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/PlainConfigurationTest.java b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/PlainConfigurationTest.java index 6ac21f856a..76435cbae4 100644 --- a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/PlainConfigurationTest.java +++ b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/PlainConfigurationTest.java @@ -18,8 +18,10 @@ */ package org.apache.qpid.server.security.access.config; +import static org.mockito.Mockito.mock; + import java.io.File; -import java.io.FileNotFoundException; +import java.io.FileReader; import java.io.FileWriter; import java.io.PrintWriter; import java.util.Map; @@ -27,15 +29,12 @@ import java.util.Map; import junit.framework.TestCase; import org.apache.qpid.server.configuration.IllegalConfigurationException; -import org.apache.qpid.server.logging.EventLogger; import org.apache.qpid.server.logging.EventLoggerProvider; import org.apache.qpid.server.security.access.ObjectProperties; import org.apache.qpid.server.security.access.ObjectProperties.Property; import org.apache.qpid.server.security.access.ObjectType; import org.apache.qpid.server.security.access.Operation; -import static org.mockito.Mockito.mock; - public class PlainConfigurationTest extends TestCase { private PlainConfiguration writeACLConfig(String...aclData) throws Exception @@ -52,28 +51,11 @@ public class PlainConfigurationTest extends TestCase aclWriter.close(); // Load ruleset - PlainConfiguration configFile = new PlainConfiguration(acl, mock(EventLoggerProvider.class)); - configFile.load(); + PlainConfiguration configFile = new PlainConfiguration(acl.getName(), mock(EventLoggerProvider.class)); + configFile.load(new FileReader(acl)); return configFile; } - public void testMissingACLConfig() throws Exception - { - try - { - // Load ruleset - ConfigurationFile configFile = new PlainConfiguration(new File("doesnotexist"), mock(EventLoggerProvider.class)); - configFile.load(); - - fail("fail"); - } - catch (IllegalConfigurationException ce) - { - assertEquals(String.format(PlainConfiguration.CONFIG_NOT_FOUND_MSG, "doesnotexist"), ce.getMessage()); - assertTrue(ce.getCause() instanceof FileNotFoundException); - } - } - public void testACLFileSyntaxContinuation() throws Exception { try diff --git a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderFactoryTest.java b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderFactoryTest.java index 49697cf5b7..a34ac16e80 100644 --- a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderFactoryTest.java +++ b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderFactoryTest.java @@ -107,7 +107,7 @@ public class ACLFileAccessControlProviderFactoryTest extends QpidTestCase } catch (IllegalConfigurationException e) { - assertTrue("Unexpected exception message: " + e.getMessage(), Pattern.matches("ACL file '.*' is not found", e.getMessage())); + assertTrue("Unexpected exception message: " + e.getMessage(), Pattern.matches("Cannot convert .* to a readable resource", e.getMessage())); } } } diff --git a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImplTest.java b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImplTest.java index 005d2a95bc..82c209bb6f 100644 --- a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImplTest.java +++ b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImplTest.java @@ -73,7 +73,7 @@ public class ACLFileAccessControlProviderImplTest extends QpidTestCase } catch (IllegalConfigurationException e) { - assertEquals("Unexpected exception message:" + e.getMessage(), String.format("ACL file '%s' is not found", aclFilePath ), e.getMessage()); + assertEquals("Unexpected exception message:" + e.getMessage(), String.format("Cannot convert %s to a readable resource", aclFilePath ), e.getMessage()); } } diff --git a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQChannel.java b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQChannel.java index 9a6059ccbf..f7f65e29c2 100644 --- a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQChannel.java +++ b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQChannel.java @@ -122,6 +122,8 @@ public class AMQChannel public static final int DEFAULT_PREFETCH = 4096; private static final Logger _logger = Logger.getLogger(AMQChannel.class); + private final DefaultQueueAssociationClearingTask + _defaultQueueAssociationClearingTask = new DefaultQueueAssociationClearingTask(); //TODO use Broker property to configure message authorization requirements private boolean _messageAuthorizationRequired = Boolean.getBoolean(BrokerProperties.PROPERTY_MSG_AUTH); @@ -139,7 +141,7 @@ public class AMQChannel private long _deliveryTag = 0; /** A channel has a default queue (the last declared) that is used when no queue name is explicitly set */ - private AMQQueue _defaultQueue; + private volatile AMQQueue<?> _defaultQueue; /** This tag is unique per subscription to a queue. The server returns this in response to a basic.consume request. */ private int _consumerTag; @@ -180,11 +182,9 @@ public class AMQChannel private LogSubject _logSubject; private volatile boolean _rollingBack; - private static final Runnable NULL_TASK = new Runnable() { public void run() {} }; private List<MessageInstance> _resendList = new ArrayList<MessageInstance>(); private static final AMQShortString IMMEDIATE_DELIVERY_REPLY_TEXT = new AMQShortString("Immediate delivery is not possible."); - private long _createTime = System.currentTimeMillis(); private final ClientDeliveryMethod _clientDeliveryMethod; @@ -829,7 +829,7 @@ public class AMQChannel getVirtualHost().getEventLogger().message(_logSubject, operationalLogMessage); unsubscribeAllConsumers(); - + setDefaultQueue(null); for (Action<? super AMQChannel> task : _taskList) { task.performAction(this); @@ -1291,17 +1291,6 @@ public class AMQChannel return "("+ _suspended.get() + ", " + _closing.get() + ", " + _connection.isClosing() + ") "+"["+ _connection.toString()+":"+_channelId+"]"; } - public void setDefaultQueue(AMQQueue queue) - { - _defaultQueue = queue; - } - - public AMQQueue getDefaultQueue() - { - return _defaultQueue; - } - - public boolean isClosing() { return _closing.get(); @@ -2123,32 +2112,32 @@ public class AMQChannel catch (AMQQueue.ExistingExclusiveConsumer e) { _connection.closeConnection(AMQConstant.ACCESS_REFUSED, - "Cannot subscribe to queue " + "Cannot subscribe to queue '" + queue1.getName() - + " as it already has an existing exclusive consumer", _channelId); + + "' as it already has an existing exclusive consumer", _channelId); } catch (AMQQueue.ExistingConsumerPreventsExclusive e) { _connection.closeConnection(AMQConstant.ACCESS_REFUSED, - "Cannot subscribe to queue " + "Cannot subscribe to queue '" + queue1.getName() - + " exclusively as it already has a consumer", _channelId); + + "' exclusively as it already has a consumer", _channelId); } catch (AccessControlException e) { - _connection.closeConnection(AMQConstant.ACCESS_REFUSED, "Cannot subscribe to queue " + _connection.closeConnection(AMQConstant.ACCESS_REFUSED, "Cannot subscribe to queue '" + queue1.getName() - + " permission denied", _channelId); + + "' permission denied", _channelId); } catch (MessageSource.ConsumerAccessRefused consumerAccessRefused) { _connection.closeConnection(AMQConstant.ACCESS_REFUSED, - "Cannot subscribe to queue " + "Cannot subscribe to queue '" + queue1.getName() - + " as it already has an incompatible exclusivity policy", _channelId); + + "' as it already has an incompatible exclusivity policy", _channelId); } @@ -2257,7 +2246,7 @@ public class AMQChannel // if the exchange does not exist we raise a channel exception if (destination == null) { - closeChannel(AMQConstant.NOT_FOUND, "Unknown exchange name: " + exchangeName); + closeChannel(AMQConstant.NOT_FOUND, "Unknown exchange name: '" + exchangeName + "'"); } else { @@ -2815,15 +2804,14 @@ public class AMQChannel exchange = virtualHost.getExchange(exchangeName.toString()); if (exchange == null) { - closeChannel(AMQConstant.NOT_FOUND, "Unknown exchange: " + exchangeName); + closeChannel(AMQConstant.NOT_FOUND, "Unknown exchange: '" + exchangeName + "'"); } else if (!(type == null || type.length() == 0) && !exchange.getType().equals(type.asString())) { - _connection.closeConnection(AMQConstant.NOT_ALLOWED, "Attempt to redeclare exchange: " - + - exchangeName - + " of type " + _connection.closeConnection(AMQConstant.NOT_ALLOWED, "Attempt to redeclare exchange: '" + + exchangeName + + "' of type " + exchange.getType() + " to " + type @@ -2850,7 +2838,6 @@ public class AMQChannel { attributes.putAll(FieldTable.convertToMap(arguments)); } - attributes.put(Exchange.ID, null); attributes.put(Exchange.NAME, name); attributes.put(Exchange.TYPE, typeString); attributes.put(Exchange.DURABLE, durable); @@ -2875,8 +2862,8 @@ public class AMQChannel catch (ReservedExchangeNameException e) { _connection.closeConnection(AMQConstant.NOT_ALLOWED, - "Attempt to declare exchange: " + exchangeName + - " which begins with reserved prefix.", getChannelId()); + "Attempt to declare exchange: '" + exchangeName + + "' which begins with reserved prefix.", getChannelId()); } @@ -2885,8 +2872,8 @@ public class AMQChannel exchange = e.getExistingExchange(); if (!new AMQShortString(exchange.getType()).equals(type)) { - _connection.closeConnection(AMQConstant.NOT_ALLOWED, "Attempt to redeclare exchange: " - + exchangeName + " of type " + _connection.closeConnection(AMQConstant.NOT_ALLOWED, "Attempt to redeclare exchange: '" + + exchangeName + "' of type " + exchange.getType() + " to " + type + ".", getChannelId()); @@ -2922,7 +2909,7 @@ public class AMQChannel // note - since 0-8/9/9-1 can't set the alt. exchange this exception should never occur final String message = "Unknown alternate exchange " + (e.getName() != null - ? "name: \"" + e.getName() + "\"" + ? "name: '" + e.getName() + "'" : "id: " + e.getId()); _connection.closeConnection(AMQConstant.NOT_FOUND, message, getChannelId()); @@ -2968,7 +2955,7 @@ public class AMQChannel final ExchangeImpl exchange = virtualHost.getExchange(exchangeName); if (exchange == null) { - closeChannel(AMQConstant.NOT_FOUND, "No such exchange: " + exchangeStr); + closeChannel(AMQConstant.NOT_FOUND, "No such exchange: '" + exchangeStr + "'"); } else { @@ -3045,7 +3032,7 @@ public class AMQChannel else if (isDefaultExchange(exchange)) { _connection.closeConnection(AMQConstant.NOT_ALLOWED, - "Cannot bind the queue " + queueName + " to the default exchange", getChannelId()); + "Cannot bind the queue '" + queueName + "' to the default exchange", getChannelId()); } else @@ -3057,7 +3044,7 @@ public class AMQChannel if (exch == null) { closeChannel(AMQConstant.NOT_FOUND, - "Exchange " + exchangeName + " does not exist."); + "Exchange '" + exchangeName + "' does not exist."); } else { @@ -3137,7 +3124,7 @@ public class AMQChannel queueName = queueStr.intern(); } - AMQQueue queue; + AMQQueue<?> queue; //TODO: do we need to check that the queue already exists with exactly the same "configuration"? @@ -3148,19 +3135,19 @@ public class AMQChannel if (queue == null) { closeChannel(AMQConstant.NOT_FOUND, - "Queue: " + "Queue: '" + queueName - + " not found on VirtualHost(" - + virtualHost - + ")."); + + "' not found on VirtualHost '" + + virtualHost.getName() + + "'."); } else { if (!queue.verifySessionAccess(this)) { - _connection.closeConnection(AMQConstant.NOT_ALLOWED, "Queue " + _connection.closeConnection(AMQConstant.NOT_ALLOWED, "Queue '" + queue.getName() - + " is exclusive, but not created on this Connection.", getChannelId()); + + "' is exclusive, but not created on this Connection.", getChannelId()); } else { @@ -3190,7 +3177,6 @@ public class AMQChannel QueueArgumentsConverter.convertWireArgsToModel(FieldTable.convertToMap(arguments)); final String queueNameString = AMQShortString.toString(queueName); attributes.put(Queue.NAME, queueNameString); - attributes.put(Queue.ID, UUID.randomUUID()); attributes.put(Queue.DURABLE, durable); LifetimePolicy lifetimePolicy; @@ -3237,9 +3223,9 @@ public class AMQChannel if (!queue.verifySessionAccess(this)) { - _connection.closeConnection(AMQConstant.NOT_ALLOWED, "Queue " + _connection.closeConnection(AMQConstant.NOT_ALLOWED, "Queue '" + queue.getName() - + " is exclusive, but not created on this Connection.", getChannelId()); + + "' is exclusive, but not created on this Connection.", getChannelId()); } else if (queue.isExclusive() != exclusive) @@ -3333,27 +3319,27 @@ public class AMQChannel if (queue == null) { - closeChannel(AMQConstant.NOT_FOUND, "Queue " + queueName + " does not exist."); + closeChannel(AMQConstant.NOT_FOUND, "Queue '" + queueName + "' does not exist."); } else { if (ifEmpty && !queue.isEmpty()) { - closeChannel(AMQConstant.IN_USE, "Queue: " + queueName + " is not empty."); + closeChannel(AMQConstant.IN_USE, "Queue: '" + queueName + "' is not empty."); } else if (ifUnused && !queue.isUnused()) { // TODO - Error code - closeChannel(AMQConstant.IN_USE, "Queue: " + queueName + " is still used."); + closeChannel(AMQConstant.IN_USE, "Queue: '" + queueName + "' is still used."); } else { if (!queue.verifySessionAccess(this)) { - _connection.closeConnection(AMQConstant.NOT_ALLOWED, "Queue " + _connection.closeConnection(AMQConstant.NOT_ALLOWED, "Queue '" + queue.getName() - + " is exclusive, but not created on this Connection.", getChannelId()); + + "' is exclusive, but not created on this Connection.", getChannelId()); } else @@ -3393,7 +3379,7 @@ public class AMQChannel } else if ((queueName != null) && (queue = virtualHost.getQueue(queueName.toString())) == null) { - closeChannel(AMQConstant.NOT_FOUND, "Queue " + queueName + " does not exist."); + closeChannel(AMQConstant.NOT_FOUND, "Queue '" + queueName + "' does not exist."); } else if (!queue.verifySessionAccess(this)) { @@ -3426,14 +3412,14 @@ public class AMQChannel @Override public void receiveQueueUnbind(final AMQShortString queueName, final AMQShortString exchange, - final AMQShortString routingKey, + final AMQShortString bindingKey, final FieldTable arguments) { if(_logger.isDebugEnabled()) { _logger.debug("RECV[" + _channelId + "] QueueUnbind[" +" queue: " + queueName + " exchange: " + exchange + - " bindingKey: " + routingKey + + " bindingKey: " + bindingKey + " arguments: " + arguments + " ]"); } @@ -3450,14 +3436,14 @@ public class AMQChannel { String message = useDefaultQueue ? "No default queue defined on channel and queue was null" - : "Queue " + queueName + " does not exist."; + : "Queue '" + queueName + "' does not exist."; closeChannel(AMQConstant.NOT_FOUND, message); } else if (isDefaultExchange(exchange)) { - _connection.closeConnection(AMQConstant.NOT_ALLOWED, "Cannot unbind the queue " + _connection.closeConnection(AMQConstant.NOT_ALLOWED, "Cannot unbind the queue '" + queue.getName() - + " from the default exchange", getChannelId()); + + "' from the default exchange", getChannelId()); } else @@ -3467,9 +3453,9 @@ public class AMQChannel if (exch == null) { - closeChannel(AMQConstant.NOT_FOUND, "Exchange " + exchange + " does not exist."); + closeChannel(AMQConstant.NOT_FOUND, "Exchange '" + exchange + "' does not exist."); } - else if (!exch.hasBinding(String.valueOf(routingKey), queue)) + else if (!exch.hasBinding(String.valueOf(bindingKey), queue)) { closeChannel(AMQConstant.NOT_FOUND, "No such binding"); } @@ -3477,7 +3463,7 @@ public class AMQChannel { try { - exch.deleteBinding(String.valueOf(routingKey), queue); + exch.deleteBinding(String.valueOf(bindingKey), queue); final AMQMethodBody responseBody = _connection.getMethodRegistry().createQueueUnbindOkBody(); sync(); @@ -3598,4 +3584,37 @@ public class AMQChannel return exchangeName == null || AMQShortString.EMPTY_STRING.equals(exchangeName); } + private void setDefaultQueue(AMQQueue<?> queue) + { + AMQQueue<?> currentDefaultQueue = _defaultQueue; + if (queue != currentDefaultQueue) + { + if (currentDefaultQueue != null) + { + currentDefaultQueue.removeDeleteTask(_defaultQueueAssociationClearingTask); + } + if (queue != null) + { + queue.addDeleteTask(_defaultQueueAssociationClearingTask); + } + } + _defaultQueue = queue; + } + + private AMQQueue getDefaultQueue() + { + return _defaultQueue; + } + + private class DefaultQueueAssociationClearingTask implements Action<AMQQueue> + { + @Override + public void performAction(final AMQQueue queue) + { + if ( queue == _defaultQueue) + { + _defaultQueue = null; + } + } + } } diff --git a/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java b/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java index f5827a3766..01c11b9eca 100644 --- a/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java +++ b/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java @@ -518,6 +518,11 @@ public class Session_1_0 implements SessionEventListener, AMQSessionModel<Sessio } _connection.sessionEnded(this); + performCloseTasks(); + if(_modelObject != null) + { + _modelObject.delete(); + } } diff --git a/qpid/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/store/derby/DerbySystemConfigImpl.java b/qpid/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/store/derby/DerbySystemConfigImpl.java index a8b9edaa12..0cc4f2b18c 100644 --- a/qpid/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/store/derby/DerbySystemConfigImpl.java +++ b/qpid/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/store/derby/DerbySystemConfigImpl.java @@ -20,7 +20,8 @@ */ package org.apache.qpid.server.store.derby; -import org.apache.qpid.server.BrokerOptions; +import java.util.Map; + import org.apache.qpid.server.configuration.updater.TaskExecutor; import org.apache.qpid.server.logging.EventLogger; import org.apache.qpid.server.logging.LogRecorder; @@ -48,10 +49,10 @@ public class DerbySystemConfigImpl extends AbstractSystemConfig<DerbySystemConfi public DerbySystemConfigImpl(final TaskExecutor taskExecutor, final EventLogger eventLogger, final LogRecorder logRecorder, - final BrokerOptions brokerOptions, + final Map<String,Object> attributes, final BrokerShutdownProvider brokerShutdownProvider) { - super(taskExecutor, eventLogger, logRecorder, brokerOptions, brokerShutdownProvider); + super(taskExecutor, eventLogger, logRecorder, attributes, brokerShutdownProvider); } @Override diff --git a/qpid/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/virtualhostnode/derby/DerbyVirtualHostNodeImpl.java b/qpid/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/virtualhostnode/derby/DerbyVirtualHostNodeImpl.java index 4bb3cc5376..dc768aff09 100644 --- a/qpid/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/virtualhostnode/derby/DerbyVirtualHostNodeImpl.java +++ b/qpid/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/virtualhostnode/derby/DerbyVirtualHostNodeImpl.java @@ -21,6 +21,8 @@ package org.apache.qpid.server.virtualhostnode.derby; +import java.util.Collection; +import java.util.Collections; import java.util.Map; import org.apache.qpid.server.logging.messages.ConfigStoreMessages; @@ -33,7 +35,9 @@ import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.server.store.derby.DerbyConfigurationStore; import org.apache.qpid.server.virtualhostnode.AbstractStandardVirtualHostNode; -@ManagedObject( category = false, type = DerbyVirtualHostNodeImpl.VIRTUAL_HOST_NODE_TYPE ) +@ManagedObject( category = false, + type = DerbyVirtualHostNodeImpl.VIRTUAL_HOST_NODE_TYPE, + validChildTypes = "org.apache.qpid.server.virtualhostnode.derby.DerbyVirtualHostNodeImpl#getSupportedChildTypes()" ) public class DerbyVirtualHostNodeImpl extends AbstractStandardVirtualHostNode<DerbyVirtualHostNodeImpl> implements DerbyVirtualHostNode<DerbyVirtualHostNodeImpl> { public static final String VIRTUAL_HOST_NODE_TYPE = "DERBY"; @@ -70,4 +74,10 @@ public class DerbyVirtualHostNodeImpl extends AbstractStandardVirtualHostNode<De { return getClass().getSimpleName() + " [id=" + getId() + ", name=" + getName() + ", storePath=" + getStorePath() + "]"; } + + + public static Map<String, Collection<String>> getSupportedChildTypes() + { + return Collections.singletonMap(VirtualHost.class.getSimpleName(), getSupportedVirtualHostTypes(true)); + } } diff --git a/qpid/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCSystemConfigImpl.java b/qpid/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCSystemConfigImpl.java index a552b170a0..9c3d33fc04 100644 --- a/qpid/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCSystemConfigImpl.java +++ b/qpid/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCSystemConfigImpl.java @@ -20,7 +20,8 @@ */ package org.apache.qpid.server.store.jdbc; -import org.apache.qpid.server.BrokerOptions; +import java.util.Map; + import org.apache.qpid.server.configuration.updater.TaskExecutor; import org.apache.qpid.server.logging.EventLogger; import org.apache.qpid.server.logging.LogRecorder; @@ -50,10 +51,10 @@ public class JDBCSystemConfigImpl extends AbstractSystemConfig<JDBCSystemConfigI public JDBCSystemConfigImpl(final TaskExecutor taskExecutor, final EventLogger eventLogger, final LogRecorder logRecorder, - final BrokerOptions brokerOptions, + final Map<String,Object> attributes, final BrokerShutdownProvider brokerShutdownProvider) { - super(taskExecutor, eventLogger, logRecorder, brokerOptions, brokerShutdownProvider); + super(taskExecutor, eventLogger, logRecorder, attributes, brokerShutdownProvider); } @Override diff --git a/qpid/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNodeImpl.java b/qpid/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNodeImpl.java index eab53e6744..cb20549b80 100644 --- a/qpid/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNodeImpl.java +++ b/qpid/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNodeImpl.java @@ -20,6 +20,8 @@ */ package org.apache.qpid.server.virtualhostnode.jdbc; +import java.util.Collection; +import java.util.Collections; import java.util.Map; import org.apache.qpid.server.model.Broker; @@ -31,7 +33,8 @@ import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.server.store.jdbc.GenericJDBCConfigurationStore; import org.apache.qpid.server.virtualhostnode.AbstractStandardVirtualHostNode; -@ManagedObject(type = JDBCVirtualHostNodeImpl.VIRTUAL_HOST_NODE_TYPE, category = false ) +@ManagedObject(type = JDBCVirtualHostNodeImpl.VIRTUAL_HOST_NODE_TYPE, category = false , + validChildTypes = "org.apache.qpid.server.virtualhostnode.jdbc.JDBCVirtualHostNodeImpl#getSupportedChildTypes()") public class JDBCVirtualHostNodeImpl extends AbstractStandardVirtualHostNode<JDBCVirtualHostNodeImpl> implements JDBCVirtualHostNode<JDBCVirtualHostNodeImpl> { public static final String VIRTUAL_HOST_NODE_TYPE = "JDBC"; @@ -97,4 +100,10 @@ public class JDBCVirtualHostNodeImpl extends AbstractStandardVirtualHostNode<JDB ", connectionPoolType=" + getConnectionPoolType() + ", username=" + getUsername() + "]"; } + + + public static Map<String, Collection<String>> getSupportedChildTypes() + { + return Collections.singletonMap(VirtualHost.class.getSimpleName(), getSupportedVirtualHostTypes(true)); + } } 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 1e795480fc..cafde3b7f9 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 @@ -54,9 +54,6 @@ public class HelperServlet extends AbstractServlet _mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true); Action[] supportedActions = { - new ListBrokerAttribute(Broker.SUPPORTED_VIRTUALHOSTNODE_TYPES, "ListVirtualHostNodeTypes"), - new ListBrokerAttribute(Broker.SUPPORTED_VIRTUALHOST_TYPES, "ListVirtualHostTypes"), - new ListBrokerAttribute(Broker.SUPPORTED_PREFERENCES_PROVIDER_TYPES, "ListPreferencesProvidersTypes"), new ListBrokerAttribute(Broker.PRODUCT_VERSION, "version"), new ListGroupProviderAttributes(), new ListAccessControlProviderAttributes(), diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MetaDataServlet.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MetaDataServlet.java index 2947cfb85b..01dd873aa5 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MetaDataServlet.java +++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MetaDataServlet.java @@ -24,6 +24,7 @@ import java.io.IOException; import java.io.Writer; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; @@ -101,9 +102,24 @@ public class MetaDataServlet extends AbstractServlet Map<String,Object> typeDetails = new LinkedHashMap<>(); typeDetails.put("attributes", processAttributes(type)); typeDetails.put("managedInterfaces", getManagedInterfaces(type)); + typeDetails.put("validChildTypes", getValidChildTypes(type)); return typeDetails; } + private Map<String, Collection<String>> getValidChildTypes(final Class<? extends ConfiguredObject> type) + { + Map<String, Collection<String>> validChildTypes = new HashMap<>(); + for(Class<? extends ConfiguredObject> childType : _instance.getChildTypes(ConfiguredObjectTypeRegistry.getCategory(type))) + { + Collection<String> validValues = _instance.getTypeRegistry().getValidChildTypes(type, childType); + if(validValues != null) + { + validChildTypes.put(childType.getSimpleName(), validValues); + } + } + return validChildTypes; + } + private Set<String> getManagedInterfaces(Class<? extends ConfiguredObject> type) { Set<String> interfaces = new HashSet<>(); 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 0bc0a4514f..71ec6e786f 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 @@ -36,7 +36,6 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; -import javax.xml.bind.DatatypeConverter; import org.apache.log4j.Logger; import org.codehaus.jackson.map.ObjectMapper; @@ -46,6 +45,7 @@ import org.apache.qpid.server.configuration.IllegalConfigurationException; import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.util.urlstreamhandler.data.Handler; +import org.apache.qpid.util.DataUrlUtils; public class RestServlet extends AbstractServlet { @@ -62,13 +62,20 @@ public class RestServlet extends AbstractServlet public static final String INHERITED_ACTUALS_PARAM = "inheritedActuals"; public static final String EXTRACT_INITIAL_CONFIG_PARAM = "extractInitialConfig"; + /** + * Signifies that the agent wishes the servlet to set the Content-Disposition on the + * response with the value attachment. This filename will be derived from the parameter value. + */ + public static final String CONTENT_DISPOSITION_ATTACHMENT_FILENAME_PARAM = "contentDispositionAttachmentFilename"; + public static final Set<String> RESERVED_PARAMS = new HashSet<>(Arrays.asList(DEPTH_PARAM, SORT_PARAM, ACTUALS_PARAM, INCLUDE_SYS_CONTEXT_PARAM, EXTRACT_INITIAL_CONFIG_PARAM, - INHERITED_ACTUALS_PARAM)); + INHERITED_ACTUALS_PARAM, + CONTENT_DISPOSITION_ATTACHMENT_FILENAME_PARAM)); private Class<? extends ConfiguredObject>[] _hierarchy; @@ -316,19 +323,29 @@ public class RestServlet extends AbstractServlet @Override protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + // TODO - sort special params, everything else should act as a filter + String attachmentFilename = request.getParameter(CONTENT_DISPOSITION_ATTACHMENT_FILENAME_PARAM); + boolean extractInitialConfig = getBooleanParameterFromRequest(request, EXTRACT_INITIAL_CONFIG_PARAM); + response.setContentType("application/json"); response.setStatus(HttpServletResponse.SC_OK); - setCachingHeadersOnResponse(response); + if (attachmentFilename == null) + { + setCachingHeadersOnResponse(response); + } + else + { + setContentDispositionHeaderIfNecessary(response, attachmentFilename); + } Collection<ConfiguredObject<?>> allObjects = getObjects(request); - // TODO - sort special params, everything else should act as a filter - boolean extractInitialConfig = getBooleanParameterFromRequest(request, EXTRACT_INITIAL_CONFIG_PARAM); int depth; boolean actuals; boolean includeSystemContext; boolean inheritedActuals; + if(extractInitialConfig) { depth = Integer.MAX_VALUE; @@ -344,20 +361,35 @@ public class RestServlet extends AbstractServlet inheritedActuals = getBooleanParameterFromRequest(request, INHERITED_ACTUALS_PARAM); } - List<Map<String, Object>> output = new ArrayList<Map<String, Object>>(); + List<Map<String, Object>> output = new ArrayList<>(); for(ConfiguredObject configuredObject : allObjects) { output.add(_objectConverter.convertObjectToMap(configuredObject, getConfiguredClass(), depth, actuals, inheritedActuals, includeSystemContext, extractInitialConfig)); } + Writer writer = getOutputWriter(request, response); ObjectMapper mapper = new ObjectMapper(); mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true); mapper.writeValue(writer, extractInitialConfig && output.size() == 1 ? output.get(0) : output); + } - response.setContentType("application/json"); - response.setStatus(HttpServletResponse.SC_OK); + private void setContentDispositionHeaderIfNecessary(final HttpServletResponse response, + final String attachmentFilename) + { + if (attachmentFilename != null) + { + String filenameRfc2183 = ensureFilenameIsRfc2183(attachmentFilename); + if (filenameRfc2183.length() > 0) + { + response.setHeader("Content-disposition", String.format("attachment; filename=\"%s\"", filenameRfc2183)); + } + else + { + response.setHeader("Content-disposition", String.format("attachment")); // Agent will allow user to choose a name + } + } } private Class<? extends ConfiguredObject> getConfiguredClass() @@ -407,8 +439,7 @@ public class RestServlet extends AbstractServlet { byte[] data = new byte[(int) part.getSize()]; part.getInputStream().read(data); - StringBuilder inlineURL = new StringBuilder("data:;base64,"); - inlineURL.append(DatatypeConverter.printBase64Binary(data)); + String inlineURL = DataUrlUtils.getDataUrlForBytes(data); fileUploads.put(part.getName(),inlineURL.toString()); } } @@ -671,4 +702,10 @@ public class RestServlet extends AbstractServlet return Boolean.parseBoolean(request.getParameter(paramName)); } + private String ensureFilenameIsRfc2183(final String requestedFilename) + { + String fileNameRfc2183 = requestedFilename.replaceAll("[\\P{InBasic_Latin}\\\\:/]", ""); + return fileNameRfc2183; + } + } diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/accesscontrolprovider/aclfile/add.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/accesscontrolprovider/aclfile/add.html new file mode 100644 index 0000000000..796988c410 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/accesscontrolprovider/aclfile/add.html @@ -0,0 +1,64 @@ +<!-- + ~ 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> + <div id="addAccessControlProvider.oldBrowserWarning" class="infoMessage hidden clear"></div> + <div class="clear"> + <div id="addAccessControlProvider.serverPathLabel" class="formLabel-labelCell tableContainer-labelCell">Server path or upload*:</div> + <div class="formLabel-controlCell tableContainer-valueCell"> + <input type="text" id="addAccessControlProvider.serverPath" + data-dojo-type="dijit/form/ValidationTextBox" + data-dojo-props=" + name: 'serverPath', + placeHolder: 'access control provider file server path', + required: true, + excluded: true, + promptMessage: 'Location of the access control provider file on the server', + title: 'Enter the access control provider file path'" /> + + <!-- Hidden and used purely for form submission --> + <input type="hidden" id="addAccessControlProvider.path" + data-dojo-type="dijit/form/ValidationTextBox" + data-dojo-props=" + name: 'path', + required: true" /> + </div> + + <div id="addAccessControlProvider.uploadFields"> + <div id="addAccessControlProvider.fileLabel" class="formLabel-labelCell tableContainer-labelCell"></div> + <div class="fileUpload clear"> + <span id="addAccessControlProvider.selectedFile" class="infoMessage"></span> + <span id="addAccessControlProvider.selectedFileStatus"></span> + </div> + + <div class="fileUpload clear"> + <input type="file" id="addAccessControlProvider.file" + multiple="false" + data-dojo-type="dojox/form/Uploader" + data-dojo-props="label: 'Upload'"/> + <button id="addAccessControlProvider.fileClearButton" + data-dojo-type="dijit/form/Button" + data-dojo-props="label: 'Clear', + disabled: true"> + </button> + </div> + </div> + + </div> +</div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/addAccessControlProvider.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/addAccessControlProvider.html new file mode 100644 index 0000000000..07a0c4cf83 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/addAccessControlProvider.html @@ -0,0 +1,66 @@ +<!-- + ~ 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 class="dijitHidden"> + <div data-dojo-type="dijit/Dialog" data-dojo-props="title:'Access Control Provider'" id="addAccessControlProvider"> + <div id="addAccessControlProvider.contentPane"> + <form id="addAccessControlProvider.form" method="post" data-dojo-type="dijit/form/Form"> + <div class="formBox"> + <div class="clear"> + <div class="formLabel-labelCell tableContainer-labelCell">Name*:</div> + <div class="formLabel-controlCell tableContainer-valueCell"> + <input type="text" id="addAccessControlProvider.name" + data-dojo-type="dijit/form/ValidationTextBox" + data-dojo-props=" + name: 'name', + placeHolder: 'access control provider name', + required: true, + promptMessage: 'Name of access control provider, must be unique', + title: 'Enter a unique access control provider name per broker'" /> + </div> + </div> + <div class="clear"> + <div class="formLabel-labelCell tableContainer-labelCell">Type*:</div> + <div class="tableContainer-valueCell formLabel-controlCell"> + <select id="addAccessControlProvider.type" data-dojo-type="dijit/form/FilteringSelect" + data-dojo-props=" + name: 'type', + required: true, + placeHolder: 'select access control provider type', + promptMessage: 'Type of access control provider', + title: 'Select access control provider type', + searchAttr: 'name'"> + </select> + </div> + </div> + + <div class="clear"> + <div id="addAccessControlProvider.typeFields"></div> + </div> + </div> + </form> + <div class="clear"> + </div> + </div> + + <div class="dijitDialogPaneActionBar"> + <button data-dojo-type="dijit/form/Button" id="addAccessControlProvider.addButton" data-dojo-props="label: 'Save'" type="submit"></button> + <button data-dojo-type="dijit/form/Button" id="addAccessControlProvider.cancelButton" data-dojo-props="label: 'Cancel'" ></button> + </div> + </div> +</div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/addStore.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/addStore.html new file mode 100644 index 0000000000..dd6e7a3d38 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/addStore.html @@ -0,0 +1,66 @@ +<!-- + ~ 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 class="dijitHidden"> + <div data-dojo-type="dijit/Dialog" data-dojo-props="title:'Add Store'" id="addStore"> + <div id="addStore.contentPane"> + <form id="addStore.form" method="post" data-dojo-type="dijit/form/Form"> + <div class="formBox"> + <div class="clear"> + <div class="formLabel-labelCell tableContainer-labelCell">Name*:</div> + <div class="formLabel-controlCell tableContainer-valueCell"> + <input type="text" id="addStore.name" + data-dojo-type="dijit/form/ValidationTextBox" + data-dojo-props=" + name: 'name', + placeHolder: 'store name', + required: true, + promptMessage: 'Name of store, must be unique', + title: 'Enter a unique store name per broker'" /> + </div> + </div> + <div class="clear"> + <div class="formLabel-labelCell tableContainer-labelCell">Type*:</div> + <div class="tableContainer-valueCell formLabel-controlCell"> + <select id="addStore.type" data-dojo-type="dijit/form/FilteringSelect" + data-dojo-props=" + name: 'type', + required: true, + placeHolder: 'store type', + promptMessage: 'Type of store', + title: 'Select type', + searchAttr: 'name'"> + </select> + </div> + </div> + <div class="clear"> + <div id="addStore.typeFields"></div> + </div> + </div> + </form> + <div class="clear"> + </div> + </div> + + <div class="dijitDialogPaneActionBar"> + <button data-dojo-type="dijit/form/Button" id="addStore.addButton" data-dojo-props="label: 'Save'" type="submit"></button> + <button data-dojo-type="dijit/form/Button" id="addStore.cancelButton" data-dojo-props="label: 'Cancel'" ></button> + </div> + </div> +</div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/addVirtualHostNodeAndVirtualHost.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/addVirtualHostNodeAndVirtualHost.html index 3e3e931829..383c782d60 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/addVirtualHostNodeAndVirtualHost.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/addVirtualHostNodeAndVirtualHost.html @@ -59,6 +59,34 @@ <div id="addVirtualHostNode.typeFields"></div> + <div id="addVirtualHostNode.uploadFields" class="clear"> + <div class="formLabel-labelCell"> + <label for="addVirtualHostNode.upload">Upload virtualhost configuration from file:</label> + </div> + <div class="formLabel-controlCell"> + <input id="addVirtualHostNode.upload" type="checkbox" + data-dojo-type="dijit.form.CheckBox" + data-dojo-props=" + name: 'upload'" /> + </div> + <div id="addVirtualHostNode.fileFields" class="clear"> + <div class="formLabel-labelCell"> + <label for="addVirtualHostNode.file">Select JSON file*:</label> + </div> + <div class="tableContainer-valueCell formLabel-controlCell"> + <input type="file" id="addVirtualHostNode.file" + multiple="false" + data-dojo-type="dojox.form.Uploader" + data-dojo-props=" + label: 'Select'"/> + <span id="addVirtualHostNode.selectedFile" class="infoMessage"></span> + <span id="addVirtualHostNode.selectedFileStatus"></span> + </div> + </div> + </div> + + <div class="clear"></div> + <div data-dojo-type="dijit/TitlePane" data-dojo-props="title: 'Context variables', open: false"> <div id="addVirtualHostNode.context"></div> </div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/css/common.css b/qpid/java/broker-plugins/management-http/src/main/java/resources/css/common.css index d04117b266..a18562fa1a 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/css/common.css +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/css/common.css @@ -215,6 +215,30 @@ div .messages { height: 16px; } +.loadingIcon +{ + background: url("../dojo/dojox/image/resources/images/loading.gif") no-repeat; + width: 16px; + height: 16px; + background-size: contain; + display: inline-block; +} + +.loadedIcon +{ + background: url("../dojo/dijit/icons/images/commonIconsObjActEnabled_rtl.png") no-repeat; + background-position: -352px -0px; + width: 16px; + height: 16px; + display: inline-block; +} + +.fileUpload +{ + float: right; + padding: 5px; +} + .infoMessage { padding: 5px; 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 eb742bbfa0..379a25bbcd 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 @@ -25,6 +25,7 @@ <link rel="stylesheet" href="dojo/dojox/grid/enhanced/resources/claro/EnhancedGrid.css"> <link rel="stylesheet" href="dojo/dojox/grid/enhanced/resources/EnhancedGrid_rtl.css"> <link rel="stylesheet" href="dojo/dojox/form/resources/CheckedMultiSelect.css"> + <link rel="stylesheet" href="dojo/dojox/form/resources/FileInput.css" /> <link rel="stylesheet" href="css/common.css" media="screen"> <script> function getContextPath() diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/metadata.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/metadata.js index 749b9b89cb..c62ba5d5d4 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/metadata.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/metadata.js @@ -69,7 +69,13 @@ define(["dojo/_base/xhr", implementsManagedInterface: function (category, type, managedInterfaceName) { return this.getMetaData(category, type).managedInterfaces.indexOf(managedInterfaceName) >= 0; + }, + validChildTypes: function (category, type, childCategory) + { + var metaData = this.getMetaData(category, type); + return metaData ? metaData.validChildTypes[childCategory] : []; } + }; metadata._init(); 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 c6741ca3cc..161ce4f83c 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 @@ -159,8 +159,8 @@ define(["dojo/_base/xhr", this.deletePreferencesProviderButton = query(".deletePreferencesProviderButton", node)[0]; this.preferencesProviderAttributes = dom.byId("preferencesProviderAttributes") this.preferencesNode = query(".preferencesProviderDetails", node)[0]; - this.authenticationProviderDetailsContainer = query(".authenticationProviderDetails", node)[0]; +this.authenticationProviderDetailsContainer = query(".authenticationProviderDetails", node)[0]; this.query = "api/latest/authenticationprovider/" + encodeURIComponent(authProviderObj.name); } diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js index 5363882eb2..a0a2e8324f 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js @@ -23,6 +23,7 @@ define(["dojo/_base/xhr", "dojo/query", "dojo/json", "dojo/_base/connect", + "dojo/store/Memory", "qpid/common/properties", "qpid/common/updater", "qpid/common/util", @@ -33,7 +34,7 @@ define(["dojo/_base/xhr", "qpid/management/addAuthenticationProvider", "qpid/management/addVirtualHostNodeAndVirtualHost", "qpid/management/addPort", - "qpid/management/addKeystore", + "qpid/management/addStore", "qpid/management/addGroupProvider", "qpid/management/addAccessControlProvider", "qpid/management/editBroker", @@ -50,8 +51,8 @@ define(["dojo/_base/xhr", "dijit/Menu", "dijit/MenuItem", "dojo/domReady!"], - function (xhr, parser, query, json, connect, properties, updater, util, UpdatableStore, EnhancedGrid, registry, entities, - addAuthenticationProvider, addVirtualHostNodeAndVirtualHost, addPort, addKeystore, addGroupProvider, addAccessControlProvider, editBroker) { + function (xhr, parser, query, json, connect, memory, properties, updater, util, UpdatableStore, EnhancedGrid, registry, entities, + addAuthenticationProvider, addVirtualHostNodeAndVirtualHost, addPort, addStore, addGroupProvider, addAccessControlProvider, editBroker) { var brokerAttributeNames = ["name", "operatingSystem", "platform", "productVersion", "modelVersion", "defaultVirtualHost", "statisticsReportingPeriod", "statisticsReportingResetEnabled", @@ -153,7 +154,11 @@ define(["dojo/_base/xhr", var addKeystoreButton = query(".addKeystore", contentPane.containerNode)[0]; connect.connect(registry.byNode(addKeystoreButton), "onClick", - function(evt){ addKeystore.showKeystoreDialog() }); + function(evt) + { + addStore.setupTypeStore("KeyStore"); + addStore.show(); + }); var deleteKeystore = query(".deleteKeystore", contentPane.containerNode)[0]; connect.connect(registry.byNode(deleteKeystore), "onClick", @@ -168,7 +173,11 @@ define(["dojo/_base/xhr", var addTruststoreButton = query(".addTruststore", contentPane.containerNode)[0]; connect.connect(registry.byNode(addTruststoreButton), "onClick", - function(evt){ addKeystore.showTruststoreDialog() }); + function(evt) + { + addStore.setupTypeStore("TrustStore"); + addStore.show(); + }); var deleteTruststore = query(".deleteTruststore", contentPane.containerNode)[0]; connect.connect(registry.byNode(deleteTruststore), "onClick", diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/KeyStore.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/KeyStore.js index 84103fdc47..6cb9ad727d 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/KeyStore.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/KeyStore.js @@ -29,16 +29,15 @@ define(["dojo/dom", "qpid/common/updater", "qpid/common/util", "qpid/common/formatter", - "qpid/management/addKeystore", + "qpid/management/addStore", "dojo/domReady!"], - function (dom, xhr, parser, query, connect, registry, entities, properties, updater, util, formatter, addKeystore) { + function (dom, xhr, parser, query, connect, registry, entities, properties, updater, util, formatter, addStore) { - function KeyStore(name, parent, controller, objectType) { + function KeyStore(name, parent, controller) { this.keyStoreName = name; this.controller = controller; this.modelObj = { type: "keystore", name: name, parent: parent}; this.url = "api/latest/keystore/" + encodeURIComponent(name); - this.dialog = addKeystore.showKeystoreDialog; } KeyStore.prototype.getTitle = function() { @@ -48,7 +47,7 @@ define(["dojo/dom", KeyStore.prototype.open = function(contentPane) { var that = this; this.contentPane = contentPane; - xhr.get({url: "showKeyStore.html", + xhr.get({url: "showStore.html", sync: true, load: function(data) { contentPane.containerNode.innerHTML = data; @@ -60,22 +59,22 @@ define(["dojo/dom", that.keyStoreUpdater.update(); - var deleteKeyStoreButton = query(".deleteKeyStoreButton", contentPane.containerNode)[0]; + var deleteKeyStoreButton = query(".deleteStoreButton", contentPane.containerNode)[0]; var node = registry.byNode(deleteKeyStoreButton); connect.connect(node, "onClick", function(evt){ that.deleteKeyStore(); }); - var editKeyStoreButton = query(".editKeyStoreButton", contentPane.containerNode)[0]; + var editKeyStoreButton = query(".editStoreButton", contentPane.containerNode)[0]; var node = registry.byNode(editKeyStoreButton); connect.connect(node, "onClick", function(evt){ xhr.get({url: that.url, sync: properties.useSyncGet, handleAs: "json", content: { actuals: true }}) .then(function(data) { - // calls showKeystoreDialog - that.dialog(data[0], that.url); + addStore.setupTypeStore("KeyStore"); + addStore.show(data[0], that.url); }); }); }}); @@ -88,9 +87,10 @@ define(["dojo/dom", function KeyStoreUpdater(containerNode, keyStoreObj, controller, url) { var that = this; + this.keyStoreDetailsContainer = query(".typeFieldsContainer", containerNode)[0]; function findNode(name) { - return query("." + name + "Value", containerNode)[0]; + return query("." + name, containerNode)[0]; } function storeNodes(names) @@ -101,12 +101,8 @@ define(["dojo/dom", } storeNodes(["name", - "path", - "keyStoreType", - "keyStoreState", - "keyManagerFactoryAlgorithm", - "certificateAlias", - "peersOnly" + "type", + "state" ]); this.query = url; @@ -122,22 +118,27 @@ define(["dojo/dom", KeyStoreUpdater.prototype.updateHeader = function() { this.name.innerHTML = entities.encode(String(this.keyStoreData[ "name" ])); - this.path.innerHTML = entities.encode(String(this.keyStoreData[ "path" ])); - this.keyStoreType.innerHTML = entities.encode(String(this.keyStoreData[ "keyStoreType" ])); - this.keyStoreState.innerHTML = entities.encode(String(this.keyStoreData[ "state" ])); - this.keyManagerFactoryAlgorithm.innerHTML = entities.encode(String(this.keyStoreData[ "keyManagerFactoryAlgorithm" ])); - this.certificateAlias.innerHTML = this.keyStoreData[ "certificateAlias" ] ? entities.encode(String( this.keyStoreData[ "certificateAlias" ])) : ""; + this.type.innerHTML = entities.encode(String(this.keyStoreData[ "type" ])); + this.state.innerHTML = entities.encode(String(this.keyStoreData[ "state" ])); }; KeyStoreUpdater.prototype.update = function() { - var thisObj = this; + var that = this; xhr.get({url: this.query, sync: properties.useSyncGet, handleAs: "json"}).then(function(data) { - thisObj.keyStoreData = data[0]; - thisObj.updateHeader(); + that.keyStoreData = data[0]; + that.updateHeader(); + + require(["qpid/management/store/" + encodeURIComponent(that.keyStoreData.type.toLowerCase()) + "/show"], + function(DetailsUI) + { + that.details = new DetailsUI({containerNode:that.keyStoreDetailsContainer, parent: that}); + that.details.update(that.keyStoreData); + } + ); }); }; diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/TrustStore.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/TrustStore.js index 9b243ccb1f..f3fa06ccba 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/TrustStore.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/TrustStore.js @@ -29,16 +29,15 @@ define(["dojo/dom", "qpid/common/updater", "qpid/common/util", "qpid/common/formatter", - "qpid/management/addKeystore", + "qpid/management/addStore", "dojo/domReady!"], - function (dom, xhr, parser, query, connect, registry, entities, properties, updater, util, formatter, addKeystore) { + function (dom, xhr, parser, query, connect, registry, entities, properties, updater, util, formatter, addStore) { function TrustStore(name, parent, controller) { this.keyStoreName = name; this.controller = controller; this.modelObj = { type: "truststore", name: name, parent: parent}; this.url = "api/latest/truststore/" + encodeURIComponent(name); - this.dialog = addKeystore.showTruststoreDialog; } TrustStore.prototype.getTitle = function() { @@ -48,7 +47,7 @@ define(["dojo/dom", TrustStore.prototype.open = function(contentPane) { var that = this; this.contentPane = contentPane; - xhr.get({url: "showTrustStore.html", + xhr.get({url: "showStore.html", sync: true, load: function(data) { contentPane.containerNode.innerHTML = data; @@ -60,28 +59,27 @@ define(["dojo/dom", that.keyStoreUpdater.update(); - var deleteTrustStoreButton = query(".deleteTrustStoreButton", contentPane.containerNode)[0]; + var deleteTrustStoreButton = query(".deleteStoreButton", contentPane.containerNode)[0]; var node = registry.byNode(deleteTrustStoreButton); connect.connect(node, "onClick", function(evt){ that.deleteKeyStore(); }); - var editTrustStoreButton = query(".editTrustStoreButton", contentPane.containerNode)[0]; + var editTrustStoreButton = query(".editStoreButton", contentPane.containerNode)[0]; var node = registry.byNode(editTrustStoreButton); connect.connect(node, "onClick", function(evt){ xhr.get({url: that.url, sync: properties.useSyncGet, handleAs: "json", content: { actuals: true }}) .then(function(data) { - that.dialog(data[0], that.url); + addStore.setupTypeStore("TrustStore"); + addStore.show(data[0], that.url); }); }); }}); }; - - TrustStore.prototype.close = function() { updater.remove( this.keyStoreUpdater ); }; @@ -89,9 +87,10 @@ define(["dojo/dom", function KeyStoreUpdater(containerNode, keyStoreObj, controller, url) { var that = this; + this.keyStoreDetailsContainer = query(".typeFieldsContainer", containerNode)[0]; function findNode(name) { - return query("." + name + "Value", containerNode)[0]; + return query("." + name , containerNode)[0]; } function storeNodes(names) @@ -102,12 +101,8 @@ define(["dojo/dom", } storeNodes(["name", - "path", - "trustStoreType", - "trustStoreState", - "trustManagerFactoryAlgorithm", - "certificateAlias", - "peersOnly" + "type", + "state" ]); this.query = url; @@ -123,23 +118,26 @@ define(["dojo/dom", KeyStoreUpdater.prototype.updateHeader = function() { this.name.innerHTML = entities.encode(String(this.keyStoreData[ "name" ])); - this.path.innerHTML = entities.encode(String(this.keyStoreData[ "path" ])); - this.trustStoreType.innerHTML = entities.encode(String(this.keyStoreData[ "trustStoreType" ])); - this.trustStoreState.innerHTML = entities.encode(String(this.keyStoreData[ "state" ])); - this.trustManagerFactoryAlgorithm.innerHTML = entities.encode(String(this.keyStoreData[ "trustManagerFactoryAlgorithm" ])); - this.peersOnly.innerHTML = "<input type='checkbox' disabled='disabled' "+(this.keyStoreData[ "peersOnly" ] ? "checked='checked'": "")+" />" ; + this.type.innerHTML = entities.encode(String(this.keyStoreData[ "type" ])); + this.state.innerHTML = entities.encode(String(this.keyStoreData[ "state" ])); }; KeyStoreUpdater.prototype.update = function() { - - var thisObj = this; - + var that = this; xhr.get({url: this.query, sync: properties.useSyncGet, handleAs: "json"}).then(function(data) - { - thisObj.keyStoreData = data[0]; - thisObj.updateHeader(); - }); + { + that.trustStoreData = data[0]; + that.updateHeader(); + + require(["qpid/management/store/" + encodeURIComponent(that.trustStoreData.type.toLowerCase()) + "/show"], + function(DetailsUI) + { + that.details = new DetailsUI({containerNode:that.keyStoreDetailsContainer, parent: that}); + that.details.update(that.trustStoreData); + } + ); + }); }; TrustStore.prototype.deleteKeyStore = function() { diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js index cdc7890209..434e119736 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js @@ -93,6 +93,19 @@ define(["dojo/_base/xhr", that.stopButton = registry.byNode(query(".stopButton", containerNode)[0]); that.startButton = registry.byNode(query(".startButton", containerNode)[0]); that.editButton = registry.byNode(query(".editButton", containerNode)[0]); + that.downloadButton = registry.byNode(query(".downloadButton", containerNode)[0]); + that.downloadButton.on("click", + function(e) + { + var iframe = document.createElement('iframe'); + iframe.id = "downloader_" + that.name; + document.body.appendChild(iframe); + var suggestedAttachmentName = encodeURIComponent(that.name + ".json"); + iframe.src = "/api/latest/virtualhost/" + encodeURIComponent(that.modelObj.parent.name) + "/" + encodeURIComponent(that.name) + "?extractInitialConfig=true&contentDispositionAttachmentFilename=" + suggestedAttachmentName; + // It seems there is no way to remove this iframe in a manner that is cross browser compatible. + } + ); + that.deleteButton = registry.byNode(query(".deleteButton", containerNode)[0]); that.deleteButton.on("click", function(e) @@ -344,6 +357,7 @@ define(["dojo/_base/xhr", this.virtualHost.startButton.set("disabled", !this.vhostData.state || this.vhostData.state != "STOPPED"); this.virtualHost.stopButton.set("disabled", !this.vhostData.state || this.vhostData.state != "ACTIVE"); this.virtualHost.editButton.set("disabled", !this.vhostData.state || this.vhostData.state == "UNAVAILABLE"); + this.virtualHost.downloadButton.set("disabled", !this.vhostData.state || this.vhostData.state != "ACTIVE"); this.virtualHost.deleteButton.set("disabled", !this.vhostData.state); util.flattenStatistics( thisObj.vhostData ); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/accesscontrolprovider/aclfile/add.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/accesscontrolprovider/aclfile/add.js new file mode 100644 index 0000000000..e42dafb3c3 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/accesscontrolprovider/aclfile/add.js @@ -0,0 +1,122 @@ +/* + * + * 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/dom","dojo/query","dijit/registry","qpid/common/util"], + function (dom, query, registry, util) + { + var addACLFileAccessControlProvider = + { + init: function() + { + // Readers are HTML5 + this.reader = window.FileReader ? new FileReader() : undefined; + }, + show: function(data) + { + var that=this; + util.parseHtmlIntoDiv(data.containerNode, "accesscontrolprovider/aclfile/add.html"); + + this.aclServerPath = registry.byId("addAccessControlProvider.serverPath"); + this.aclUploadFields = dom.byId("addAccessControlProvider.uploadFields"); + this.aclSelectedFileContainer = dom.byId("addAccessControlProvider.selectedFile"); + this.aclSelectedFileStatusContainer = dom.byId("addAccessControlProvider.selectedFileStatus"); + this.aclFile = registry.byId("addAccessControlProvider.file"); + this.aclFileClearButton = registry.byId("addAccessControlProvider.fileClearButton"); + this.aclFileOldBrowserWarning = dom.byId("addAccessControlProvider.oldBrowserWarning"); + + //Only submitted field + this.aclPath = registry.byId("addAccessControlProvider.path"); + + this.addButton = data.parent.addButton; + + if (this.reader) + { + this.reader.onload = function(evt) {that._aclUploadFileComplete(evt);}; + this.reader.onerror = function(ex) {console.error("Failed to load ACL file", ex);}; + this.aclFile.on("change", function(selected){that._aclFileChanged(selected)}); + this.aclFileClearButton.on("click", function(event){that._aclFileClearButtonClicked(event)}); + } + else + { + // Fall back for IE8/9 which do not support FileReader + this.aclUploadFields.style.display = "none"; + this.aclFileOldBrowserWarning.innerHTML = "File upload requires a more recent browser with HTML5 support"; + this.aclFileOldBrowserWarning.className = this.aclFileOldBrowserWarning.className.replace("hidden", ""); + } + + this.aclServerPath.on("blur", function(){that._aclServerPathChanged()}); + }, + _aclFileChanged: function (evt) + { + // We only ever expect a single file + var file = this.aclFile.domNode.children[0].files[0]; + + this.addButton.setDisabled(true); + this.aclSelectedFileContainer.innerHTML = file.name; + this.aclSelectedFileStatusContainer.className = "loadingIcon"; + + console.log("Beginning to read ACL file " + file.name); + this.reader.readAsDataURL(file); + }, + _aclUploadFileComplete: function(evt) + { + var reader = evt.target; + var result = reader.result; + console.log("ACL file read complete, contents " + result); + this.addButton.setDisabled(false); + this.aclSelectedFileStatusContainer.className = "loadedIcon"; + + this.aclServerPath.set("value", ""); + this.aclServerPath.setDisabled(true); + this.aclServerPath.set("required", false); + + this.aclFileClearButton.setDisabled(false); + + this.aclPath.set("value", result); + }, + _aclFileClearButtonClicked: function(event) + { + this.aclFile.reset(); + this.aclSelectedFileStatusContainer.className = ""; + this.aclSelectedFileContainer.innerHTML = ""; + this.aclServerPath.set("required", true); + this.aclServerPath.setDisabled(false); + this.aclFileClearButton.setDisabled(true); + + this.aclPath.set("value", ""); + }, + _aclServerPathChanged: function() + { + var serverPathValue = this.aclServerPath.get("value"); + this.aclPath.set("value", serverPathValue); + } + }; + + try + { + addACLFileAccessControlProvider.init(); + } + catch(e) + { + console.warn(e); + } + return addACLFileAccessControlProvider; + } +); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAccessControlProvider.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAccessControlProvider.js index ac0493bfa5..38a6c8e841 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAccessControlProvider.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAccessControlProvider.js @@ -26,8 +26,10 @@ define(["dojo/_base/lang", "dojo/parser", "dojo/_base/array", "dojo/_base/event", - 'dojo/_base/json', + 'dojo/json', "qpid/common/util", + "qpid/common/metadata", + "dojo/text!addAccessControlProvider.html", "dojo/store/Memory", "dojox/validate/us", "dojox/validate/web", @@ -42,140 +44,124 @@ define(["dojo/_base/lang", "dijit/layout/ContentPane", "dojox/layout/TableContainer", "dojo/domReady!"], - function (lang, xhr, dom, construct, registry, parser, array, event, json, util) { - - var addAccessControlProvider = {}; - - addAccessControlProvider.show = function(accessControlProvider) { - var fields = [{ - name: "name", - createWidget: function(accessControlProvider) { - return new dijit.form.ValidationTextBox({ - required: true, - value: accessControlProvider.name, - disabled: accessControlProvider.name ? true : false, - label: "Name*:", - regexp: "^[\x20-\x2e\x30-\x7F]{1,255}$", - promptMessage: "Name of access control provider.", - placeHolder: "name", - name: "name"}); - } - }, { - name: "type", - createWidget: function(accessControlProvider) { - - var typeContainer = construct.create("div"); - - var typeListContainer = new dojox.layout.TableContainer({ - cols: 1, - "labelWidth": "300", - customClass: "formLabel", - showLabels: true, - orientation: "horiz" - }); - - typeContainer.appendChild(typeListContainer.domNode); - - var providers = []; - var fieldSetContainers = {}; - xhr.get({ - url: "service/helper?action=ListAccessControlProviderAttributes", - handleAs: "json", - sync: true - }).then( - function(data) { - var providerIndex = 0; - - for (var providerType in data) { - if (data.hasOwnProperty(providerType)) { - providers[providerIndex++] = {id: providerType, name: providerType}; - - var attributes = data[providerType].attributes; - var descriptions = data[providerType].descriptions; - - var layout = new dojox.layout.TableContainer( { - cols: 1, - "labelWidth": "300", - customClass: "formLabel", - showLabels: true, - orientation: "horiz" - }); - - for(var i=0; i < attributes.length; i++) { - if ("type" == attributes[i]) - { - continue; - } - var labelValue = attributes[i]; - if (descriptions && descriptions[attributes[i]]) - { - labelValue = descriptions[attributes[i]]; - } - var text = new dijit.form.TextBox({ - label: labelValue + ":", - name: attributes[i] - }); - layout.addChild(text); - } - - typeContainer.appendChild(layout.domNode); - fieldSetContainers[providerType] = layout; - } - } - }); - - var providersStore = new dojo.store.Memory({ data: providers }); - - var typeList = new dijit.form.FilteringSelect({ - required: true, - value: accessControlProvider.type, - store: providersStore, - label: "Type*:", - name: "type"}); - - typeListContainer.addChild(typeList); - - var onChangeHandler = function onChangeHandler(newValue){ - for (var i in fieldSetContainers) { - var container = fieldSetContainers[i]; - var descendants = container.getChildren(); - for(var i in descendants){ - var descendant = descendants[i]; - var propName = descendant.name; - if (propName) { - descendant.set("disabled", true); - } + function (lang, xhr, dom, construct, registry, parser, array, event, json, util, metadata, template) + { + + var addAccessControlProvider = + { + init: function() + { + var that=this; + this.containerNode = construct.create("div", {innerHTML: template}); + parser.parse(this.containerNode); + + this.accessControlProviderName = registry.byId("addAccessControlProvider.name"); + this.accessControlProviderName.set("regExpGen", util.nameOrContextVarRegexp); + + this.dialog = registry.byId("addAccessControlProvider"); + this.addButton = registry.byId("addAccessControlProvider.addButton"); + this.cancelButton = registry.byId("addAccessControlProvider.cancelButton"); + this.cancelButton.on("click", function(e){that._cancel(e);}); + this.addButton.on("click", function(e){that._add(e);}); + + this.accessControlProviderTypeFieldsContainer = dom.byId("addAccessControlProvider.typeFields"); + this.accessControlProviderForm = registry.byId("addAccessControlProvider.form"); + this.accessControlProviderType = registry.byId("addAccessControlProvider.type"); + this.supportedAccessControlProviderTypes = metadata.getTypesForCategory("AccessControlProvider"); + this.supportedAccessControlProviderTypes.sort(); + var accessControlProviderTypeStore = util.makeTypeStore(this.supportedAccessControlProviderTypes); + this.accessControlProviderType.set("store", accessControlProviderTypeStore); + this.accessControlProviderType.on("change", function(type){that._accessControlProviderTypeChanged(type);}); + }, + show: function(effectiveData) + { + this.accessControlProviderForm.reset(); + this.dialog.show(); + }, + _cancel: function(e) + { + event.stop(e); + if (this.reader) + { + this.reader.abort(); + } + this.dialog.hide(); + }, + _add: function(e) + { + event.stop(e); + this._submit(); + }, + _submit: function() + { + if (this.accessControlProviderForm.validate()) + { + var success = false,failureReason=null; + + var accessControlProviderData = util.getFormWidgetValues(this.accessControlProviderForm, this.initialData); + var encodedAccessControlProviderName = encodeURIComponent(this.accessControlProviderName.value); + + xhr.put( + { + url: "api/latest/accesscontrolprovider/" + encodedAccessControlProviderName, + sync: true, + handleAs: "json", + headers: { "Content-Type": "application/json"}, + putData: json.stringify(accessControlProviderData), + load: function(x) {success = true; }, + error: function(error) {success = false; failureReason = error;} + }); + + if (success == true) + { + this.dialog.hide(); } - container.domNode.style.display = "none"; - } - var container = fieldSetContainers[newValue]; - if (container) - { - container.domNode.style.display = "block"; - var descendants = container.getChildren(); - for(var i in descendants){ - var descendant = descendants[i]; - var propName = descendant.name; - if (propName) { - descendant.set("disabled", false); - } + else + { + util.xhrErrorHandler(failureReason); } - } - }; - typeList.on("change", onChangeHandler); - onChangeHandler(typeList.value); - return new dijit.layout.ContentPane({content: typeContainer, style:{padding: 0}}); - } - }]; - - util.showSetAttributesDialog( - fields, - accessControlProvider ? accessControlProvider : {}, - "api/latest/accesscontrolprovider" + (name ? "/" + encodeURIComponent(name.name) : ""), - accessControlProvider ? "Edit access control provider - " + accessControlProvider.name : "Add access control provider", - "AccessControlProvider", - accessControlProvider && accessControlProvider.type ? accessControlProvider.type : "AclFile", - accessControlProvider ? false : true); + } + else + { + alert('Form contains invalid data. Please correct first'); + } + }, + _accessControlProviderTypeChanged: function(type) + { + this._typeChanged(type, this.accessControlProviderTypeFieldsContainer, "qpid/management/accesscontrolprovider/", "AccessControlProvider" ); + }, + _typeChanged: function(type, typeFieldsContainer, baseUrl, category ) + { + var widgets = registry.findWidgets(typeFieldsContainer); + array.forEach(widgets, function(item) { item.destroyRecursive();}); + construct.empty(typeFieldsContainer); + + if (type) + { + var that = this; + require([ baseUrl + type.toLowerCase() + "/add"], function(typeUI) + { + try + { + typeUI.show({containerNode:typeFieldsContainer, parent: that, data: that.initialData, effectiveData: that.effectiveData}); + util.applyMetadataToWidgets(typeFieldsContainer, category, type); + } + catch(e) + { + console.warn(e); + } + }); + } + } }; + + try + { + addAccessControlProvider.init(); + } + catch(e) + { + console.warn(e); + } return addAccessControlProvider; - });
\ No newline at end of file + }); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addKeystore.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addKeystore.js deleted file mode 100644 index e7e79e742d..0000000000 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addKeystore.js +++ /dev/null @@ -1,181 +0,0 @@ -/* - * - * 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/lang", - "dojo/_base/xhr", - "dojo/dom", - "dojo/dom-construct", - "dijit/registry", - "dojo/parser", - "dojo/_base/array", - "dojo/_base/event", - 'dojo/_base/json', - "qpid/common/util", - "dojo/store/Memory", - "dojox/validate/us", - "dojox/validate/web", - "dijit/Dialog", - "dijit/form/CheckBox", - "dijit/form/Textarea", - "dijit/form/ComboBox", - "dijit/form/TextBox", - "dijit/form/ValidationTextBox", - "dijit/form/Button", - "dijit/form/Form", - "dijit/TitlePane", - "dojox/layout/TableContainer", - "dojo/domReady!"], - function (lang, xhr, dom, construct, registry, parser, array, event, json, util) { - - var addKeystore = { }; - - addKeystore.createWidgetFactories = function(isKeystore) - { - var fields = [{ - name: "name", - createWidget: function(keystore) { - return new dijit.form.ValidationTextBox({ - required: true, - value: keystore.name, - disabled: keystore.name ? true : false, - label: "Name:", - regExpGen: util.nameOrContextVarRegexp, - promptMessage: "Name of keystore. Used to refer to the keystore from other objects within the Broker.", - placeHolder: "name", - name: "name"}); - } - }, { - name: "path", - createWidget: function(keystore) { - return new dijit.form.ValidationTextBox({ - required: true, - value: keystore.path, - label: "Path to keystore:", - promptMessage: "File system location to the keystore file", - placeHolder: "path/to/keystore", - name: "path"}); - } - }, { - name: "password", - requiredFor: "path", - createWidget: function(keystore) { - return new dijit.form.ValidationTextBox({ - required: false, - label: "Keystore password:", - promptMessage: "Password used to open the keystore", - name: "password", - placeHolder: keystore["password"] ? keystore["password"] : "" - }); - } - }]; - if (!isKeystore) - { - fields.push({ - name: "peersOnly", - createWidget: function(keystore) { - return new dijit.form.CheckBox({ - required: false, - checked: keystore && keystore.peersOnly, - label: "Peers only:", - name: "peersOnly"}); - } - }); - } - fields.push({ - name: "Options", - - createWidget: function(keystore) { - var optionalFieldContainer = new dojox.layout.TableContainer({ - cols: 1, - "labelWidth": "300", - showLabels: true, - orientation: "horiz", - customClass: "formLabel" - }); - if (isKeystore) - { - optionalFieldContainer.addChild(new dijit.form.ValidationTextBox({ - required: false, - value: keystore.certificateAlias, - label: "Keystore certificate alias:", - name: "certificateAlias", - placeHolder: "alias", - promptMessage: "Used to identify one certificate in a store that has many"})); - - optionalFieldContainer.addChild( new dijit.form.ValidationTextBox({ - required: false, - value: keystore.keyManagerFactoryAlgorithm, - label: "Key manager factory algorithm:", - placeHolder: "algorithm name", - promptMessage: "Name of the key manager algorithm known to Java", - name: "keyManagerFactoryAlgorithm"})); - } - else - { - optionalFieldContainer.addChild( new dijit.form.ValidationTextBox({ - required: false, - value: keystore.trustManagerFactoryAlgorithm, - label: "Trust manager factory algorithm:", - placeHolder: "algorithm name", - promptMessage: "Name of the trust manager algorithm known to Java", - name: "trustManagerFactoryAlgorithm"})); - } - optionalFieldContainer.addChild(new dijit.form.ValidationTextBox({ - required: false, - value: isKeystore ? keystore.keyStoreType : keystore.trustStoreType, - label: "Key store type:", - placeHolder: "store type", - promptMessage: "Name of the store type known to Java", - name: isKeystore ? "keyStoreType" : "trustStoreType"})); - - var panel = new dijit.TitlePane({title: "Optional Attributes", content: optionalFieldContainer.domNode, open: false}); - - return panel; - } - }); - return fields; - } - - addKeystore.showKeystoreDialog = function(keystore, putURL) { - var keystoreAttributeWidgetFactories = addKeystore.createWidgetFactories(true); - - util.showSetAttributesDialog( - keystoreAttributeWidgetFactories, - keystore ? keystore : {}, - keystore ? putURL : "api/latest/keystore", - keystore ? "Edit keystore - " + keystore.name : "Add keystore", - "KeyStore", - keystore && keystore.type ? keystore.type : "FileKeyStore", // GET?actuals=true doesn't get type for objects of the default type for the category - keystore ? false : true); - }; - - addKeystore.showTruststoreDialog = function(truststore, putURL) { - var truststoreAttributeWidgetFactories = addKeystore.createWidgetFactories(false); - util.showSetAttributesDialog( - truststoreAttributeWidgetFactories, - truststore ? truststore : {}, - truststore ? putURL : "api/latest/truststore", - truststore ? "Edit truststore - " + truststore.name : "Add truststore", - "TrustStore", - truststore && truststore.type ? truststore.type : "FileTrustStore", - truststore ? false : true); - }; - return addKeystore; - });
\ No newline at end of file diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addStore.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addStore.js new file mode 100644 index 0000000000..98068f2376 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addStore.js @@ -0,0 +1,211 @@ +/* + * + * 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/lang", + "dojo/_base/xhr", + "dojo/dom", + "dojo/dom-construct", + "dijit/registry", + "dojo/parser", + "dojo/store/Memory", + "dojo/_base/array", + "dojo/_base/event", + 'dojo/json', + "qpid/common/util", + "qpid/common/metadata", + "dojo/text!addStore.html", + "dojo/store/Memory", + "dojox/validate/us", + "dojox/validate/web", + "dijit/Dialog", + "dijit/form/CheckBox", + "dijit/form/Textarea", + "dijit/form/ComboBox", + "dijit/form/TextBox", + "dijit/form/ValidationTextBox", + "dijit/form/Button", + "dijit/form/Form", + "dijit/layout/ContentPane", + "dojox/layout/TableContainer", + "dojo/domReady!"], + function (lang, xhr, dom, construct, registry, parser, memory, array, event, json, util, metadata, template) + { + var addStore = + { + init: function() + { + var that=this; + this.containerNode = construct.create("div", {innerHTML: template}); + parser.parse(this.containerNode); + + this.storeName = registry.byId("addStore.name"); + this.storeName.set("regExpGen", util.nameOrContextVarRegexp); + + this.dialog = registry.byId("addStore"); + this.addButton = registry.byId("addStore.addButton"); + this.cancelButton = registry.byId("addStore.cancelButton"); + this.cancelButton.on("click", function(e){that._cancel(e);}); + this.addButton.on("click", function(e){that._add(e);}); + + this.storeTypeFieldsContainer = dom.byId("addStore.typeFields"); + this.storeForm = registry.byId("addStore.form"); + + this.storeType = registry.byId("addStore.type"); + this.storeType.on("change", function(type){that._storeTypeChanged(type);}); + }, + setupTypeStore: function(category) + { + this.category = category; + var storeTypeSupportedTypes = metadata.getTypesForCategory(category); + storeTypeSupportedTypes.sort(); + var storeTypeStore = util.makeTypeStore(storeTypeSupportedTypes); + this.storeType.set("store", storeTypeStore); + }, + show: function(effectiveData) + { + this.storeForm.reset(); + + if (effectiveData) + { + this.effectiveData = effectiveData; + this._destroyTypeFields(this.containerNode); + this._initFields(effectiveData); + } + this.storeName.set("disabled", effectiveData == null ? false : true); + this.storeType.set("disabled", effectiveData == null ? false : true); + this.dialog.show(); + }, + _initFields:function(data) + { + var type = data["type"]; + var attributes = metadata.getMetaData(this.category, type).attributes; + for(var name in attributes) + { + var widget = registry.byId("addStore."+name); + if (widget) + { + widget.set("value", data[name]); + } + } + }, + _cancel: function(e) + { + event.stop(e); + if (this.reader) + { + this.reader.abort(); + } + this.dialog.hide(); + }, + _add: function(e) + { + event.stop(e); + this._submit(); + }, + _submit: function() + { + if (this.storeForm.validate()) + { + var success = false,failureReason=null; + + var storeData = util.getFormWidgetValues(this.storeForm, this.initialData); + var encodedStoreName = encodeURIComponent(this.storeName.value); + var encodedCategory = encodeURIComponent(this.category.toLowerCase()); + var jsonString = json.stringify(storeData); + + try { + xhr.put( + { + url: "api/latest/" + encodedCategory + "/" + encodedStoreName, + sync: true, + handleAs: "json", + headers: { "Content-Type": "application/json"}, + putData: jsonString, + load: function(x) {success = true; }, + error: function(error) {success = false; failureReason = error;} + }); + } + catch (e) + { + console.warn(e); + } + + if (success == true) + { + this.dialog.hide(); + } + else + { + util.xhrErrorHandler(failureReason); + } + } + else + { + alert('Form contains invalid data. Please correct first'); + } + }, + _storeTypeChanged: function(type) + { + this._typeChanged(type, this.storeTypeFieldsContainer, "qpid/management/store/", this.category ); + }, + _destroyTypeFields: function(typeFieldsContainer) + { + var widgets = registry.findWidgets(typeFieldsContainer); + array.forEach(widgets, function(item) { item.destroyRecursive();}); + construct.empty(typeFieldsContainer); + }, + _typeChanged: function(type, typeFieldsContainer, baseUrl, category ) + { + this._destroyTypeFields(typeFieldsContainer); + + if (type) + { + var that = this; + require([ baseUrl + type.toLowerCase() + "/add"], function(typeUI) + { + try + { + typeUI.show({containerNode:typeFieldsContainer, parent: that, data: that.initialData, effectiveData: that.effectiveData}); + util.applyMetadataToWidgets(typeFieldsContainer, category, type); + if (that.effectiveData) + { + typeUI.update(that.effectiveData); + that.effectiveData = undefined; + } + } + catch(e) + { + console.warn(e); + } + }); + } + } + }; + + try + { + addStore.init(); + } + catch(e) + { + console.warn(e); + } + return addStore; + }); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addVirtualHostNodeAndVirtualHost.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addVirtualHostNodeAndVirtualHost.js index 0a18a8909b..f379361a09 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addVirtualHostNodeAndVirtualHost.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addVirtualHostNodeAndVirtualHost.js @@ -44,6 +44,7 @@ define(["dojo/_base/xhr", "dijit/form/Form", "dijit/form/CheckBox", "dijit/form/RadioButton", + "dojox/form/Uploader", "dojox/validate/us", "dojox/validate/web", "dojo/domReady!"], @@ -61,6 +62,9 @@ define(["dojo/_base/xhr", var virtualHostNodeName = registry.byId("addVirtualHostNode.nodeName"); virtualHostNodeName.set("regExpGen", util.nameOrContextVarRegexp); + // Readers are HTML5 + this.reader = window.FileReader ? new FileReader() : undefined; + this.dialog = registry.byId("addVirtualHostNodeAndVirtualHost"); this.addButton = registry.byId("addVirtualHostNodeAndVirtualHost.addButton"); this.cancelButton = registry.byId("addVirtualHostNodeAndVirtualHost.cancelButton"); @@ -68,34 +72,51 @@ define(["dojo/_base/xhr", this.addButton.on("click", function(e){that._add(e);}); this.virtualHostNodeTypeFieldsContainer = dom.byId("addVirtualHostNode.typeFields"); + this.virtualHostNodeSelectedFileContainer = dom.byId("addVirtualHostNode.selectedFile"); + this.virtualHostNodeSelectedFileStatusContainer = dom.byId("addVirtualHostNode.selectedFileStatus"); + this.virtualHostNodeUploadFields = dom.byId("addVirtualHostNode.uploadFields"); + this.virtualHostNodeFileFields = dom.byId("addVirtualHostNode.fileFields"); + this.virtualHostNodeForm = registry.byId("addVirtualHostNode.form"); this.virtualHostNodeType = registry.byId("addVirtualHostNode.type"); + this.virtualHostNodeFileCheck = registry.byId("addVirtualHostNode.upload"); + this.virtualHostNodeFile = registry.byId("addVirtualHostNode.file"); + this.virtualHostNodeType.set("disabled", true); this.virtualHostTypeFieldsContainer = dom.byId("addVirtualHost.typeFields"); this.virtualHostForm = registry.byId("addVirtualHost.form"); this.virtualHostType = registry.byId("addVirtualHost.type"); - this.virtualHostType.set("disabled", true); - this.supportedVirtualHostNodeTypes = metadata.getTypesForCategory("VirtualHostNode"); - this.supportedVirtualHostNodeTypes.sort(); - this.supportedVirtualHostTypes = metadata.getTypesForCategory("VirtualHost"); - this.supportedVirtualHostTypes.sort(); + this.virtualHostType.set("disabled", true); - //VH Type BDB_HA_REPLICA is not user creatable. This is only needed until we have model meta data available. - this.supportedVirtualHostTypes = array.filter(this.supportedVirtualHostTypes, function(item){ - return item != "BDB_HA_REPLICA" && item != "BDB_HA"; - }); + var supportedVirtualHostNodeTypes = metadata.getTypesForCategory("VirtualHostNode"); + supportedVirtualHostNodeTypes.sort(); - var virtualHostNodeTypeStore = util.makeTypeStore(this.supportedVirtualHostNodeTypes); + var virtualHostNodeTypeStore = util.makeTypeStore(supportedVirtualHostNodeTypes); this.virtualHostNodeType.set("store", virtualHostNodeTypeStore); this.virtualHostNodeType.set("disabled", false); this.virtualHostNodeType.on("change", function(type){that._vhnTypeChanged(type, that.virtualHostNodeTypeFieldsContainer, "qpid/management/virtualhostnode/");}); - this.virtualHostTypeStore = util.makeTypeStore(this.supportedVirtualHostTypes); - this.virtualHostType.set("store", this.virtualHostTypeStore); - this.virtualHostType.set("disabled", false); + this.virtualHostType.set("disabled", true); this.virtualHostType.on("change", function(type){that._vhTypeChanged(type, that.virtualHostTypeFieldsContainer, "qpid/management/virtualhost/");}); + + if (this.reader) + { + this.reader.onload = function(evt) {that._vhnUploadFileComplete(evt);}; + this.reader.onerror = function(ex) {console.error("Failed to load JSON file", ex);}; + this.virtualHostNodeFile.on("change", function(selected){that._vhnFileChanged(selected)}); + this.virtualHostNodeFileCheck.on("change", function(selected){that._vhnFileFlagChanged(selected)}); + } + else + { + // Fall back for IE8/9 which do not support FileReader + this.virtualHostNodeFileCheck.set("disabled", "disabled"); + this.virtualHostNodeFileCheck.set("title", "Requires a more recent browser with HTML5 support"); + this.virtualHostNodeFileFields.style.display = "none"; + } + + this.virtualHostNodeUploadFields.style.display = "none"; }, show: function() { @@ -161,8 +182,29 @@ define(["dojo/_base/xhr", }, _vhnTypeChanged: function (type, typeFieldsContainer, urlStem) { - this._processDropDownsForBdbHa(type); - this._processDropDownsForJson(type); + var validChildTypes = metadata.validChildTypes("VirtualHostNode", type, "VirtualHost"); + validChildTypes.sort(); + + var virtualHostTypeStore = util.makeTypeStore( validChildTypes ); + + this.virtualHostType.set("store", virtualHostTypeStore); + this.virtualHostType.set("disabled", validChildTypes.length <= 1); + if (validChildTypes.length == 1) + { + this.virtualHostType.set("value", validChildTypes[0]); + } + else + { + this.virtualHostType.reset(); + } + + var vhnTypeSelected = !(type == ''); + this.virtualHostNodeUploadFields.style.display = vhnTypeSelected ? "block" : "none"; + + if (!vhnTypeSelected) + { + this._vhnFileFlagChanged(false); + } this._typeChanged(type, typeFieldsContainer, urlStem, "VirtualHostNode"); }, @@ -203,52 +245,43 @@ define(["dojo/_base/xhr", ); } }, - _processDropDownsForBdbHa: function (type) + _vhnFileFlagChanged: function (selected) { - if (type == "BDB_HA") - { - this.virtualHostType.set("disabled", true); - if (!this.virtualHostTypeStore.get("BDB_HA")) - { - this.virtualHostTypeStore.add({id: "BDB_HA", name: "BDB_HA"}); - } - this.virtualHostType.set("value", "BDB_HA"); - } - else - { - if (this.virtualHostTypeStore.get("BDB_HA")) - { - this.virtualHostTypeStore.remove("BDB_HA"); - } - this.virtualHostType.set("value", ""); - - this.virtualHostType.set("disabled", false); - } + this.virtualHostForm.domNode.style.display = selected ? "none" : "block"; + this.virtualHostNodeFileFields.style.display = selected ? "block" : "none"; + this.virtualHostType.set("required", !selected); + this.virtualHostNodeFile.reset(); + this.virtualHostInitialConfiguration = undefined; + this.virtualHostNodeSelectedFileContainer.innerHTML = ""; + this.virtualHostNodeSelectedFileStatusContainer.className = ""; }, - _processDropDownsForJson: function (type) + _vhnFileChanged: function (evt) { - if (type == "JSON") - { - if (this.virtualHostType.value == "ProvidedStore") - { - this.virtualHostType.set("value", ""); - } + // We only ever expect a single file + var file = this.virtualHostNodeFile.domNode.children[0].files[0]; - if (this.virtualHostTypeStore.get("ProvidedStore")) - { - this.virtualHostTypeStore.remove("ProvidedStore"); - } - } - else - { - if (!this.virtualHostTypeStore.get("ProvidedStore")) - { - this.virtualHostTypeStore.add({id: "ProvidedStore", name: "ProvidedStore"}); - } - } + this.addButton.set("disabled", true); + this.virtualHostNodeSelectedFileContainer.innerHTML = file.name; + this.virtualHostNodeSelectedFileStatusContainer.className = "loadingIcon"; + + console.log("Beginning to read file " + file.name); + this.reader.readAsDataURL(file); + }, + _vhnUploadFileComplete: function(evt) + { + var reader = evt.target; + var result = reader.result; + console.log("File read complete, contents " + result); + this.virtualHostInitialConfiguration = result; + this.addButton.set("disabled", false); + this.virtualHostNodeSelectedFileStatusContainer.className = "loadedIcon"; }, _cancel: function(e) { + if (this.reader) + { + this.reader.abort(); + } this.dialog.hide(); }, _add: function(e) @@ -258,16 +291,32 @@ define(["dojo/_base/xhr", }, _submit: function() { - if(this.virtualHostNodeForm.validate() && this.virtualHostForm.validate()) + + var uploadVHConfig = this.virtualHostNodeFileCheck.get("checked"); + var virtualHostNodeData = undefined; + + if (uploadVHConfig && this.virtualHostNodeFile.getFileList().length > 0 && this.virtualHostNodeForm.validate()) { - var success = false,failureReason=null; + // VH config is being uploaded + virtualHostNodeData = this._getValues(this.virtualHostNodeForm); + var virtualHostNodeContext = this.virtualHostNodeContext.get("value"); + if (virtualHostNodeContext) + { + virtualHostNodeData["context"] = virtualHostNodeContext; + } - var virtualHostNodeData = this._getValues(this.virtualHostNodeForm); + // Add the loaded virtualhost configuration + virtualHostNodeData["virtualHostInitialConfiguration"] = this.virtualHostInitialConfiguration; + } + else if (!uploadVHConfig && this.virtualHostNodeForm.validate() && this.virtualHostForm.validate()) + { + virtualHostNodeData = this._getValues(this.virtualHostNodeForm); var virtualHostNodeContext = this.virtualHostNodeContext.get("value"); if (virtualHostNodeContext) { virtualHostNodeData["context"] = virtualHostNodeContext; } + var virtualHostData = this._getValues(this.virtualHostForm); var virtualHostContext = this.virtualHostContext.get("value"); if (virtualHostContext) @@ -278,48 +327,35 @@ define(["dojo/_base/xhr", //Default the VH name to be the same as the VHN name. virtualHostData["name"] = virtualHostNodeData["name"]; - var encodedVirtualHostNodeName = encodeURIComponent(virtualHostNodeData.name); - xhr.put({ - url: "api/latest/virtualhostnode/" + encodedVirtualHostNodeName, - sync: true, - handleAs: "json", - headers: { "Content-Type": "application/json"}, - putData: json.stringify(virtualHostNodeData), - load: function(x) {success = true; }, - error: function(error) {success = false; failureReason = error;} - }); - - if(success === true && virtualHostNodeData["type"] != "BDB_HA") - { - var encodedVirtualHostName = encodeURIComponent(virtualHostData.name); - xhr.put({ - url: "api/latest/virtualhost/" + encodedVirtualHostNodeName + "/" + encodedVirtualHostName, - sync: true, - handleAs: "json", - headers: { "Content-Type": "application/json"}, - putData: json.stringify(virtualHostData), - load: function (x) { - success = true; - }, - error: function (error) { - success = false; - failureReason = error; - } - }); - } + virtualHostNodeData["virtualHostInitialConfiguration"] = json.stringify(virtualHostData) - if (success == true) - { - this.dialog.hide(); - } - else - { - util.xhrErrorHandler(failureReason); - } } else { - alert('Form contains invalid data. Please correct first'); + alert('Form contains invalid data. Please correct first'); + return; + } + + var success = false,failureReason=null; + + var encodedVirtualHostNodeName = encodeURIComponent(virtualHostNodeData.name); + xhr.put({ + url: "api/latest/virtualhostnode/" + encodedVirtualHostNodeName, + sync: true, + handleAs: "json", + headers: { "Content-Type": "application/json"}, + putData: json.stringify(virtualHostNodeData), + load: function(x) {success = true; }, + error: function(error) {success = false; failureReason = error;} + }); + + if (success == true) + { + this.dialog.hide(); + } + else + { + util.xhrErrorHandler(failureReason); } }, _getValues: function (form) diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/filekeystore/add.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/filekeystore/add.js new file mode 100644 index 0000000000..b158b9e051 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/filekeystore/add.js @@ -0,0 +1,152 @@ +/* + * + * 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/dom","dojo/query", "dojo/_base/array", "dijit/registry","qpid/common/util", "qpid/common/metadata"], + function (dom, query, array, registry, util, metadata) + { + var addKeyStore = + { + init: function() + { + // Readers are HTML5 + this.reader = window.FileReader ? new FileReader() : undefined; + }, + show: function(data) + { + var that=this; + util.parseHtmlIntoDiv(data.containerNode, "store/filekeystore/add.html"); + + this.containerNode = data.containerNode; + this.keyStoreServerPath = registry.byId("addStore.serverPath"); + this.keyStoreUploadFields = dom.byId("addStore.uploadFields"); + this.keyStoreSelectedFileContainer = dom.byId("addStore.selectedFile"); + this.keyStoreSelectedFileStatusContainer = dom.byId("addStore.selectedFileStatus"); + this.keyStoreFile = registry.byId("addStore.file"); + this.keyStoreFileClearButton = registry.byId("addStore.fileClearButton"); + this.keyStoreOldBrowserWarning = dom.byId("addStore.oldBrowserWarning"); + + //Only submitted field + this.keyStorePath = registry.byId("addStore.path"); + + this.addButton = data.parent.addButton; + + if (this.reader) + { + this.reader.onload = function(evt) {that._keyStoreUploadFileComplete(evt);}; + this.reader.onerror = function(ex) {console.error("Failed to load key store file", ex);}; + this.keyStoreFile.on("change", function(selected){that._keyStoreFileChanged(selected)}); + this.keyStoreFileClearButton.on("click", function(event){that._keyStoreFileClearButtonClicked(event)}); + } + else + { + // Fall back for IE8/9 which do not support FileReader + this.keyStoreUploadFields.style.display = "none"; + this.keyStoreOldBrowserWarning.innerHTML = "File upload requires a more recent browser with HTML5 support"; + this.keyStoreOldBrowserWarning.className = this.keyStoreOldBrowserWarning.className.replace("hidden", ""); + } + + this.keyStoreServerPath.on("blur", function(){that._keyStoreServerPathChanged()}); + }, + _keyStoreFileChanged: function (evt) + { + // We only ever expect a single file + var file = this.keyStoreFile.domNode.children[0].files[0]; + + this.addButton.setDisabled(true); + this.keyStoreSelectedFileContainer.innerHTML = file.name; + this.keyStoreSelectedFileStatusContainer.className = "loadingIcon"; + + console.log("Beginning to read key store file " + file.name); + this.reader.readAsDataURL(file); + }, + _keyStoreUploadFileComplete: function(evt) + { + var reader = evt.target; + var result = reader.result; + console.log("Key store file read complete, contents " + result); + this.addButton.setDisabled(false); + this.keyStoreSelectedFileStatusContainer.className = "loadedIcon"; + + this.keyStoreServerPath.set("value", ""); + this.keyStoreServerPath.setDisabled(true); + this.keyStoreServerPath.set("required", false); + + this.keyStoreFileClearButton.setDisabled(false); + + this.keyStorePath.set("value", result); + }, + _keyStoreFileClearButtonClicked: function(event) + { + this.keyStoreFile.reset(); + this.keyStoreSelectedFileStatusContainer.className = ""; + this.keyStoreSelectedFileContainer.innerHTML = ""; + this.keyStoreServerPath.set("required", true); + this.keyStoreServerPath.setDisabled(false); + this.keyStoreFileClearButton.setDisabled(true); + + this.keyStorePath.set("value", ""); + }, + _keyStoreServerPathChanged: function() + { + var serverPathValue = this.keyStoreServerPath.get("value"); + this.keyStorePath.set("value", serverPathValue); + }, + update: function(effectiveData) + { + var attributes = metadata.getMetaData("KeyStore", "FileKeyStore").attributes; + var widgets = registry.findWidgets(this.containerNode); + array.forEach(widgets, function(item) + { + var name = item.id.replace("addStore.",""); + if (name in attributes && item.type != "password") + { + item.set("value", effectiveData[name]); + } + }); + + var keyStorePathValue = effectiveData["path"]; + var isDataUrl = keyStorePathValue.indexOf("data:") == 0; + + if (isDataUrl) + { + this.keyStoreSelectedFileStatusContainer.className = "loadedIcon"; + this.keyStoreSelectedFileContainer.innerHTML = "uploaded.jks"; + this.keyStoreServerPath.setDisabled(true); + this.keyStoreServerPath.set("required", false); + this.keyStoreFileClearButton.setDisabled(false); + } + else + { + this.keyStoreServerPath.set("value", keyStorePathValue); + } + } + }; + + try + { + addKeyStore.init(); + } + catch(e) + { + console.warn(e); + } + return addKeyStore; + } +); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/filekeystore/show.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/filekeystore/show.js new file mode 100644 index 0000000000..fbe2bbc9c2 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/filekeystore/show.js @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +define(["qpid/common/util", "qpid/common/metadata", "dojo/domReady!"], + function (util, metadata) + { + + function FileKeyStoreProvider(data) + { + this.fields = []; + var attributes = metadata.getMetaData("KeyStore", "FileKeyStore").attributes; + for(var name in attributes) + { + this.fields.push(name); + } + util.buildUI(data.containerNode, data.parent, "store/filekeystore/show.html", this.fields, this); + } + + FileKeyStoreProvider.prototype.update = function(data) + { + util.updateUI(data, this.fields, this); + } + + return FileKeyStoreProvider; + } +); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/filetruststore/add.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/filetruststore/add.js new file mode 100644 index 0000000000..9d113a9d9e --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/filetruststore/add.js @@ -0,0 +1,152 @@ +/* + * + * 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/dom","dojo/query", "dojo/_base/array", "dijit/registry","qpid/common/util", "qpid/common/metadata"], + function (dom, query, array, registry, util, metadata) + { + var addTrustStore = + { + init: function() + { + // Readers are HTML5 + this.reader = window.FileReader ? new FileReader() : undefined; + }, + show: function(data) + { + var that=this; + util.parseHtmlIntoDiv(data.containerNode, "store/filetruststore/add.html"); + + this.containerNode = data.containerNode; + this.keyStoreServerPath = registry.byId("addStore.serverPath"); + this.keyStoreUploadFields = dom.byId("addStore.uploadFields"); + this.keyStoreSelectedFileContainer = dom.byId("addStore.selectedFile"); + this.keyStoreSelectedFileStatusContainer = dom.byId("addStore.selectedFileStatus"); + this.keyStoreFile = registry.byId("addStore.file"); + this.keyStoreFileClearButton = registry.byId("addStore.fileClearButton"); + this.keyStoreOldBrowserWarning = dom.byId("addStore.oldBrowserWarning"); + + //Only submitted field + this.keyStorePath = registry.byId("addStore.path"); + + this.addButton = data.parent.addButton; + + if (this.reader) + { + this.reader.onload = function(evt) {that._keyStoreUploadFileComplete(evt);}; + this.reader.onerror = function(ex) {console.error("Failed to load trust store file", ex);}; + this.keyStoreFile.on("change", function(selected){that._keyStoreFileChanged(selected)}); + this.keyStoreFileClearButton.on("click", function(event){that._keyStoreFileClearButtonClicked(event)}); + } + else + { + // Fall back for IE8/9 which do not support FileReader + this.keyStoreUploadFields.style.display = "none"; + this.keyStoreOldBrowserWarning.innerHTML = "File upload requires a more recent browser with HTML5 support"; + this.keyStoreOldBrowserWarning.className = this.keyStoreOldBrowserWarning.className.replace("hidden", ""); + } + + this.keyStoreServerPath.on("blur", function(){that._keyStoreServerPathChanged()}); + }, + _keyStoreFileChanged: function (evt) + { + // We only ever expect a single file + var file = this.keyStoreFile.domNode.children[0].files[0]; + + this.addButton.setDisabled(true); + this.keyStoreSelectedFileContainer.innerHTML = file.name; + this.keyStoreSelectedFileStatusContainer.className = "loadingIcon"; + + console.log("Beginning to read trust store file " + file.name); + this.reader.readAsDataURL(file); + }, + _keyStoreUploadFileComplete: function(evt) + { + var reader = evt.target; + var result = reader.result; + console.log("Trust store file read complete, contents " + result); + this.addButton.setDisabled(false); + this.keyStoreSelectedFileStatusContainer.className = "loadedIcon"; + + this.keyStoreServerPath.set("value", ""); + this.keyStoreServerPath.setDisabled(true); + this.keyStoreServerPath.set("required", false); + + this.keyStoreFileClearButton.setDisabled(false); + + this.keyStorePath.set("value", result); + }, + _keyStoreFileClearButtonClicked: function(event) + { + this.keyStoreFile.reset(); + this.keyStoreSelectedFileStatusContainer.className = ""; + this.keyStoreSelectedFileContainer.innerHTML = ""; + this.keyStoreServerPath.set("required", true); + this.keyStoreServerPath.setDisabled(false); + this.keyStoreFileClearButton.setDisabled(true); + + this.keyStorePath.set("value", ""); + }, + _keyStoreServerPathChanged: function() + { + var serverPathValue = this.keyStoreServerPath.get("value"); + this.keyStorePath.set("value", serverPathValue); + }, + update: function(effectiveData) + { + var attributes = metadata.getMetaData("TrustStore", "FileTrustStore").attributes; + var widgets = registry.findWidgets(this.containerNode); + array.forEach(widgets, function(item) + { + var name = item.id.replace("addStore.",""); + if (name in attributes && item.type != "password") + { + item.set("value", effectiveData[name]); + } + }); + + var keyStorePathValue = effectiveData["path"]; + var isDataUrl = keyStorePathValue.indexOf("data:") == 0; + + if (isDataUrl) + { + this.keyStoreSelectedFileStatusContainer.className = "loadedIcon"; + this.keyStoreSelectedFileContainer.innerHTML = "uploaded.jks"; + this.keyStoreServerPath.setDisabled(true); + this.keyStoreServerPath.set("required", false); + this.keyStoreFileClearButton.setDisabled(false); + } + else + { + this.keyStoreServerPath.set("value", keyStorePathValue); + } + } + }; + + try + { + addTrustStore.init(); + } + catch(e) + { + console.warn(e); + } + return addTrustStore; + } +); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/filetruststore/show.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/filetruststore/show.js new file mode 100644 index 0000000000..b03199021d --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/filetruststore/show.js @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +define(["qpid/common/util", "qpid/common/metadata", "dojo/domReady!"], + function (util, metadata) + { + + function FileTrustStoreProvider(data) + { + this.fields = []; + var attributes = metadata.getMetaData("TrustStore", "FileTrustStore").attributes; + for(var name in attributes) + { + this.fields.push(name); + } + util.buildUI(data.containerNode, data.parent, "store/filetruststore/show.html", this.fields, this); + } + + FileTrustStoreProvider.prototype.update = function(data) + { + util.updateUI(data, this.fields, this); + } + + return FileTrustStoreProvider; + } +); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/showKeyStore.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/showKeyStore.html deleted file mode 100644 index 33987a8397..0000000000 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/showKeyStore.html +++ /dev/null @@ -1,51 +0,0 @@ -<!-- - - - - 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 class="keystore"> - <div class="keyStoreContainer" data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'KeyStore Attributes', open: true"> - - <div class="formLabel-labelCell">Name:</div> - <div class="nameValue"></div> - - <div class="formLabel-labelCell">Type:</div> - <div class="keyStoreTypeValue"></div> - - <div class="formLabel-labelCell">State:</div> - <div class="keyStoreStateValue"></div> - - <div class="formLabel-labelCell">Key Manager Factory Algorithm:</div> - <div class="keyManagerFactoryAlgorithmValue"></div> - - <div class="formLabel-labelCell">Path:</div> - <div class="pathValue"></div> - - <div class="certificateAlias"> - <div class="formLabel-labelCell">Certificate alias:</div> - <div class="certificateAliasValue"></div> - </div> - <div class="clear"></div> - </div> - - <br/> - <div class="dijitDialogPaneActionBar"> - <button data-dojo-type="dijit.form.Button" class="editKeyStoreButton" type="button">Edit</button> - <button data-dojo-type="dijit.form.Button" class="deleteKeyStoreButton" type="button">Delete</button> - </div> -</div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/showStore.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/showStore.html new file mode 100644 index 0000000000..e564726cbb --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/showStore.html @@ -0,0 +1,46 @@ +<!-- + ~ 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> + <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Show Store', open: true"> + <div id="showStore.contentPane"> + <div class="clear"> + <div class="formLabel-labelCell">Name:</div> + <div class="name"></div> + </div> + <div class="clear"> + <div class="formLabel-labelCell">Type:</div> + <div class="type"></div> + </div> + <div class="clear"> + <div class="formLabel-labelCell">State:</div> + <div class="state"></div> + </div> + <div class="clear"> + <div class="typeFieldsContainer"></div> + </div> + <div class="clear"> + </div> + </div> + + <div class="dijitDialogPaneActionBar"> + <button data-dojo-type="dijit.form.Button" class="editStoreButton" type="button">Edit</button> + <button data-dojo-type="dijit.form.Button" class="deleteStoreButton" type="button">Delete</button> + </div> + </div> +</div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/showTrustStore.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/showTrustStore.html deleted file mode 100644 index 2b35efd502..0000000000 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/showTrustStore.html +++ /dev/null @@ -1,51 +0,0 @@ -<!-- - - - - 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 class="truststore"> - <div class="trustStoreContainer" data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'TrustStore Attributes', open: true"> - - <div class="formLabel-labelCell">Name:</div> - <div class="nameValue"></div> - - <div class="formLabel-labelCell">Type:</div> - <div class="trustStoreTypeValue"></div> - - <div class="formLabel-labelCell">State:</div> - <div class="trustStoreStateValue"></div> - - <div class="formLabel-labelCell">Trust Manager Factory Algorithm:</div> - <div class="trustManagerFactoryAlgorithmValue"></div> - - <div class="formLabel-labelCell">Path:</div> - <div class="pathValue"></div> - - <div class="peersOnly"> - <div class="formLabel-labelCell">Peer store:</div> - <div class="peersOnlyValue"></div> - </div> - <div class="clear"></div> - </div> - - <br/> - <div class="dijitDialogPaneActionBar"> - <button data-dojo-type="dijit.form.Button" class="editTrustStoreButton" type="button">Edit</button> - <button data-dojo-type="dijit.form.Button" class="deleteTrustStoreButton" type="button">Delete</button> - </div> -</div> 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 a99c73fbf9..1a2b5293b6 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 @@ -114,6 +114,7 @@ <button data-dojo-type="dijit.form.Button" class="startButton" type="button" data-dojo-props="disabled: true">Start</button> <button data-dojo-type="dijit.form.Button" class="stopButton" type="button" data-dojo-props="disabled: true">Stop</button> <button data-dojo-type="dijit.form.Button" class="editButton" type="button" data-dojo-props="disabled: true">Edit</button> + <button data-dojo-type="dijit.form.Button" class="downloadButton" type="button" data-dojo-props="disabled: true">Download</button> <button data-dojo-type="dijit.form.Button" class="deleteButton" data-dojo-props="iconClass: 'dijitIconDelete'">Delete</button> </div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/store/filekeystore/add.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/store/filekeystore/add.html new file mode 100644 index 0000000000..1732688ba7 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/store/filekeystore/add.html @@ -0,0 +1,114 @@ +<!-- + ~ 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> + <div id="addStore.oldBrowserWarning" class="infoMessage hidden clear"></div> + <div class="clear"> + <div id="addStore.serverPathLabel" class="formLabel-labelCell tableContainer-labelCell">Server path or upload*:</div> + <div class="formLabel-controlCell tableContainer-valueCell"> + <input type="text" id="addStore.serverPath" + data-dojo-type="dijit/form/ValidationTextBox" + data-dojo-props=" + name: 'serverPath', + placeHolder: 'key store file server path', + required: true, + excluded: true, + promptMessage: 'Location of the key store file on the server', + title: 'Enter the key store file path'" /> + + <!-- Hidden and used purely for form submission --> + <input type="hidden" id="addStore.path" + data-dojo-type="dijit/form/ValidationTextBox" + data-dojo-props=" + name: 'path', + required: true" /> + </div> + + <div id="addStore.uploadFields"> + <div id="addStore.fileLabel" class="formLabel-labelCell tableContainer-labelCell"></div> + <div class="fileUpload clear"> + <span id="addStore.selectedFile" class="infoMessage"></span> + <span id="addStore.selectedFileStatus"></span> + </div> + + <div class="fileUpload clear"> + <input type="file" id="addStore.file" + multiple="false" + data-dojo-type="dojox/form/Uploader" + data-dojo-props="label: 'Upload'"/> + <button id="addStore.fileClearButton" + data-dojo-type="dijit/form/Button" + data-dojo-props="label: 'Clear', + disabled: true"> + </button> + </div> + </div> + + <div class="clear"> + <div class="formLabel-labelCell tableContainer-labelCell">Password*:</div> + <div class="formLabel-controlCell tableContainer-valueCell"> + <input type="password" id="addStore.password" + data-dojo-type="dijit/form/ValidationTextBox" + data-dojo-props=" + name: 'password', + placeHolder: 'store password', + required: true, + promptMessage: 'password for store', + title: 'Enter a password for the store'" /> + </div> + </div> + <div class="clear"> + <div class="formLabel-labelCell tableContainer-labelCell">Certificate alias:</div> + <div class="formLabel-controlCell tableContainer-valueCell"> + <input type="text" id="addStore.certificateAlias" + data-dojo-type="dijit/form/ValidationTextBox" + data-dojo-props=" + name: 'certificateAlias', + placeHolder: 'certificate alias', + promptMessage: 'Used to identify one certificate in a store that has many', + title: 'Enter an alias to identify one certificate in a store with many'" /> + </div> + </div> + <div class="clear"> + <div class="formLabel-labelCell tableContainer-labelCell clear">Key manager factory algorithm:</div> + <div class="formLabel-controlCell tableContainer-valueCell"> + <input type="text" id="addStore.keyManagerFactoryAlgorithm" + data-dojo-type="dijit/form/ValidationTextBox" + data-dojo-props=" + name: 'keyManagerFactoryAlgorithm', + placeHolder: 'key manager factory algorithm', + promptMessage: 'Name of the key manager algorithm known to Java', + title: 'Enter the key manager algorithm known to Java'" /> + </div> + </div> + <div class="clear"> + <div class="formLabel-labelCell tableContainer-labelCell">Java key store type:</div> + <div class="formLabel-controlCell tableContainer-valueCell"> + <input type="text" id="addStore.keyStoreType" + data-dojo-type="dijit/form/ValidationTextBox" + data-dojo-props=" + name: 'keyStoreType', + placeHolder: 'java key store type', + promptMessage: 'Name of the store type known to Java', + title: 'Enter the store type known to Java'" /> + </div> + </div> + + </div> +</div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/store/filekeystore/show.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/store/filekeystore/show.html new file mode 100644 index 0000000000..9a1d93d83a --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/store/filekeystore/show.html @@ -0,0 +1,39 @@ +<!-- + ~ 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> + <div class="clear"> + <div class="formLabel-labelCell">Path:</div> + <div ><span class="path" ></span></div> + </div> + <div class="clear"> + <div class="formLabel-labelCell">Certificate alias:</div> + <div><span class="certificateAlias" ></span></div> + </div> + <div class="clear"> + <div class="formLabel-labelCell">Java key store type:</div> + <div><span class="keyStoreType" ></span></div> + </div> + <div class="clear"> + <div class="formLabel-labelCell">Key manager factory algorithm:</div> + <div><span class="keyManagerFactoryAlgorithm" ></span></div> + </div> + <div class="clear"></div> +</div> + diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/store/filetruststore/add.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/store/filetruststore/add.html new file mode 100644 index 0000000000..36180d8a39 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/store/filetruststore/add.html @@ -0,0 +1,109 @@ +<!-- + ~ 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> + <div id="addStore.oldBrowserWarning" class="infoMessage hidden clear"></div> + <div class="clear"> + <div id="addStore.serverPathLabel" class="formLabel-labelCell tableContainer-labelCell">Server path or upload*:</div> + <div class="formLabel-controlCell tableContainer-valueCell"> + <input type="text" id="addStore.serverPath" + data-dojo-type="dijit/form/ValidationTextBox" + data-dojo-props=" + name: 'serverPath', + placeHolder: 'trust store file server path', + required: true, + excluded: true, + promptMessage: 'Location of the trust store file on the server', + title: 'Enter the store file path'" /> + <!-- Hidden and used purely for form submission --> + <input type="hidden" id="addStore.path" + data-dojo-type="dijit/form/ValidationTextBox" + data-dojo-props=" + name: 'path', + required: true" /> + </div> + <div id="addStore.uploadFields"> + <div id="addStore.fileLabel" class="formLabel-labelCell tableContainer-labelCell"></div> + <div class="fileUpload clear"> + <span id="addStore.selectedFile" class="infoMessage"></span> + <span id="addStore.selectedFileStatus"></span> + </div> + <div class="fileUpload clear"> + <input type="file" id="addStore.file" + multiple="false" + data-dojo-type="dojox/form/Uploader" + data-dojo-props="label: 'Upload'"/> + <button id="addStore.fileClearButton" + data-dojo-type="dijit/form/Button" + data-dojo-props="label: 'Clear', + disabled: true"> + </button> + </div> + </div> + <div class="clear"> + <div class="formLabel-labelCell tableContainer-labelCell">Password*:</div> + <div class="formLabel-controlCell tableContainer-valueCell"> + <input type="password" id="addStore.password" + data-dojo-type="dijit/form/ValidationTextBox" + data-dojo-props=" + name: 'password', + placeHolder: 'store password', + required: true, + promptMessage: 'password for store', + title: 'Enter a password for the store'" /> + </div> + </div> + <div class="clear"> + <div class="formLabel-labelCell tableContainer-labelCell">Peers only:</div> + <div class="formLabel-controlCell tableContainer-valueCell"> + <input type="text" id="addStore.peersOnly" + data-dojo-type="dijit/form/CheckBox" + data-dojo-props=" + name: 'peersOnly', + promptMessage: 'Peers only or not', + title: 'Tick if peers only'" /> + </div> + </div> + <div class="clear"> + <div class="formLabel-labelCell tableContainer-labelCell">Trust manager factory algorithm:</div> + <div class="formLabel-controlCell tableContainer-valueCell"> + <input type="text" id="addStore.keyManagerFactoryAlgorithm" + data-dojo-type="dijit/form/ValidationTextBox" + data-dojo-props=" + name: 'trustManagerFactoryAlgorithm', + placeHolder: 'trust manager factory algorithm', + promptMessage: 'Name of the trust manager algorithm known to Java', + title: 'Enter the trust manager algorithm known to Java'" /> + </div> + </div> + <div class="clear"> + <div class="formLabel-labelCell tableContainer-labelCell">Java trust store type:</div> + <div class="formLabel-controlCell tableContainer-valueCell"> + <input type="text" id="addStore.trustStoreType" + data-dojo-type="dijit/form/ValidationTextBox" + data-dojo-props=" + name: 'trustStoreType', + placeHolder: 'java trust store type', + promptMessage: 'Name of the store type known to Java', + title: 'Enter the store type known to Java'" /> + </div> + </div> + + </div> +</div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/store/filetruststore/show.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/store/filetruststore/show.html new file mode 100644 index 0000000000..1c3744b83c --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/store/filetruststore/show.html @@ -0,0 +1,39 @@ +<!-- + ~ 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> + <div class="clear"> + <div class="formLabel-labelCell">Path:</div> + <div ><span class="path" ></span></div> + </div> + <div class="clear"> + <div class="formLabel-labelCell">Peers only:</div> + <div><span class="peersOnly" ></span></div> + </div> + <div class="clear"> + <div class="formLabel-labelCell">Java trust store type:</div> + <div><span class="trustStoreType" ></span></div> + </div> + <div class="clear"> + <div class="formLabel-labelCell">Trust manager factory algorithm:</div> + <div><span class="trustManagerFactoryAlgorithm" ></span></div> + </div> + <div class="clear"></div> +</div> + diff --git a/qpid/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/store/MemorySystemConfigImpl.java b/qpid/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/store/MemorySystemConfigImpl.java index 3f5215219b..a15de21ce7 100644 --- a/qpid/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/store/MemorySystemConfigImpl.java +++ b/qpid/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/store/MemorySystemConfigImpl.java @@ -20,7 +20,8 @@ */ package org.apache.qpid.server.store; -import org.apache.qpid.server.BrokerOptions; +import java.util.Map; + import org.apache.qpid.server.configuration.updater.TaskExecutor; import org.apache.qpid.server.logging.EventLogger; import org.apache.qpid.server.logging.LogRecorder; @@ -40,10 +41,10 @@ public class MemorySystemConfigImpl extends AbstractSystemConfig<MemorySystemCon public MemorySystemConfigImpl(final TaskExecutor taskExecutor, final EventLogger eventLogger, final LogRecorder logRecorder, - final BrokerOptions brokerOptions, + final Map<String,Object> attributes, final BrokerShutdownProvider brokerShutdownProvider) { - super(taskExecutor, eventLogger, logRecorder, brokerOptions, brokerShutdownProvider); + super(taskExecutor, eventLogger, logRecorder, attributes, brokerShutdownProvider); } @Override diff --git a/qpid/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/virtualhostnode/memory/MemoryVirtualHostNode.java b/qpid/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/virtualhostnode/memory/MemoryVirtualHostNode.java index f57c0df4c0..10c30cf87a 100644 --- a/qpid/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/virtualhostnode/memory/MemoryVirtualHostNode.java +++ b/qpid/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/virtualhostnode/memory/MemoryVirtualHostNode.java @@ -20,6 +20,8 @@ */ package org.apache.qpid.server.virtualhostnode.memory; +import java.util.Collection; +import java.util.Collections; import java.util.Map; import org.apache.qpid.server.model.Broker; @@ -30,7 +32,7 @@ import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.server.store.MemoryConfigurationStore; import org.apache.qpid.server.virtualhostnode.AbstractStandardVirtualHostNode; -@ManagedObject(type=MemoryVirtualHostNode.VIRTUAL_HOST_NODE_TYPE, category=false) +@ManagedObject(type=MemoryVirtualHostNode.VIRTUAL_HOST_NODE_TYPE, category=false, validChildTypes = "org.apache.qpid.server.virtualhostnode.memory.MemoryVirtualHostNode#getSupportedChildTypes()") public class MemoryVirtualHostNode extends AbstractStandardVirtualHostNode<MemoryVirtualHostNode> { public static final String VIRTUAL_HOST_NODE_TYPE = "Memory"; @@ -51,4 +53,9 @@ public class MemoryVirtualHostNode extends AbstractStandardVirtualHostNode<Memor { return new MemoryConfigurationStore(VirtualHost.class); } + + public static Map<String, Collection<String>> getSupportedChildTypes() + { + return Collections.singletonMap(VirtualHost.class.getSimpleName(), getSupportedVirtualHostTypes(true)); + } } |
