diff options
| author | Keith Wall <kwall@apache.org> | 2015-02-10 16:15:08 +0000 |
|---|---|---|
| committer | Keith Wall <kwall@apache.org> | 2015-02-10 16:15:08 +0000 |
| commit | 085486ebe5ff21133b9caf1c31625ac6ea356568 (patch) | |
| tree | 7acbe9ca99a345dca71f9f80cd3e29ea4e3710f0 /qpid/java | |
| parent | 60c62c03ca404e98e4fbd1abf4a5ebf50763d604 (diff) | |
| parent | e2e6d542b8cde9e702d1c3b63376e9d8380ba1c7 (diff) | |
| download | qpid-python-085486ebe5ff21133b9caf1c31625ac6ea356568.tar.gz | |
merge from trunk
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/QPID-6262-JavaBrokerNIO@1658748 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java')
161 files changed, 3611 insertions, 1975 deletions
diff --git a/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionFactoryImpl.java b/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionFactoryImpl.java index 90b3298c3a..3bf9efd3d9 100644 --- a/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionFactoryImpl.java +++ b/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionFactoryImpl.java @@ -40,6 +40,7 @@ import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; +import org.apache.qpid.amqp_1_0.client.SSLOptions; import org.apache.qpid.amqp_1_0.client.SSLUtil; import org.apache.qpid.amqp_1_0.jms.ConnectionFactory; @@ -66,7 +67,15 @@ public class ConnectionFactoryImpl implements ConnectionFactory, TopicConnection private String _keyStoreCertAlias; private String _trustStorePath; private String _trustStorePassword; + private String _sslContextProtocol; + private String _sslContextProvider; + private String _sslEnabledProtocols; + private String _sslDisabledProtocols; + + + private SSLContext _sslContext; + private SSLOptions _sslOptions; public ConnectionFactoryImpl(final String host, @@ -163,7 +172,10 @@ public class ConnectionFactoryImpl implements ConnectionFactory, TopicConnection KeyManagerFactory.getDefaultAlgorithm(), _trustStorePath,_trustStorePassword, KeyStore.getDefaultType(), - TrustManagerFactory.getDefaultAlgorithm()); + TrustManagerFactory.getDefaultAlgorithm(), + _sslContextProtocol, + _sslContextProvider + ); if(username == null && _keyStoreCertAlias != null) { X509Certificate[] certs = SSLUtil.getClientCertificates(_keyStoreCertAlias, @@ -198,6 +210,7 @@ public class ConnectionFactoryImpl implements ConnectionFactory, TopicConnection connection.setTopicPrefix(_topicPrefix); connection.setUseBinaryMessageId(_useBinaryMessageId); connection.setSyncPublish(_syncPublish); + connection.setSslOptions(_sslOptions); if(_maxPrefetch != 0) { connection.setMaxPrefetch(_maxPrefetch); @@ -220,6 +233,16 @@ public class ConnectionFactoryImpl implements ConnectionFactory, TopicConnection _keyStorePassword = keyStorePassword; } + public void setSslContextProtocol(final String sslContextProtocol) + { + _sslContextProtocol = sslContextProtocol; + } + + public void setSslContextProvider(final String sslContextProvider) + { + _sslContextProvider = sslContextProvider; + } + public void setKeyStoreCertAlias(final String keyStoreCertAlias) { _keyStoreCertAlias = keyStoreCertAlias; @@ -252,6 +275,10 @@ public class ConnectionFactoryImpl implements ConnectionFactory, TopicConnection public String keyStorePath; public String keyStorePassword; public String keyStoreCertAlias; + public String sslContextProvider; + public String sslContextProtocol; + public String sslEnabledProtocols; + public String sslDisabledProtocols; } @@ -388,7 +415,36 @@ public class ConnectionFactoryImpl implements ConnectionFactory, TopicConnection { options.keyStoreCertAlias = value; } + }, + new OptionSetter("ssl-context-provider","") + { + public void setOption(final ConnectionOptions options, final String value) throws MalformedURLException + { + options.sslContextProvider = value; + } + }, + new OptionSetter("ssl-context-protocol","") + { + public void setOption(final ConnectionOptions options, final String value) throws MalformedURLException + { + options.sslContextProtocol = value; + } + }, + new OptionSetter("ssl-enabled-protocols","") + { + public void setOption(final ConnectionOptions options, final String value) throws MalformedURLException + { + options.sslEnabledProtocols = value; + } + }, + new OptionSetter("ssl-disabled-protocols","") + { + public void setOption(final ConnectionOptions options, final String value) throws MalformedURLException + { + options.sslDisabledProtocols = value; + } } + }; public static ConnectionFactoryImpl createFromURL(final String urlString) throws MalformedURLException @@ -496,6 +552,22 @@ public class ConnectionFactoryImpl implements ConnectionFactory, TopicConnection { connectionFactory.setTrustStorePassword(options.trustStorePassword); } + if (options.sslContextProvider != null) + { + connectionFactory.setSslContextProvider(options.sslContextProvider); + } + if (options.sslContextProtocol != null) + { + connectionFactory.setSslContextProtocol(options.sslContextProtocol); + } + if (options.sslEnabledProtocols != null) + { + connectionFactory.setSslEnabledProtocols(options.sslEnabledProtocols); + } + if (options.sslDisabledProtocols != null) + { + connectionFactory.setSslDisabledProtocols(options.sslDisabledProtocols); + } return connectionFactory; @@ -559,5 +631,160 @@ public class ConnectionFactoryImpl implements ConnectionFactory, TopicConnection _syncPublish = syncPublish; } + public String getSslContextProvider() + { + return _sslContextProvider; + } + + public String getSslContextProtocol() + { + return _sslContextProtocol; + } + + public String getTrustStorePassword() + { + return _trustStorePassword; + } + + public String getTrustStorePath() + { + return _trustStorePath; + } + + public String getKeyStoreCertAlias() + { + return _keyStoreCertAlias; + } + + public String getKeyStorePassword() + { + return _keyStorePassword; + } + + public String getKeyStorePath() + { + return _keyStorePath; + } + + public int getMaxPrefetch() + { + return _maxPrefetch; + } + public int getMaxSessions() + { + return _maxSessions; + } + + public Boolean getSyncPublish() + { + return _syncPublish; + } + + public boolean isUseBinaryMessageId() + { + return _useBinaryMessageId; + } + + public boolean isSsl() + { + return _ssl; + } + + public String getRemoteHost() + { + return _remoteHost; + } + + public String getClientId() + { + return _clientId; + } + + public String getPassword() + { + return _password; + } + + public String getUsername() + { + return _username; + } + + public int getPort() + { + return _port; + } + + public String getHost() + { + return _host; + } + + public String getProtocol() + { + return _protocol; + } + + public void setHost(final String host) + { + _host = host; + } + + public void setPort(final int port) + { + _port = port; + } + + public void setUsername(final String username) + { + _username = username; + } + + public void setPassword(final String password) + { + _password = password; + } + + public void setClientId(final String clientId) + { + _clientId = clientId; + } + + public void setRemoteHost(final String remoteHost) + { + _remoteHost = remoteHost; + } + + public void setSsl(final boolean ssl) + { + _ssl = ssl; + } + + public void setMaxSessions(final int maxSessions) + { + _maxSessions = maxSessions; + } + + public String getSslEnabledProtocols() + { + return _sslEnabledProtocols; + } + + public void setSslEnabledProtocols(final String sslEnabledProtocols) + { + _sslEnabledProtocols = sslEnabledProtocols; + _sslOptions = new SSLOptions(_sslEnabledProtocols, _sslDisabledProtocols); + } + + public String getSslDisabledProtocols() + { + return _sslDisabledProtocols; + } + + public void setSslDisabledProtocols(final String sslDisabledProtocols) + { + _sslDisabledProtocols = sslDisabledProtocols; + _sslOptions = new SSLOptions(_sslEnabledProtocols, _sslDisabledProtocols); + } } diff --git a/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionImpl.java b/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionImpl.java index 9722286d41..ca3d3dfbcd 100644 --- a/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionImpl.java +++ b/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionImpl.java @@ -41,6 +41,7 @@ import javax.net.ssl.SSLContext; import org.apache.qpid.amqp_1_0.client.ConnectionErrorException; import org.apache.qpid.amqp_1_0.client.ConnectionException; +import org.apache.qpid.amqp_1_0.client.SSLOptions; import org.apache.qpid.amqp_1_0.jms.Connection; import org.apache.qpid.amqp_1_0.jms.ConnectionMetaData; import org.apache.qpid.amqp_1_0.jms.Session; @@ -77,11 +78,7 @@ public class ConnectionImpl implements Connection, QueueConnection, TopicConnect private Boolean _syncPublish; private int _maxSessions; private int _maxPrefetch; - - public void setMaxPrefetch(final int maxPrefetch) - { - _maxPrefetch = maxPrefetch; - } + private SSLOptions _sslOptions; private static enum State { @@ -175,6 +172,7 @@ public class ConnectionImpl implements Connection, QueueConnection, TopicConnect { _conn = new org.apache.qpid.amqp_1_0.client.Connection(_protocol, _host, _port, _username, _password, container, _remoteHost, _sslContext, + _sslOptions, _maxSessions - 1); _conn.setConnectionErrorTask(new ConnectionErrorTask()); // TODO - retrieve negotiated AMQP version @@ -674,6 +672,21 @@ public class ConnectionImpl implements Connection, QueueConnection, TopicConnect return _syncPublish; } + public void setMaxPrefetch(final int maxPrefetch) + { + _maxPrefetch = maxPrefetch; + } + + public void setSslOptions(final SSLOptions sslOptions) + { + _sslOptions = sslOptions; + } + + public SSLOptions getSslOptions() + { + return _sslOptions; + } + private class ConnectionErrorTask implements Runnable { diff --git a/qpid/java/amqp-1-0-client-websocket/src/main/java/org/apache/qpid/amqp_1_0/client/websocket/WebSocketProvider.java b/qpid/java/amqp-1-0-client-websocket/src/main/java/org/apache/qpid/amqp_1_0/client/websocket/WebSocketProvider.java index af871d2bc4..8df20d495c 100644 --- a/qpid/java/amqp-1-0-client-websocket/src/main/java/org/apache/qpid/amqp_1_0/client/websocket/WebSocketProvider.java +++ b/qpid/java/amqp-1-0-client-websocket/src/main/java/org/apache/qpid/amqp_1_0/client/websocket/WebSocketProvider.java @@ -33,6 +33,7 @@ import org.eclipse.jetty.websocket.WebSocketClient; import org.eclipse.jetty.websocket.WebSocketClientFactory; import org.apache.qpid.amqp_1_0.client.ConnectionException; +import org.apache.qpid.amqp_1_0.client.SSLOptions; import org.apache.qpid.amqp_1_0.client.SSLUtil; import org.apache.qpid.amqp_1_0.client.TransportProvider; import org.apache.qpid.amqp_1_0.codec.FrameWriter; @@ -111,7 +112,9 @@ class WebSocketProvider implements TransportProvider public void connect(final ConnectionEndpoint conn, final String address, final int port, - final SSLContext sslContext, final ExceptionHandler exceptionHandler) throws ConnectionException + final SSLContext sslContext, + final SSLOptions sslOptions, + final ExceptionHandler exceptionHandler) throws ConnectionException { try diff --git a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Connection.java b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Connection.java index 9319d4ddff..69b4939070 100644 --- a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Connection.java +++ b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Connection.java @@ -149,10 +149,26 @@ public class Connection implements ExceptionHandler final SSLContext sslContext, final int channelMax) throws ConnectionException { + this(protocol, address, port, username, password,container,remoteHost,sslContext, + null, channelMax); + } + + public Connection(final String protocol, + final String address, + final int port, + final String username, + final String password, + final Container container, + final String remoteHost, + final SSLContext sslContext, + final SSLOptions sslOptions, + final int channelMax) throws ConnectionException + { this(protocol, address, port, username, password, MAX_FRAME_SIZE,container,remoteHost,sslContext, - channelMax); + sslOptions, channelMax); } + public Connection(final String address, final int port, final String username, @@ -163,7 +179,11 @@ public class Connection implements ExceptionHandler boolean ssl, int channelMax) throws ConnectionException { - this(ssl?"amqp":"amqps",address,port,username,password,maxFrameSize,container,remoteHostname,getSslContext(ssl),channelMax); + this(ssl?"amqp":"amqps",address,port,username,password,maxFrameSize,container, + remoteHostname, + getSslContext(ssl), + null, + channelMax); } private static SSLContext getSslContext(final boolean ssl) throws ConnectionException @@ -187,7 +207,7 @@ public class Connection implements ExceptionHandler final Container container, final String remoteHostname, SSLContext sslContext, - int channelMax) throws ConnectionException + final SSLOptions sslOptions, int channelMax) throws ConnectionException { _address = address; @@ -255,7 +275,7 @@ public class Connection implements ExceptionHandler TransportProvider transportProvider = getTransportProvider(protocol); - transportProvider.connect(_conn,address,port, sslContext, this); + transportProvider.connect(_conn,address,port, sslContext, sslOptions, this); try diff --git a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/SSLOptions.java b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/SSLOptions.java new file mode 100644 index 0000000000..1558b2043b --- /dev/null +++ b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/SSLOptions.java @@ -0,0 +1,79 @@ +/* + * + * 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.amqp_1_0.client; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class SSLOptions +{ + private final List<String> _enabledProtocols; + private final List<String> _disabledProtocols; + + public SSLOptions(String enabledProtocols, String disabledProtocols) + { + if(enabledProtocols == null) + { + enabledProtocols = System.getProperty("qpid.ssl.enabledProtocols"); + } + + if(disabledProtocols == null) + { + disabledProtocols = System.getProperty("qpid.ssl.disabledProtocols", SSLUtil.SSLV3_PROTOCOL); + } + + if(enabledProtocols == null) + { + _enabledProtocols = null; + } + else + { + _enabledProtocols = Collections.unmodifiableList(Arrays.asList(enabledProtocols.split(","))); + } + + if(disabledProtocols == null) + { + _disabledProtocols = null; + } + else + { + _disabledProtocols = Collections.unmodifiableList(Arrays.asList(disabledProtocols.split(","))); + } + } + + public SSLOptions(final List<String> enabledProtocols, final List<String> disabledProtocols) + { + this._enabledProtocols = enabledProtocols == null ? Collections.<String>emptyList() : Collections.unmodifiableList(new ArrayList<>(enabledProtocols)); + this._disabledProtocols = disabledProtocols == null ? Collections.<String>emptyList() : Collections.unmodifiableList(new ArrayList<>(disabledProtocols)); + } + + public List<String> getEnabledProtocols() + { + return _enabledProtocols; + } + + public List<String> getDisabledProtocols() + { + return _disabledProtocols; + } +} diff --git a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/SSLUtil.java b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/SSLUtil.java index 225293c42e..7bcf796fa9 100644 --- a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/SSLUtil.java +++ b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/SSLUtil.java @@ -27,12 +27,15 @@ import java.io.InputStream; import java.net.Socket; import java.security.GeneralSecurityException; import java.security.KeyStore; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; import java.security.Principal; import java.security.PrivateKey; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.logging.Logger; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; @@ -48,6 +51,10 @@ public class SSLUtil public static final String TRANSPORT_LAYER_SECURITY_CODE = "TLS"; public static final String SSLV3_PROTOCOL = "SSLv3"; + + private static final Logger LOGGER = Logger.getLogger(SSLUtil.class.getName()); + + public static SSLContext buildSslContext(final String certAlias, final String keyStorePath, final String keyStoreType, @@ -56,11 +63,13 @@ public class SSLUtil final String trustStorePath, final String trustStorePassword, final String trustStoreType, - final String trustManagerFactoryAlgorithm) throws GeneralSecurityException, IOException + final String trustManagerFactoryAlgorithm, + final String sslProtocol, + final String sslProvider) throws GeneralSecurityException, IOException { - final SSLContext sslContext = SSLContext - .getInstance(TRANSPORT_LAYER_SECURITY_CODE); + + SSLContext sslContext = getSslContext(sslProtocol, sslProvider); final TrustManager[] trustManagers; final KeyManager[] keyManagers; @@ -109,6 +118,49 @@ public class SSLUtil return sslContext; } + private static SSLContext getSslContext(final String sslProtocol, + final String sslProvider) throws NoSuchAlgorithmException + { + + final String sslProviderName = sslProvider != null ? sslProvider : System.getProperty("qpid.ssl.contextProvider"); + final String sslProtocolName = sslProtocol != null ? sslProtocol : System.getProperty("qpid.ssl.contextProtocol", TRANSPORT_LAYER_SECURITY_CODE); + + SSLContext sslContext = null; + if(sslProviderName != null && sslProtocolName != null) + { + try + { + sslContext = SSLContext.getInstance(sslProtocolName, sslProviderName); + } + catch(NoSuchProviderException e) + { + LOGGER.info("Unknown SSL Context Provider '"+ sslProviderName + "' will use the default"); + } + catch (NoSuchAlgorithmException e) + { + LOGGER.info("Unknown SSL protocol '" + sslProtocolName + + "' when using the provider '" + sslProviderName + "' will use the default provider"); + } + } + if(sslContext == null && sslProtocolName != null) + { + try + { + sslContext = SSLContext.getInstance(sslProtocolName); + } + catch(NoSuchAlgorithmException e) + { + LOGGER.info("Unknown SSL protocol '" + sslProtocolName + + "' will use '"+TRANSPORT_LAYER_SECURITY_CODE+"'"); + } + } + if(sslContext == null) + { + sslContext = SSLContext.getInstance(TRANSPORT_LAYER_SECURITY_CODE); + } + return sslContext; + } + public static X509Certificate[] getClientCertificates(final String alias, final String keyStorePath, final String keyStorePassword, diff --git a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TCPTransportProvier.java b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TCPTransportProvider.java index 720f12dc0d..855d619081 100644 --- a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TCPTransportProvier.java +++ b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TCPTransportProvider.java @@ -26,6 +26,10 @@ import java.io.OutputStream; import java.net.Socket; import java.net.SocketTimeoutException; import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Level; import java.util.logging.Logger; @@ -40,7 +44,7 @@ import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint; import org.apache.qpid.amqp_1_0.type.FrameBody; import org.apache.qpid.amqp_1_0.type.SaslFrameBody; -class TCPTransportProvier implements TransportProvider +class TCPTransportProvider implements TransportProvider { private static final Logger RAW_LOGGER = Logger.getLogger("RAW"); @@ -57,7 +61,7 @@ class TCPTransportProvier implements TransportProvider private long _readIdleTimeout = Long.getLong("qpid.connection_read_idle_timeout", -1L); private final AtomicLong _threadNameIndex = new AtomicLong(); - public TCPTransportProvier(final String transport) + public TCPTransportProvider(final String transport) { _transport = transport; } @@ -67,7 +71,7 @@ class TCPTransportProvier implements TransportProvider final String address, final int port, final SSLContext sslContext, - final ExceptionHandler exceptionHandler) throws ConnectionException + final SSLOptions sslOptions, final ExceptionHandler exceptionHandler) throws ConnectionException { try { @@ -75,7 +79,30 @@ class TCPTransportProvier implements TransportProvider { final SSLSocketFactory socketFactory = sslContext.getSocketFactory(); SSLSocket sslSocket = (SSLSocket) socketFactory.createSocket(address, port); - SSLUtil.removeSSLv3Support(sslSocket); + if(sslOptions == null) + { + SSLUtil.removeSSLv3Support(sslSocket); + } + else + { + final List<String> enabledProtocols = sslOptions.getEnabledProtocols(); + final List<String> disabledProtocols = sslOptions.getDisabledProtocols(); + + if(enabledProtocols != null && !enabledProtocols.isEmpty()) + { + final Set<String> supportedSuites = + new HashSet<>(Arrays.asList(sslSocket.getSupportedProtocols())); + supportedSuites.retainAll(enabledProtocols); + sslSocket.setEnabledProtocols(supportedSuites.toArray(new String[supportedSuites.size()])); + } + + if(disabledProtocols != null && !disabledProtocols.isEmpty()) + { + final Set<String> enabledSuites = new HashSet<>(Arrays.asList(sslSocket.getEnabledProtocols())); + enabledSuites.removeAll(disabledProtocols); + sslSocket.setEnabledProtocols(enabledSuites.toArray(new String[enabledSuites.size()])); + } + } sslSocket.startHandshake(); conn.setExternalPrincipal(sslSocket.getSession().getLocalPrincipal()); _socket=sslSocket; diff --git a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TCPTransportProviderFactory.java b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TCPTransportProviderFactory.java index 2327a3860a..a29bbcd232 100644 --- a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TCPTransportProviderFactory.java +++ b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TCPTransportProviderFactory.java @@ -34,6 +34,6 @@ public class TCPTransportProviderFactory implements TransportProviderFactory @Override public TransportProvider getProvider(final String transport) { - return new TCPTransportProvier(transport); + return new TCPTransportProvider(transport); } } diff --git a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TransportProvider.java b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TransportProvider.java index 71628679f8..e8ea53b451 100644 --- a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TransportProvider.java +++ b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TransportProvider.java @@ -31,6 +31,7 @@ public interface TransportProvider String address, int port, SSLContext sslContext, + final SSLOptions sslOptions, ExceptionHandler exceptionHandler) throws ConnectionException; void close(); diff --git a/qpid/java/broker-core/pom.xml b/qpid/java/broker-core/pom.xml index 68301f07bd..516ac9a4c4 100644 --- a/qpid/java/broker-core/pom.xml +++ b/qpid/java/broker-core/pom.xml @@ -150,6 +150,9 @@ <testResource> <directory>${basedir}/src/test/resources</directory> </testResource> + <testResource> + <directory>${basedir}/../test-profiles/test_resources/ssl</directory> + </testResource> </testResources> <plugins> diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/BrokerOptions.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/BrokerOptions.java index c7cceb3913..59075dfb57 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/BrokerOptions.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/BrokerOptions.java @@ -30,7 +30,6 @@ import java.util.concurrent.ConcurrentMap; import org.apache.qpid.server.configuration.BrokerProperties; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.SystemConfig; -import org.apache.qpid.server.util.StringUtil; public class BrokerOptions { @@ -58,7 +57,6 @@ public class BrokerOptions BrokerOptions.class.getClassLoader().getResource(DEFAULT_INITIAL_CONFIG_NAME).toExternalForm(); public static final String MANAGEMENT_MODE_USER_NAME = "mm_admin"; - private static final int MANAGEMENT_MODE_PASSWORD_LENGTH = 10; private static final File FALLBACK_WORK_DIR = new File(System.getProperty("user.dir"), "work"); @@ -79,7 +77,6 @@ public class BrokerOptions private boolean _skipLoggingConfiguration; private boolean _overwriteConfigurationStore; private Map<String, String> _configProperties = new HashMap<String,String>(); - private String _initialSystemProperties; private boolean _startupLoggedToSystemOut = true; public Map<String, Object> convertToSystemConfigAttributes() @@ -102,11 +99,6 @@ public class BrokerOptions public String getManagementModePassword() { - if(_managementModePassword == null) - { - _managementModePassword = new StringUtil().randomAlphaNumericString(MANAGEMENT_MODE_PASSWORD_LENGTH); - } - return _managementModePassword; } diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsoleMessages.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsoleMessages.java index 16a115d1ae..6c27b51ce0 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsoleMessages.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsoleMessages.java @@ -46,7 +46,6 @@ public class ManagementConsoleMessages public static final String MANAGEMENTCONSOLE_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "managementconsole"; public static final String OPEN_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "managementconsole.open"; public static final String LISTENING_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "managementconsole.listening"; - public static final String SSL_KEYSTORE_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "managementconsole.ssl_keystore"; public static final String STOPPED_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "managementconsole.stopped"; public static final String CLOSE_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "managementconsole.close"; public static final String SHUTTING_DOWN_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "managementconsole.shutting_down"; @@ -58,7 +57,6 @@ public class ManagementConsoleMessages Logger.getLogger(MANAGEMENTCONSOLE_LOG_HIERARCHY); Logger.getLogger(OPEN_LOG_HIERARCHY); Logger.getLogger(LISTENING_LOG_HIERARCHY); - Logger.getLogger(SSL_KEYSTORE_LOG_HIERARCHY); Logger.getLogger(STOPPED_LOG_HIERARCHY); Logger.getLogger(CLOSE_LOG_HIERARCHY); Logger.getLogger(SHUTTING_DOWN_LOG_HIERARCHY); @@ -102,16 +100,16 @@ public class ManagementConsoleMessages /** * Log a ManagementConsole message of the Format: - * <pre>MNG-1002 : Starting : {0} : Listening on port {1,number,#}</pre> + * <pre>MNG-1002 : Starting : {0} : Listening on {1} port {2,number,#}</pre> * Optional values are contained in [square brackets] and are numbered * sequentially in the method call. * */ - public static LogMessage LISTENING(String param1, Number param2) + public static LogMessage LISTENING(String param1, String param2, Number param3) { String rawMessage = _messages.getString("LISTENING"); - final Object[] messageArguments = {param1, param2}; + final Object[] messageArguments = {param1, param2, param3}; // Create a new MessageFormat to ensure thread safety. // Sharing a MessageFormat and using applyPattern is not thread safe MessageFormat formatter = new MessageFormat(rawMessage, _currentLocale); @@ -134,38 +132,6 @@ public class ManagementConsoleMessages /** * Log a ManagementConsole message of the Format: - * <pre>MNG-1006 : Using SSL Keystore : {0}</pre> - * Optional values are contained in [square brackets] and are numbered - * sequentially in the method call. - * - */ - public static LogMessage SSL_KEYSTORE(String param1) - { - String rawMessage = _messages.getString("SSL_KEYSTORE"); - - final Object[] messageArguments = {param1}; - // Create a new MessageFormat to ensure thread safety. - // Sharing a MessageFormat and using applyPattern is not thread safe - MessageFormat formatter = new MessageFormat(rawMessage, _currentLocale); - - final String message = formatter.format(messageArguments); - - return new LogMessage() - { - public String toString() - { - return message; - } - - public String getLogHierarchy() - { - return SSL_KEYSTORE_LOG_HIERARCHY; - } - }; - } - - /** - * Log a ManagementConsole message of the Format: * <pre>MNG-1005 : {0} Management Stopped</pre> * Optional values are contained in [square brackets] and are numbered * sequentially in the method call. diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsole_logmessages.properties b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsole_logmessages.properties index 7924be28d3..bb4dce7d36 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsole_logmessages.properties +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsole_logmessages.properties @@ -22,7 +22,7 @@ STARTUP = MNG-1001 : {0} Management Startup # 0 - Service # 1 - Port -LISTENING = MNG-1002 : Starting : {0} : Listening on port {1,number,#} +LISTENING = MNG-1002 : Starting : {0} : Listening on {1} port {2,number,#} # 0 - Service # 1 - Port SHUTTING_DOWN = MNG-1003 : Shutting down : {0} : port {1,number,#} @@ -30,8 +30,6 @@ SHUTTING_DOWN = MNG-1003 : Shutting down : {0} : port {1,number,#} READY = MNG-1004 : {0} Management Ready # 0 - Management Type STOPPED = MNG-1005 : {0} Management Stopped -# 0 - Path -SSL_KEYSTORE = MNG-1006 : Using SSL Keystore : {0} # 0 - Username OPEN = MNG-1007 : Open : User {0} # 0 - Username diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/BrokerModel.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/BrokerModel.java index a9e9f26af0..57d61b963a 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/BrokerModel.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/BrokerModel.java @@ -42,12 +42,13 @@ public final class BrokerModel extends Model * 1.3 Truststore/Keystore type => trustStoreType / type => keyStoreType * 1.4 Separate messageStoreSettings from virtualhost * 2.0 Introduce VirtualHostNode as a child of a Broker instead of VirtualHost - * 2.1 Add VH aliases; + * 3.0 Add VH aliases; * Remove Broker#supportedVirtualHostNodeTypes, #supportedVirtualHostTypes, #supportedAuthenticationProviders, * supportedPreferencesProviderTypes, VH#supportedExchangeTypes, VH#supportedQueueTypes + * Renamed FileTrustStore/FileKeyStore.path => FileTrustStore/FileKeyStore.storeUrl */ - public static final int MODEL_MAJOR_VERSION = 2; - public static final int MODEL_MINOR_VERSION = 1; + public static final int MODEL_MAJOR_VERSION = 3; + public static final int MODEL_MINOR_VERSION = 0; public static final String MODEL_VERSION = MODEL_MAJOR_VERSION + "." + MODEL_MINOR_VERSION; private static final Model MODEL_INSTANCE = new BrokerModel(); private final Map<Class<? extends ConfiguredObject>, Collection<Class<? extends ConfiguredObject>>> _parents = diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredAutomatedAttribute.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredAutomatedAttribute.java index 24a62de61c..9fca898dc0 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredAutomatedAttribute.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredAutomatedAttribute.java @@ -123,6 +123,18 @@ public class ConfiguredAutomatedAttribute<C extends ConfiguredObject, T> extend return _annotation.persist(); } + @Override + public boolean isOversized() + { + return _annotation.oversize(); + } + + @Override + public String getOversizedAltText() + { + return _annotation.oversizedAltText(); + } + public String getDescription() { return _annotation.description(); diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredDerivedAttribute.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredDerivedAttribute.java index 9495c1ff84..71488edb8c 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredDerivedAttribute.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredDerivedAttribute.java @@ -54,6 +54,19 @@ public class ConfiguredDerivedAttribute<C extends ConfiguredObject, T> extends return _annotation.persist(); } + @Override + public boolean isOversized() + { + return _annotation.oversize(); + } + + @Override + public String getOversizedAltText() + { + return ""; + } + + public String getDescription() { return _annotation.description(); diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java index deda7768f3..7079461a09 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java @@ -35,6 +35,8 @@ import org.apache.qpid.server.store.ConfiguredObjectRecord; */ public interface ConfiguredObject<X extends ConfiguredObject<X>> { + String OVER_SIZED_ATTRIBUTE_ALTERNATIVE_TEXT = "Value is too long to display"; + String ID = "id"; String NAME = "name"; String TYPE = "type"; diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectAttribute.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectAttribute.java index 1d1c736cd3..73b7839a8e 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectAttribute.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectAttribute.java @@ -43,6 +43,10 @@ public abstract class ConfiguredObjectAttribute<C extends ConfiguredObject, T> e public abstract boolean isPersisted(); + public abstract boolean isOversized(); + + public abstract String getOversizedAltText(); + public abstract String getDescription(); public T convert(final Object value, C object) diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/DerivedAttribute.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/DerivedAttribute.java index 57fc5b365e..e5c17a17e4 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/DerivedAttribute.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/DerivedAttribute.java @@ -31,5 +31,5 @@ public @interface DerivedAttribute boolean secure() default false; boolean persist() default false; String description() default ""; - + boolean oversize() default false; } diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/GroupManagingGroupProvider.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/GroupManagingGroupProvider.java new file mode 100644 index 0000000000..a961d77776 --- /dev/null +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/GroupManagingGroupProvider.java @@ -0,0 +1,24 @@ +/* + * 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.model; + +@ManagedAnnotation +public interface GroupManagingGroupProvider extends ManagedInterface +{ +} diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ManagedAttribute.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ManagedAttribute.java index d8b36f487c..05b2c610ba 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ManagedAttribute.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ManagedAttribute.java @@ -35,4 +35,6 @@ public @interface ManagedAttribute String defaultValue() default ""; String description() default ""; String[] validValues() default {}; + boolean oversize() default false; + String oversizedAltText() default ""; } diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ManagedObject.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ManagedObject.java index 483ddd478d..66a5508ec6 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ManagedObject.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ManagedObject.java @@ -37,4 +37,6 @@ public @interface ManagedObject String type() default ""; String validChildTypes() default ""; boolean register() default true; + String description() default ""; + boolean deprecated() default false; } diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Port.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Port.java index 24528b9a4e..7318a58640 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Port.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Port.java @@ -60,6 +60,18 @@ public interface Port<X extends Port<X>> extends ConfiguredObject<X> @ManagedAttribute Collection<TrustStore> getTrustStores(); + @ManagedContextDefault(name = "qpid.port.enabledCipherSuites" ) + String DEFAULT_ENABLED_CIPHER_SUITES="[]"; + + @ManagedAttribute( defaultValue = "${qpid.port.enabledCipherSuites}") + Collection<String> getEnabledCipherSuites(); + + @ManagedContextDefault(name = "qpid.port.disabledCipherSuites" ) + String DEFAULT_DISABLED_CIPHER_SUITES="[]"; + + @ManagedAttribute( defaultValue = "${qpid.port.disabledCipherSuites}") + Collection<String> getDisabledCipherSuites(); + Collection<Connection> getConnections(); void start(); diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHostNode.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHostNode.java index ce1022c2d9..fa35e725c9 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHostNode.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHostNode.java @@ -27,6 +27,11 @@ import org.apache.qpid.server.store.DurableConfigurationStore; @ManagedObject(category=true, managesChildren=false) public interface VirtualHostNode<X extends VirtualHostNode<X>> extends ConfiguredObject<X> { + String QPID_INITIAL_CONFIG_VIRTUALHOST_CONFIG_VAR = "qpid.initial_config_virtualhost_config"; + @ManagedContextDefault(name = QPID_INITIAL_CONFIG_VIRTUALHOST_CONFIG_VAR) + String DEFAULT_INITIAL_CONFIG_VIRTUALHOST_CONFIG_VAR = "{ \"type\" : \"DERBY\" }"; + + String VIRTUALHOST_INITIAL_CONFIGURATION = "virtualHostInitialConfiguration"; String VIRTUALHOST_BLUEPRINT_CONTEXT_VAR = "virtualhostBlueprint"; diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProvider.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProvider.java index d338dad300..631ed3e8f7 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProvider.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProvider.java @@ -20,12 +20,13 @@ */ package org.apache.qpid.server.model.adapter; +import org.apache.qpid.server.model.GroupManagingGroupProvider; import org.apache.qpid.server.model.GroupProvider; import org.apache.qpid.server.model.ManagedAttribute; import org.apache.qpid.server.model.ManagedObject; @ManagedObject( category = false, type = "GroupFile" ) -public interface FileBasedGroupProvider<X extends FileBasedGroupProvider<X>> extends GroupProvider<X> +public interface FileBasedGroupProvider<X extends FileBasedGroupProvider<X>> extends GroupProvider<X>, GroupManagingGroupProvider { String PATH="path"; diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java index 6d8e65cd17..21827ffe58 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java @@ -66,6 +66,12 @@ abstract public class AbstractPort<X extends AbstractPort<X>> extends AbstractCo @ManagedAttributeField private Set<Protocol> _protocols; + @ManagedAttributeField + private Collection<String> _enabledCipherSuites; + + @ManagedAttributeField + private Collection<String> _disabledCipherSuites; + public AbstractPort(Map<String, Object> attributes, Broker<?> broker) { @@ -278,6 +284,18 @@ abstract public class AbstractPort<X extends AbstractPort<X>> extends AbstractCo } @Override + public Collection<String> getEnabledCipherSuites() + { + return _enabledCipherSuites; + } + + @Override + public Collection<String> getDisabledCipherSuites() + { + return _disabledCipherSuites; + } + + @Override public KeyStore getKeyStore() { return _keyStore; diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStore.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStore.java index 899e98fa22..0607f4b3d3 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStore.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStore.java @@ -22,6 +22,7 @@ package org.apache.qpid.server.security; import javax.net.ssl.KeyManagerFactory; +import org.apache.qpid.server.model.DerivedAttribute; import org.apache.qpid.server.model.KeyStore; import org.apache.qpid.server.model.ManagedAttribute; import org.apache.qpid.server.model.ManagedContextDefault; @@ -35,7 +36,8 @@ public interface FileKeyStore<X extends FileKeyStore<X>> extends KeyStore<X> String CERTIFICATE_ALIAS = "certificateAlias"; String KEY_STORE_TYPE = "keyStoreType"; String PASSWORD = "password"; - String PATH = "path"; + String STORE_URL = "storeUrl"; + @ManagedContextDefault(name = "keyStoreFile.keyStoreType") RuntimeDefault<String> DEFAULT_KEYSTORE_TYPE = new RuntimeDefault<String>() @@ -60,7 +62,10 @@ public interface FileKeyStore<X extends FileKeyStore<X>> extends KeyStore<X> @ManagedAttribute(defaultValue = "${this:path}") String getDescription(); - @ManagedAttribute( mandatory = true) + @ManagedAttribute( mandatory = true, secure = true, oversize = true, oversizedAltText = OVER_SIZED_ATTRIBUTE_ALTERNATIVE_TEXT) + String getStoreUrl(); + + @DerivedAttribute String getPath(); @ManagedAttribute diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreImpl.java index 31a4b473ed..aa5f55dfb4 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreImpl.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreImpl.java @@ -68,7 +68,8 @@ public class FileKeyStoreImpl extends AbstractConfiguredObject<FileKeyStoreImpl> private String _certificateAlias; @ManagedAttributeField private String _keyManagerFactoryAlgorithm; - @ManagedAttributeField + @ManagedAttributeField(afterSet = "postSetStoreUrl") + private String _storeUrl; private String _path; @ManagedAttributeField private String _password; @@ -162,7 +163,7 @@ public class FileKeyStoreImpl extends AbstractConfiguredObject<FileKeyStoreImpl> java.security.KeyStore keyStore; try { - URL url = getUrlFromString(fileKeyStore.getPath()); + URL url = getUrlFromString(fileKeyStore.getStoreUrl()); String password = fileKeyStore.getPassword(); String keyStoreType = fileKeyStore.getKeyStoreType(); keyStore = SSLUtil.getInitializedKeyStore(url, password, keyStoreType); @@ -173,11 +174,11 @@ public class FileKeyStoreImpl extends AbstractConfiguredObject<FileKeyStoreImpl> final String message; if (e instanceof IOException && e.getCause() != null && e.getCause() instanceof UnrecoverableKeyException) { - message = "Check key store password. Cannot instantiate key store from '" + fileKeyStore.getPath() + "'."; + message = "Check key store password. Cannot instantiate key store from '" + fileKeyStore.getStoreUrl() + "'."; } else { - message = "Cannot instantiate key store from '" + fileKeyStore.getPath() + "'."; + message = "Cannot instantiate key store from '" + fileKeyStore.getStoreUrl() + "'."; } throw new IllegalConfigurationException(message, e); @@ -198,7 +199,7 @@ public class FileKeyStoreImpl extends AbstractConfiguredObject<FileKeyStoreImpl> if (cert == null) { throw new IllegalConfigurationException("Cannot find a certificate with alias '" + fileKeyStore.getCertificateAlias() - + "' in key store : " + fileKeyStore.getPath()); + + "' in key store : " + fileKeyStore.getStoreUrl()); } } @@ -219,6 +220,12 @@ public class FileKeyStoreImpl extends AbstractConfiguredObject<FileKeyStoreImpl> } @Override + public String getStoreUrl() + { + return _storeUrl; + } + + @Override public String getPath() { return _path; @@ -258,7 +265,7 @@ public class FileKeyStoreImpl extends AbstractConfiguredObject<FileKeyStoreImpl> try { - URL url = getUrlFromString(_path); + URL url = getUrlFromString(_storeUrl); if (_certificateAlias != null) { return new KeyManager[] { @@ -301,4 +308,17 @@ public class FileKeyStoreImpl extends AbstractConfiguredObject<FileKeyStoreImpl> } return url; } + + @SuppressWarnings(value = "unused") + private void postSetStoreUrl() + { + if (_storeUrl != null && !_storeUrl.startsWith("data:")) + { + _path = _storeUrl; + } + else + { + _path = null; + } + } } diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStore.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStore.java index 86d7d5e4b8..a8035da5b4 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStore.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStore.java @@ -22,6 +22,7 @@ package org.apache.qpid.server.security; import javax.net.ssl.KeyManagerFactory; +import org.apache.qpid.server.model.DerivedAttribute; import org.apache.qpid.server.model.ManagedAttribute; import org.apache.qpid.server.model.ManagedContextDefault; import org.apache.qpid.server.model.ManagedObject; @@ -35,7 +36,7 @@ public interface FileTrustStore<X extends FileTrustStore<X>> extends TrustStore< String PEERS_ONLY = "peersOnly"; String TRUST_STORE_TYPE = "trustStoreType"; String PASSWORD = "password"; - String PATH = "path"; + String STORE_URL = "storeUrl"; @ManagedContextDefault(name = "trustStoreFile.trustStoreType") RuntimeDefault<String> DEFAULT_TRUSTSTORE_TYPE = new RuntimeDefault<String>() @@ -58,10 +59,13 @@ public interface FileTrustStore<X extends FileTrustStore<X>> extends TrustStore< }; - @ManagedAttribute(defaultValue = "${this:path}") + @ManagedAttribute(defaultValue = "${this:storeUrl}") String getDescription(); - @ManagedAttribute( mandatory = true ) + @ManagedAttribute( mandatory = true, oversize = true, oversizedAltText = OVER_SIZED_ATTRIBUTE_ALTERNATIVE_TEXT) + String getStoreUrl(); + + @DerivedAttribute String getPath(); @ManagedAttribute( defaultValue = "${trustStoreFile.trustManagerFactoryAlgorithm}") diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java index 66ae6fdb35..fb161fef4e 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java @@ -64,7 +64,8 @@ public class FileTrustStoreImpl extends AbstractConfiguredObject<FileTrustStoreI private String _trustStoreType; @ManagedAttributeField private String _trustManagerFactoryAlgorithm; - @ManagedAttributeField + @ManagedAttributeField(afterSet = "postSetStoreUrl") + private String _storeUrl; private String _path; @ManagedAttributeField private boolean _peersOnly; @@ -193,7 +194,7 @@ public class FileTrustStoreImpl extends AbstractConfiguredObject<FileTrustStoreI { try { - URL trustStoreUrl = getUrlFromString(trustStore.getPath()); + URL trustStoreUrl = getUrlFromString(trustStore.getStoreUrl()); SSLUtil.getInitializedKeyStore(trustStoreUrl, trustStore.getPassword(), trustStore.getTrustStoreType()); } catch (Exception e) @@ -201,11 +202,11 @@ public class FileTrustStoreImpl extends AbstractConfiguredObject<FileTrustStoreI final String message; if (e instanceof IOException && e.getCause() != null && e.getCause() instanceof UnrecoverableKeyException) { - message = "Check trust store password. Cannot instantiate trust store from '" + trustStore.getPath() + "'."; + message = "Check trust store password. Cannot instantiate trust store from '" + trustStore.getStoreUrl() + "'."; } else { - message = "Cannot instantiate trust store from '" + trustStore.getPath() + "'."; + message = "Cannot instantiate trust store from '" + trustStore.getStoreUrl() + "'."; } throw new IllegalConfigurationException(message, e); @@ -222,6 +223,12 @@ public class FileTrustStoreImpl extends AbstractConfiguredObject<FileTrustStoreI } @Override + public String getStoreUrl() + { + return _storeUrl; + } + + @Override public String getPath() { return _path; @@ -263,7 +270,7 @@ public class FileTrustStoreImpl extends AbstractConfiguredObject<FileTrustStoreI try { - URL trustStoreUrl = getUrlFromString(_path); + URL trustStoreUrl = getUrlFromString(_storeUrl); KeyStore ts = SSLUtil.getInitializedKeyStore(trustStoreUrl, trustStorePassword, trustStoreType); final TrustManagerFactory tmf = TrustManagerFactory @@ -328,4 +335,16 @@ public class FileTrustStoreImpl extends AbstractConfiguredObject<FileTrustStoreI return url; } + @SuppressWarnings(value = "unused") + private void postSetStoreUrl() + { + if (_storeUrl != null && !_storeUrl.startsWith("data:")) + { + _path = _storeUrl; + } + else + { + _path = null; + } + } } diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStore.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStore.java index 458daa4b7a..78509182b5 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStore.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStore.java @@ -31,13 +31,13 @@ public interface NonJavaKeyStore<X extends NonJavaKeyStore<X>> extends KeyStore< @ManagedAttribute(defaultValue = "${this:subjectName}") String getDescription(); - @ManagedAttribute( mandatory = true, secure = true ) + @ManagedAttribute( mandatory = true, secure = true, oversize = true, oversizedAltText = OVER_SIZED_ATTRIBUTE_ALTERNATIVE_TEXT ) String getPrivateKeyUrl(); - @ManagedAttribute( mandatory = true ) + @ManagedAttribute( mandatory = true, oversize = true, oversizedAltText = OVER_SIZED_ATTRIBUTE_ALTERNATIVE_TEXT ) String getCertificateUrl(); - @ManagedAttribute + @ManagedAttribute( oversize = true, oversizedAltText = OVER_SIZED_ATTRIBUTE_ALTERNATIVE_TEXT ) String getIntermediateCertificateUrl(); @DerivedAttribute diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStoreImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStoreImpl.java index 6231413dd7..f6298ab383 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStoreImpl.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStoreImpl.java @@ -248,16 +248,16 @@ public class NonJavaKeyStoreImpl extends AbstractConfiguredObject<NonJavaKeyStor { try { - getUrlFromString(keyStore.getPrivateKeyUrl()).openStream(); - getUrlFromString(keyStore.getCertificateUrl()).openStream(); + readPrivateKey(getUrlFromString(keyStore.getPrivateKeyUrl())); + readCertificates(getUrlFromString(keyStore.getCertificateUrl())); if(keyStore.getIntermediateCertificateUrl() != null) { - getUrlFromString(keyStore.getIntermediateCertificateUrl()).openStream(); + readCertificates(getUrlFromString(keyStore.getIntermediateCertificateUrl())); } } - catch (IOException e) + catch (IOException | GeneralSecurityException e ) { - throw new IllegalArgumentException(e); + throw new IllegalConfigurationException("Cannot validate private key or certificate(s):" + e, e); } } @@ -296,8 +296,7 @@ public class NonJavaKeyStoreImpl extends AbstractConfiguredObject<NonJavaKeyStor } catch (IOException | GeneralSecurityException e) { - LOGGER.error("Error attempting to create KeyStore from private key and certificates", e); - _keyManagers = new KeyManager[0]; + throw new IllegalConfigurationException("Cannot load private key or certificate(s): " + e, e); } } diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStore.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStore.java index f7d970074d..2ae5a329d5 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStore.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStore.java @@ -34,7 +34,7 @@ public interface NonJavaTrustStore<X extends NonJavaTrustStore<X>> extends Trust @ManagedAttribute(defaultValue = "${this:certificateDetails}") String getDescription(); - @ManagedAttribute( mandatory = true ) + @ManagedAttribute( mandatory = true, oversize = true, oversizedAltText = OVER_SIZED_ATTRIBUTE_ALTERNATIVE_TEXT ) String getCertificatesUrl(); enum CertificateDetails diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStoreImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStoreImpl.java index 48594a8320..993d689fb6 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStoreImpl.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStoreImpl.java @@ -261,11 +261,11 @@ public class NonJavaTrustStoreImpl { try { - getUrlFromString(keyStore.getCertificatesUrl()).openStream(); + readCertificates(getUrlFromString(keyStore.getCertificatesUrl())); } - catch (IOException e) + catch (IOException | GeneralSecurityException e) { - throw new IllegalArgumentException(e); + throw new IllegalArgumentException("Cannot validate certificate(s):" + e, e); } } @@ -297,8 +297,7 @@ public class NonJavaTrustStoreImpl } catch (IOException | GeneralSecurityException e) { - LOGGER.error("Error attempting to create KeyStore from private key and certificates", e); - _trustManagers = new TrustManager[0]; + throw new IllegalConfigurationException("Cannot load certificate(s) :" + e, e); } } diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/group/GroupProviderImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/group/GroupProviderImpl.java index 6728ba2fed..ecc166f8fc 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/group/GroupProviderImpl.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/group/GroupProviderImpl.java @@ -30,6 +30,7 @@ import org.apache.qpid.server.model.AbstractConfiguredObject; import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.Group; +import org.apache.qpid.server.model.GroupManagingGroupProvider; import org.apache.qpid.server.model.GroupMember; import org.apache.qpid.server.model.GroupProvider; import org.apache.qpid.server.model.ManagedObject; @@ -38,7 +39,7 @@ import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.StateTransition; @ManagedObject(category = false, type = GroupProviderImpl.CONFIG_TYPE) -public class GroupProviderImpl extends AbstractConfiguredObject<GroupProviderImpl> implements GroupProvider<GroupProviderImpl> +public class GroupProviderImpl extends AbstractConfiguredObject<GroupProviderImpl> implements GroupProvider<GroupProviderImpl>, GroupManagingGroupProvider { public static final String CONFIG_TYPE = "ManagedGroupProvider"; diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecoverer.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecoverer.java index a2d8d21d58..69d94a6710 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecoverer.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecoverer.java @@ -54,7 +54,7 @@ public class BrokerStoreUpgraderAndRecoverer register(new Upgrader_1_1_to_1_2()); register(new Upgrader_1_2_to_1_3()); register(new Upgrader_1_3_to_2_0()); - register(new Upgrader_2_0_to_2_1()); + register(new Upgrader_2_0_to_3_0()); } private void register(StoreUpgraderPhase upgrader) @@ -217,11 +217,11 @@ public class BrokerStoreUpgraderAndRecoverer } } - private class Upgrader_2_0_to_2_1 extends StoreUpgraderPhase + private class Upgrader_2_0_to_3_0 extends StoreUpgraderPhase { - public Upgrader_2_0_to_2_1() + public Upgrader_2_0_to_3_0() { - super("modelVersion", "2.0", "2.1"); + super("modelVersion", "2.0", "3.0"); } @Override @@ -245,10 +245,31 @@ public class BrokerStoreUpgraderAndRecoverer { record = upgradeRootRecord(record); } + else if("KeyStore".equals(record.getType())) + { + record = upgradeKeyStoreRecordIfTypeTheSame(record, "FileKeyStore"); + } + else if("TrustStore".equals(record.getType())) + { + record = upgradeKeyStoreRecordIfTypeTheSame(record, "FileTrustStore"); + } getNextUpgrader().configuredObject(record); } + private ConfiguredObjectRecord upgradeKeyStoreRecordIfTypeTheSame(ConfiguredObjectRecord record, String expectedType) + { + Map<String, Object> attributes = new HashMap<>(record.getAttributes()); + if (expectedType.equals(attributes.get("type"))) + { + Object path = attributes.remove("path"); + attributes.put("storeUrl", path); + record = new ConfiguredObjectRecordImpl(record.getId(), record.getType(), attributes, record.getParents()); + getUpdateMap().put(record.getId(), record); + } + return record; + } + private boolean isAmqpPort(final Map<String, Object> attributes) { Object type = attributes.get(ConfiguredObject.TYPE); diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/VirtualHostStoreUpgraderAndRecoverer.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/VirtualHostStoreUpgraderAndRecoverer.java index cd3ae5fdb7..10d8a5d61c 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/VirtualHostStoreUpgraderAndRecoverer.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/VirtualHostStoreUpgraderAndRecoverer.java @@ -63,7 +63,7 @@ public class VirtualHostStoreUpgraderAndRecoverer register(new Upgrader_0_2_to_0_3()); register(new Upgrader_0_3_to_0_4()); register(new Upgrader_0_4_to_2_0()); - register(new Upgrader_2_0_to_2_1()); + register(new Upgrader_2_0_to_3_0()); Map<String, UUID> defaultExchangeIds = new HashMap<String, UUID>(); for (String exchangeName : DEFAULT_EXCHANGES.keySet()) @@ -483,11 +483,11 @@ public class VirtualHostStoreUpgraderAndRecoverer } - private class Upgrader_2_0_to_2_1 extends StoreUpgraderPhase + private class Upgrader_2_0_to_3_0 extends StoreUpgraderPhase { - public Upgrader_2_0_to_2_1() + public Upgrader_2_0_to_3_0() { - super("modelVersion", "2.0", "2.1"); + super("modelVersion", "2.0", "3.0"); } @Override diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/TCPandSSLTransport.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/TCPandSSLTransport.java index 8970df434a..5f5467db07 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/TCPandSSLTransport.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/TCPandSSLTransport.java @@ -24,6 +24,7 @@ import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS; import java.net.InetSocketAddress; import java.util.EnumSet; +import java.util.Collection; import java.util.Set; import javax.net.ssl.SSLContext; @@ -124,25 +125,37 @@ class TCPandSSLTransport implements AcceptingTransport } @Override + public Collection<String> getEnabledCipherSuites() + { + return _port.getEnabledCipherSuites(); + } + + @Override + public Collection<String> getDisabledCipherSuites() + { + return _port.getDisabledCipherSuites(); + } + + @Override public boolean needClientAuth() { return _port.getNeedClientAuth(); } @Override - public Boolean getTcpNoDelay() + public boolean getTcpNoDelay() { return _port.isTcpNoDelay(); } @Override - public Integer getSendBufferSize() + public int getSendBufferSize() { return _port.getSendBufferSize(); } @Override - public Integer getReceiveBufferSize() + public int getReceiveBufferSize() { return _port.getReceiveBufferSize(); } diff --git a/qpid/java/broker-core/src/main/resources/initial-config.json b/qpid/java/broker-core/src/main/resources/initial-config.json index 012cdc9017..7d88d8fd5c 100644 --- a/qpid/java/broker-core/src/main/resources/initial-config.json +++ b/qpid/java/broker-core/src/main/resources/initial-config.json @@ -20,7 +20,7 @@ */ { "name": "${broker.name}", - "modelVersion": "2.1", + "modelVersion": "3.0", "defaultVirtualHost" : "default", "authenticationproviders" : [ { "name" : "passwordFile", @@ -65,7 +65,7 @@ "virtualhostnodes" : [ { "name" : "default", "type" : "JSON", - "virtualHostInitialConfiguration" : "{ \"type\" : \"DERBY\" }" + "virtualHostInitialConfiguration" : "${qpid.initial_config_virtualhost_config}" } ], "plugins" : [ { "type" : "MANAGEMENT-HTTP", diff --git a/qpid/java/broker-core/src/main/resources/system.properties b/qpid/java/broker-core/src/main/resources/system.properties index 6559636f75..661b0cba77 100644 --- a/qpid/java/broker-core/src/main/resources/system.properties +++ b/qpid/java/broker-core/src/main/resources/system.properties @@ -17,4 +17,4 @@ # under the License. # -qpid.helpURL = http://qpid.apache.org/releases/qpid-${project.version}/java-broker/book + diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/logging/messages/ManagementConsoleMessagesTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/logging/messages/ManagementConsoleMessagesTest.java index dfc9357402..4b4fbb2db6 100644 --- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/logging/messages/ManagementConsoleMessagesTest.java +++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/logging/messages/ManagementConsoleMessagesTest.java @@ -22,6 +22,8 @@ package org.apache.qpid.server.logging.messages; import java.util.List; +import org.apache.qpid.server.model.Transport; + /** * Test MNG Log Messages */ @@ -39,13 +41,13 @@ public class ManagementConsoleMessagesTest extends AbstractTestMessages public void testManagementListening() { - String transport = "JMX"; + String management = "JMX"; Integer port = 8889; - _logMessage = ManagementConsoleMessages.LISTENING(transport, port); + _logMessage = ManagementConsoleMessages.LISTENING(management, Transport.TCP.name(), port); List<Object> log = performLog(); - String[] expected = {"Starting :", transport, ": Listening on port", String.valueOf(port)}; + String[] expected = {"Starting :", management, ": Listening on ", Transport.TCP.name(), " port", String.valueOf(port)}; validateLogMessage(log, "MNG-1002", expected); } @@ -83,16 +85,5 @@ public class ManagementConsoleMessagesTest extends AbstractTestMessages validateLogMessage(log, "MNG-1005", expected); } - public void testManagementSSLKeyStore() - { - String path = "/path/to/the/keystore/files.jks"; - - _logMessage = ManagementConsoleMessages.SSL_KEYSTORE(path); - List<Object> log = performLog(); - - String[] expected = {"Using SSL Keystore :", path}; - - validateLogMessage(log, "MNG-1006", expected); - } } diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/FileKeyStoreTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/FileKeyStoreTest.java index 0e45582d7c..0a2e122d16 100644 --- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/FileKeyStoreTest.java +++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/FileKeyStoreTest.java @@ -69,7 +69,7 @@ public class FileKeyStoreTest extends QpidTestCase { Map<String,Object> attributes = new HashMap<>(); attributes.put(FileKeyStore.NAME, "myFileKeyStore"); - attributes.put(FileKeyStore.PATH, TestSSLConstants.BROKER_KEYSTORE); + attributes.put(FileKeyStore.STORE_URL, TestSSLConstants.BROKER_KEYSTORE); attributes.put(FileKeyStore.PASSWORD, TestSSLConstants.BROKER_KEYSTORE_PASSWORD); FileKeyStoreImpl fileKeyStore = (FileKeyStoreImpl) _factory.create(KeyStore.class, attributes, _broker); @@ -84,7 +84,7 @@ public class FileKeyStoreTest extends QpidTestCase { Map<String,Object> attributes = new HashMap<>(); attributes.put(FileKeyStore.NAME, "myFileKeyStore"); - attributes.put(FileKeyStore.PATH, TestSSLConstants.BROKER_KEYSTORE); + attributes.put(FileKeyStore.STORE_URL, TestSSLConstants.BROKER_KEYSTORE); attributes.put(FileKeyStore.PASSWORD, TestSSLConstants.BROKER_KEYSTORE_PASSWORD); attributes.put(FileKeyStore.CERTIFICATE_ALIAS, TestSSLConstants.BROKER_KEYSTORE_ALIAS); @@ -100,7 +100,7 @@ public class FileKeyStoreTest extends QpidTestCase { Map<String,Object> attributes = new HashMap<>(); attributes.put(FileKeyStore.NAME, "myFileKeyStore"); - attributes.put(FileKeyStore.PATH, TestSSLConstants.BROKER_KEYSTORE); + attributes.put(FileKeyStore.STORE_URL, TestSSLConstants.BROKER_KEYSTORE); attributes.put(FileKeyStore.PASSWORD, "wrong"); try @@ -119,7 +119,7 @@ public class FileKeyStoreTest extends QpidTestCase { Map<String,Object> attributes = new HashMap<>(); attributes.put(FileKeyStore.NAME, "myFileKeyStore"); - attributes.put(FileKeyStore.PATH, TestSSLConstants.KEYSTORE); + attributes.put(FileKeyStore.STORE_URL, TestSSLConstants.KEYSTORE); attributes.put(FileKeyStore.PASSWORD, TestSSLConstants.KEYSTORE_PASSWORD); attributes.put(FileKeyStore.CERTIFICATE_ALIAS, "notknown"); @@ -141,7 +141,7 @@ public class FileKeyStoreTest extends QpidTestCase Map<String,Object> attributes = new HashMap<>(); attributes.put(FileKeyStore.NAME, "myFileKeyStore"); - attributes.put(FileKeyStore.PATH, trustStoreAsDataUrl); + attributes.put(FileKeyStore.STORE_URL, trustStoreAsDataUrl); attributes.put(FileKeyStore.PASSWORD, TestSSLConstants.BROKER_KEYSTORE_PASSWORD); FileKeyStoreImpl fileKeyStore = (FileKeyStoreImpl) _factory.create(KeyStore.class, attributes, _broker); @@ -158,7 +158,7 @@ public class FileKeyStoreTest extends QpidTestCase Map<String,Object> attributes = new HashMap<>(); attributes.put(FileKeyStore.NAME, "myFileKeyStore"); - attributes.put(FileKeyStore.PATH, trustStoreAsDataUrl); + attributes.put(FileKeyStore.STORE_URL, trustStoreAsDataUrl); attributes.put(FileKeyStore.PASSWORD, TestSSLConstants.BROKER_KEYSTORE_PASSWORD); attributes.put(FileKeyStore.CERTIFICATE_ALIAS, TestSSLConstants.BROKER_KEYSTORE_ALIAS); @@ -177,7 +177,7 @@ public class FileKeyStoreTest extends QpidTestCase Map<String,Object> attributes = new HashMap<>(); attributes.put(FileKeyStore.NAME, "myFileKeyStore"); attributes.put(FileKeyStore.PASSWORD, "wrong"); - attributes.put(FileKeyStore.PATH, keyStoreAsDataUrl); + attributes.put(FileKeyStore.STORE_URL, keyStoreAsDataUrl); try { @@ -198,7 +198,7 @@ public class FileKeyStoreTest extends QpidTestCase Map<String,Object> attributes = new HashMap<>(); attributes.put(FileKeyStore.NAME, "myFileKeyStore"); attributes.put(FileKeyStore.PASSWORD, TestSSLConstants.BROKER_KEYSTORE_PASSWORD); - attributes.put(FileKeyStore.PATH, keyStoreAsDataUrl); + attributes.put(FileKeyStore.STORE_URL, keyStoreAsDataUrl); try { @@ -220,7 +220,7 @@ public class FileKeyStoreTest extends QpidTestCase Map<String,Object> attributes = new HashMap<>(); attributes.put(FileKeyStore.NAME, "myFileKeyStore"); attributes.put(FileKeyStore.PASSWORD, TestSSLConstants.BROKER_KEYSTORE_PASSWORD); - attributes.put(FileKeyStore.PATH, keyStoreAsDataUrl); + attributes.put(FileKeyStore.STORE_URL, keyStoreAsDataUrl); attributes.put(FileKeyStore.CERTIFICATE_ALIAS, "notknown"); try @@ -242,7 +242,7 @@ public class FileKeyStoreTest extends QpidTestCase Map<String,Object> attributes = new HashMap<>(); attributes.put(FileKeyStore.NAME, "myFileKeyStore"); - attributes.put(FileKeyStore.PATH, TestSSLConstants.BROKER_KEYSTORE); + attributes.put(FileKeyStore.STORE_URL, TestSSLConstants.BROKER_KEYSTORE); attributes.put(FileKeyStore.PASSWORD, TestSSLConstants.BROKER_KEYSTORE_PASSWORD); FileKeyStoreImpl fileKeyStore = (FileKeyStoreImpl) _factory.create(KeyStore.class, attributes, _broker); @@ -283,7 +283,7 @@ public class FileKeyStoreTest extends QpidTestCase Map<String,Object> attributes = new HashMap<>(); attributes.put(FileKeyStore.NAME, "myFileKeyStore"); - attributes.put(FileKeyStore.PATH, TestSSLConstants.BROKER_KEYSTORE); + attributes.put(FileKeyStore.STORE_URL, TestSSLConstants.BROKER_KEYSTORE); attributes.put(FileKeyStore.PASSWORD, TestSSLConstants.BROKER_KEYSTORE_PASSWORD); FileKeyStoreImpl fileKeyStore = (FileKeyStoreImpl) _factory.create(KeyStore.class, attributes, _broker); @@ -299,7 +299,7 @@ public class FileKeyStoreTest extends QpidTestCase Map<String,Object> attributes = new HashMap<>(); attributes.put(FileKeyStore.NAME, "myFileKeyStore"); - attributes.put(FileKeyStore.PATH, TestSSLConstants.BROKER_KEYSTORE); + attributes.put(FileKeyStore.STORE_URL, TestSSLConstants.BROKER_KEYSTORE); attributes.put(FileKeyStore.PASSWORD, TestSSLConstants.BROKER_KEYSTORE_PASSWORD); FileKeyStoreImpl fileKeyStore = (FileKeyStoreImpl) _factory.create(KeyStore.class, attributes, _broker); diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/FileTrustStoreTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/FileTrustStoreTest.java index d965549cdd..72c8926f85 100644 --- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/FileTrustStoreTest.java +++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/FileTrustStoreTest.java @@ -73,7 +73,7 @@ public class FileTrustStoreTest extends QpidTestCase { Map<String,Object> attributes = new HashMap<>(); attributes.put(FileTrustStore.NAME, "myFileTrustStore"); - attributes.put(FileTrustStore.PATH, TestSSLConstants.TRUSTSTORE); + attributes.put(FileTrustStore.STORE_URL, TestSSLConstants.TRUSTSTORE); attributes.put(FileTrustStore.PASSWORD, TestSSLConstants.TRUSTSTORE_PASSWORD); FileTrustStoreImpl fileTrustStore = @@ -89,7 +89,7 @@ public class FileTrustStoreTest extends QpidTestCase { Map<String,Object> attributes = new HashMap<>(); attributes.put(FileTrustStore.NAME, "myFileTrustStore"); - attributes.put(FileTrustStore.PATH, TestSSLConstants.TRUSTSTORE); + attributes.put(FileTrustStore.STORE_URL, TestSSLConstants.TRUSTSTORE); attributes.put(FileTrustStore.PASSWORD, "wrong"); try @@ -108,7 +108,7 @@ public class FileTrustStoreTest extends QpidTestCase { Map<String,Object> attributes = new HashMap<>(); attributes.put(FileTrustStore.NAME, "myFileTrustStore"); - attributes.put(FileTrustStore.PATH, TestSSLConstants.BROKER_PEERSTORE); + attributes.put(FileTrustStore.STORE_URL, TestSSLConstants.BROKER_PEERSTORE); attributes.put(FileTrustStore.PASSWORD, TestSSLConstants.BROKER_PEERSTORE_PASSWORD); attributes.put(FileTrustStore.PEERS_ONLY, true); @@ -129,7 +129,7 @@ public class FileTrustStoreTest extends QpidTestCase Map<String,Object> attributes = new HashMap<>(); attributes.put(FileTrustStore.NAME, "myFileTrustStore"); - attributes.put(FileTrustStore.PATH, trustStoreAsDataUrl); + attributes.put(FileTrustStore.STORE_URL, trustStoreAsDataUrl); attributes.put(FileTrustStore.PASSWORD, TestSSLConstants.TRUSTSTORE_PASSWORD); FileTrustStoreImpl fileTrustStore = @@ -148,7 +148,7 @@ public class FileTrustStoreTest extends QpidTestCase Map<String,Object> attributes = new HashMap<>(); attributes.put(FileTrustStore.NAME, "myFileTrustStore"); attributes.put(FileTrustStore.PASSWORD, "wrong"); - attributes.put(FileTrustStore.PATH, trustStoreAsDataUrl); + attributes.put(FileTrustStore.STORE_URL, trustStoreAsDataUrl); try { @@ -169,7 +169,7 @@ public class FileTrustStoreTest extends QpidTestCase Map<String,Object> attributes = new HashMap<>(); attributes.put(FileTrustStore.NAME, "myFileTrustStore"); attributes.put(FileTrustStore.PASSWORD, TestSSLConstants.TRUSTSTORE_PASSWORD); - attributes.put(FileTrustStore.PATH, trustStoreAsDataUrl); + attributes.put(FileTrustStore.STORE_URL, trustStoreAsDataUrl); try { @@ -191,18 +191,18 @@ public class FileTrustStoreTest extends QpidTestCase Map<String,Object> attributes = new HashMap<>(); attributes.put(FileTrustStore.NAME, "myFileTrustStore"); - attributes.put(FileTrustStore.PATH, TestSSLConstants.TRUSTSTORE); + attributes.put(FileTrustStore.STORE_URL, TestSSLConstants.TRUSTSTORE); attributes.put(FileTrustStore.PASSWORD, TestSSLConstants.TRUSTSTORE_PASSWORD); FileTrustStoreImpl fileTrustStore = (FileTrustStoreImpl) _factory.create(TrustStore.class, attributes, _broker); - assertEquals("Unexpected path value before change", TestSSLConstants.TRUSTSTORE, fileTrustStore.getPath()); + assertEquals("Unexpected path value before change", TestSSLConstants.TRUSTSTORE, fileTrustStore.getStoreUrl()); try { Map<String,Object> unacceptableAttributes = new HashMap<>(); - unacceptableAttributes.put(FileTrustStore.PATH, "/not/a/truststore"); + unacceptableAttributes.put(FileTrustStore.STORE_URL, "/not/a/truststore"); fileTrustStore.setAttributes(unacceptableAttributes); fail("Exception not thrown"); @@ -213,17 +213,17 @@ public class FileTrustStoreTest extends QpidTestCase assertTrue("Exception text not as unexpected:" + message, message.contains("Cannot instantiate trust store")); } - assertEquals("Unexpected path value after failed change", TestSSLConstants.TRUSTSTORE, fileTrustStore.getPath()); + assertEquals("Unexpected path value after failed change", TestSSLConstants.TRUSTSTORE, fileTrustStore.getStoreUrl()); Map<String,Object> changedAttributes = new HashMap<>(); - changedAttributes.put(FileTrustStore.PATH, TestSSLConstants.BROKER_TRUSTSTORE); + changedAttributes.put(FileTrustStore.STORE_URL, TestSSLConstants.BROKER_TRUSTSTORE); changedAttributes.put(FileTrustStore.PASSWORD, TestSSLConstants.BROKER_TRUSTSTORE_PASSWORD); fileTrustStore.setAttributes(changedAttributes); assertEquals("Unexpected path value after change that is expected to be successful", TestSSLConstants.BROKER_TRUSTSTORE, - fileTrustStore.getPath()); + fileTrustStore.getStoreUrl()); } public void testDeleteTrustStore_Success() throws Exception @@ -233,7 +233,7 @@ public class FileTrustStoreTest extends QpidTestCase Map<String,Object> attributes = new HashMap<>(); attributes.put(FileTrustStore.NAME, "myFileTrustStore"); - attributes.put(FileTrustStore.PATH, TestSSLConstants.TRUSTSTORE); + attributes.put(FileTrustStore.STORE_URL, TestSSLConstants.TRUSTSTORE); attributes.put(FileTrustStore.PASSWORD, TestSSLConstants.TRUSTSTORE_PASSWORD); FileTrustStoreImpl fileTrustStore = @@ -250,7 +250,7 @@ public class FileTrustStoreTest extends QpidTestCase Map<String,Object> attributes = new HashMap<>(); attributes.put(FileTrustStore.NAME, "myFileTrustStore"); - attributes.put(FileTrustStore.PATH, TestSSLConstants.TRUSTSTORE); + attributes.put(FileTrustStore.STORE_URL, TestSSLConstants.TRUSTSTORE); attributes.put(FileTrustStore.PASSWORD, TestSSLConstants.TRUSTSTORE_PASSWORD); FileTrustStoreImpl fileTrustStore = @@ -281,7 +281,7 @@ public class FileTrustStoreTest extends QpidTestCase Map<String,Object> attributes = new HashMap<>(); attributes.put(FileTrustStore.NAME, "myFileTrustStore"); - attributes.put(FileTrustStore.PATH, TestSSLConstants.TRUSTSTORE); + attributes.put(FileTrustStore.STORE_URL, TestSSLConstants.TRUSTSTORE); attributes.put(FileTrustStore.PASSWORD, TestSSLConstants.TRUSTSTORE_PASSWORD); FileTrustStoreImpl fileTrustStore = diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/NonJavaKeyStoreTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/NonJavaKeyStoreTest.java new file mode 100644 index 0000000000..f8d4ee8d6c --- /dev/null +++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/NonJavaKeyStoreTest.java @@ -0,0 +1,220 @@ +/* + * 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; + + +import static org.apache.qpid.test.utils.TestSSLConstants.KEYSTORE_PASSWORD; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import javax.net.ssl.KeyManager; +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.security.Key; +import java.security.cert.Certificate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.codec.binary.Base64; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.BrokerModel; +import org.apache.qpid.server.model.ConfiguredObjectFactory; +import org.apache.qpid.server.model.KeyStore; +import org.apache.qpid.server.model.Model; +import org.apache.qpid.test.utils.QpidTestCase; +import org.apache.qpid.test.utils.TestFileUtils; + +public class NonJavaKeyStoreTest extends QpidTestCase +{ + private final Broker<?> _broker = mock(Broker.class); + private final TaskExecutor _taskExecutor = CurrentThreadTaskExecutor.newStartedInstance(); + private final SecurityManager _securityManager = mock(SecurityManager.class); + private final Model _model = BrokerModel.getInstance(); + private final ConfiguredObjectFactory _factory = _model.getObjectFactory(); + private List<File> _testResources; + + @Override + public void setUp() throws Exception + { + super.setUp(); + + when(_broker.getTaskExecutor()).thenReturn(_taskExecutor); + when(_broker.getModel()).thenReturn(_model); + when(_broker.getSecurityManager()).thenReturn(_securityManager); + _testResources = new ArrayList<>(); + } + + @Override + public void tearDown() throws Exception + { + try + { + super.tearDown(); + } + finally + { + for (File resource: _testResources) + { + try + { + resource.delete(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + } + } + + private File[] extractResourcesFromTestKeyStore(boolean pem) throws Exception + { + java.security.KeyStore ks = java.security.KeyStore.getInstance(java.security.KeyStore.getDefaultType()); + try(InputStream is = getClass().getResourceAsStream("/java_broker_keystore.jks")) + { + ks.load(is, KEYSTORE_PASSWORD.toCharArray() ); + } + + + File privateKeyFile = TestFileUtils.createTempFile(this, ".private-key.der"); + try(FileOutputStream kos = new FileOutputStream(privateKeyFile)) + { + Key pvt = ks.getKey("java-broker", KEYSTORE_PASSWORD.toCharArray()); + if (pem) + { + kos.write("-----BEGIN PRIVATE KEY-----\n".getBytes()); + kos.write(Base64.encodeBase64(pvt.getEncoded(), true)); + kos.write("\n-----END PRIVATE KEY-----".getBytes()); + } + else + { + kos.write(pvt.getEncoded()); + } + kos.flush(); + } + + File certificateFile = TestFileUtils.createTempFile(this, ".certificate.der"); + + try(FileOutputStream cos = new FileOutputStream(certificateFile)) + { + Certificate pub = ks.getCertificate("rootca"); + if (pem) + { + cos.write("-----BEGIN CERTIFICATE-----\n".getBytes()); + cos.write(Base64.encodeBase64(pub.getEncoded(), true)); + cos.write("\n-----END CERTIFICATE-----".getBytes()); + } + else + { + cos.write(pub.getEncoded()); + } + cos.flush(); + } + + return new File[]{privateKeyFile,certificateFile}; + } + + public void testCreationOfTrustStoreFromValidPrivateKeyAndCertificateInDERFormat() throws Exception + { + runTestCreationOfTrustStoreFromValidPrivateKeyAndCertificateInDerFormat(false); + } + + public void testCreationOfTrustStoreFromValidPrivateKeyAndCertificateInPEMFormat() throws Exception + { + runTestCreationOfTrustStoreFromValidPrivateKeyAndCertificateInDerFormat(true); + } + + private void runTestCreationOfTrustStoreFromValidPrivateKeyAndCertificateInDerFormat(boolean isPEM)throws Exception + { + File[] resources = extractResourcesFromTestKeyStore(isPEM); + _testResources.addAll(Arrays.asList(resources)); + + Map<String,Object> attributes = new HashMap<>(); + attributes.put(NonJavaKeyStore.NAME, "myTestTrustStore"); + attributes.put("privateKeyUrl", resources[0].toURI().toURL().toExternalForm()); + attributes.put("certificateUrl", resources[1].toURI().toURL().toExternalForm()); + attributes.put(NonJavaKeyStore.TYPE, "NonJavaKeyStore"); + + NonJavaKeyStoreImpl fileTrustStore = + (NonJavaKeyStoreImpl) _factory.create(KeyStore.class, attributes, _broker); + + KeyManager[] keyManagers = fileTrustStore.getKeyManagers(); + assertNotNull(keyManagers); + assertEquals("Unexpected number of key managers", 1, keyManagers.length); + assertNotNull("Key manager is null", keyManagers[0]); + } + + public void testCreationOfTrustStoreFromValidPrivateKeyAndInvalidCertificate()throws Exception + { + File[] resources = extractResourcesFromTestKeyStore(true); + _testResources.addAll(Arrays.asList(resources)); + + File invalidCertificate = TestFileUtils.createTempFile(this, ".invalid.cert", "content"); + _testResources.add(invalidCertificate); + + Map<String,Object> attributes = new HashMap<>(); + attributes.put(NonJavaKeyStore.NAME, "myTestTrustStore"); + attributes.put("privateKeyUrl", resources[0].toURI().toURL().toExternalForm()); + attributes.put("certificateUrl", invalidCertificate.toURI().toURL().toExternalForm()); + attributes.put(NonJavaKeyStore.TYPE, "NonJavaKeyStore"); + + try + { + _factory.create(KeyStore.class, attributes, _broker); + fail("Created key store from invalid certificate"); + } + catch(IllegalConfigurationException e) + { + // pass + } + } + + public void testCreationOfTrustStoreFromInvalidPrivateKeyAndValidCertificate()throws Exception + { + File[] resources = extractResourcesFromTestKeyStore(true); + _testResources.addAll(Arrays.asList(resources)); + + File invalidPrivateKey = TestFileUtils.createTempFile(this, ".invalid.pk", "content"); + _testResources.add(invalidPrivateKey); + + Map<String,Object> attributes = new HashMap<>(); + attributes.put(NonJavaKeyStore.NAME, "myTestTrustStore"); + attributes.put("privateKeyUrl", invalidPrivateKey.toURI().toURL().toExternalForm()); + attributes.put("certificateUrl", resources[1].toURI().toURL().toExternalForm()); + attributes.put(NonJavaKeyStore.TYPE, "NonJavaKeyStore"); + + try + { + _factory.create(KeyStore.class, attributes, _broker); + fail("Created key store from invalid certificate"); + } + catch(IllegalConfigurationException e) + { + // pass + } + } +} diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/NonJavaTrustStoreTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/NonJavaTrustStoreTest.java new file mode 100644 index 0000000000..798d9fcbe5 --- /dev/null +++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/NonJavaTrustStoreTest.java @@ -0,0 +1,92 @@ +/* + * 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; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import javax.net.ssl.TrustManager; +import java.util.HashMap; +import java.util.Map; + +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.BrokerModel; +import org.apache.qpid.server.model.ConfiguredObjectFactory; +import org.apache.qpid.server.model.Model; +import org.apache.qpid.server.model.TrustStore; +import org.apache.qpid.test.utils.QpidTestCase; + + +public class NonJavaTrustStoreTest extends QpidTestCase +{ + private final Broker<?> _broker = mock(Broker.class); + private final TaskExecutor _taskExecutor = CurrentThreadTaskExecutor.newStartedInstance(); + private final SecurityManager _securityManager = mock(SecurityManager.class); + private final Model _model = BrokerModel.getInstance(); + private final ConfiguredObjectFactory _factory = _model.getObjectFactory(); + + @Override + public void setUp() throws Exception + { + super.setUp(); + + when(_broker.getTaskExecutor()).thenReturn(_taskExecutor); + when(_broker.getModel()).thenReturn(_model); + when(_broker.getSecurityManager()).thenReturn(_securityManager); + } + + public void testCreationOfTrustStoreFromValidCertificate() throws Exception + { + Map<String,Object> attributes = new HashMap<>(); + attributes.put(NonJavaTrustStore.NAME, "myTestTrustStore"); + attributes.put("certificatesUrl", getClass().getResource("/java_broker.crt").toExternalForm()); + attributes.put(NonJavaTrustStore.TYPE, "NonJavaTrustStore"); + + NonJavaTrustStoreImpl fileTrustStore = + (NonJavaTrustStoreImpl) _factory.create(TrustStore.class, attributes, _broker); + + TrustManager[] trustManagers = fileTrustStore.getTrustManagers(); + assertNotNull(trustManagers); + assertEquals("Unexpected number of trust managers", 1, trustManagers.length); + assertNotNull("Trust manager unexpected null", trustManagers[0]); + } + + public void testCreationOfTrustStoreFromNonCertificate() throws Exception + { + Map<String,Object> attributes = new HashMap<>(); + attributes.put(NonJavaTrustStore.NAME, "myTestTrustStore"); + attributes.put("certificatesUrl", getClass().getResource("/java_broker.req").toExternalForm()); + attributes.put(NonJavaTrustStore.TYPE, "NonJavaTrustStore"); + + try + { + _factory.create(TrustStore.class, attributes, _broker); + fail("Trust store is created from certificate request file"); + } + catch (IllegalConfigurationException e) + { + // pass + } + } + +} diff --git a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProvider.java b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProvider.java index b8509ebd39..3e0f5b63f0 100644 --- a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProvider.java +++ b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProvider.java @@ -27,6 +27,6 @@ import org.apache.qpid.server.model.ManagedObject; @ManagedObject( category = false, type="AclFile" ) public interface ACLFileAccessControlProvider<X extends ACLFileAccessControlProvider<X>> extends AccessControlProvider<X> { - @ManagedAttribute( mandatory = true, description = "File location" ) + @ManagedAttribute( mandatory = true, description = "File location", oversize = true, oversizedAltText = OVER_SIZED_ATTRIBUTE_ALTERNATIVE_TEXT) String getPath(); } 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 f7f65e29c2..a149214455 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 @@ -3256,17 +3256,6 @@ public class AMQChannel + autoDelete + ")"); } - else if (queue.isDurable() != durable) - { - closeChannel(AMQConstant.ALREADY_EXISTS, - "Cannot re-declare queue '" - + queue.getName() - + "' with different durability (was: " - + queue.isDurable() - + " requested " - + durable - + ")"); - } else { setDefaultQueue(queue); diff --git a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolEngine.java b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolEngine.java index 1aa4ef0b3f..233f68aeb6 100644 --- a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolEngine.java +++ b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolEngine.java @@ -96,6 +96,16 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQConnectionModel<AMQProtocolEngine, AMQChannel>, ServerMethodProcessor<ServerChannelMethodProcessor> { + enum ConnectionState + { + INIT, + AWAIT_START_OK, + AWAIT_SECURE_OK, + AWAIT_TUNE_OK, + AWAIT_OPEN, + OPEN + } + private static final Logger _logger = Logger.getLogger(AMQProtocolEngine.class); // to save boxing the channelId and looking up in a map... cache in an array the low numbered @@ -123,6 +133,8 @@ public class AMQProtocolEngine implements ServerProtocolEngine, private final AMQChannel[] _cachedChannels = new AMQChannel[CHANNEL_CACHE_SIZE + 1]; + private ConnectionState _state = ConnectionState.INIT; + /** * The channels that the latest call to {@link #received(ByteBuffer)} applied to. * Used so we know which channels we need to call {@link AMQChannel#receivedComplete()} @@ -486,14 +498,9 @@ public class AMQProtocolEngine implements ServerProtocolEngine, serverProperties, mechanisms.getBytes(), locales.getBytes()); - try - { - responseBody.generateFrame(0).writePayload(_sender); - } - catch (IOException e) - { - throw new ServerScopedRuntimeException(e); - } + writeFrame(responseBody.generateFrame(0)); + _state = ConnectionState.AWAIT_START_OK; + _sender.flush(); } @@ -501,14 +508,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, { _logger.info("Received unsupported protocol initiation for protocol version: " + getProtocolVersion()); - try - { - new ProtocolInitiation(ProtocolVersion.getLatestSupportedVersion()).writePayload(_sender); - } - catch (IOException ioex) - { - throw new ServerScopedRuntimeException(ioex); - } + writeFrame(new ProtocolInitiation(ProtocolVersion.getLatestSupportedVersion())); _sender.flush(); } } @@ -1498,6 +1498,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, { _logger.debug("RECV[" + channelId + "] ChannelOpen"); } + assertState(ConnectionState.OPEN); // Protect the broker against out of order frame request. if (_virtualHost == null) @@ -1534,6 +1535,15 @@ public class AMQProtocolEngine implements ServerProtocolEngine, } } + void assertState(final ConnectionState requiredState) + { + if(_state != requiredState) + { + closeConnection(AMQConstant.COMMAND_INVALID, "Command Invalid", 0); + + } + } + @Override public void receiveConnectionOpen(AMQShortString virtualHostName, AMQShortString capabilities, @@ -1586,6 +1596,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQMethodBody responseBody = methodRegistry.createConnectionOpenOkBody(virtualHostName); writeFrame(responseBody.generateFrame(0)); + _state = ConnectionState.OPEN; } catch (AccessControlException e) { @@ -1656,6 +1667,8 @@ public class AMQProtocolEngine implements ServerProtocolEngine, _logger.debug("RECV ConnectionSecureOk[ response: ******** ] "); } + assertState(ConnectionState.AWAIT_SECURE_OK); + Broker<?> broker = getBroker(); SubjectCreator subjectCreator = getSubjectCreator(); @@ -1696,6 +1709,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, frameMax, broker.getConnection_heartBeatDelay()); writeFrame(tuneBody.generateFrame(0)); + _state = ConnectionState.AWAIT_TUNE_OK; setAuthorizedSubject(authResult.getSubject()); disposeSaslServer(); break; @@ -1744,6 +1758,8 @@ public class AMQProtocolEngine implements ServerProtocolEngine, + " ]"); } + assertState(ConnectionState.AWAIT_START_OK); + Broker<?> broker = getBroker(); _logger.info("SASL Mechanism selected: " + mechanism); @@ -1805,11 +1821,14 @@ public class AMQProtocolEngine implements ServerProtocolEngine, frameMax, broker.getConnection_heartBeatDelay()); writeFrame(tuneBody.generateFrame(0)); + _state = ConnectionState.AWAIT_TUNE_OK; break; case CONTINUE: ConnectionSecureBody secureBody = methodRegistry.createConnectionSecureBody(authResult.getChallenge()); writeFrame(secureBody.generateFrame(0)); + + _state = ConnectionState.AWAIT_SECURE_OK; } } } @@ -1828,6 +1847,8 @@ public class AMQProtocolEngine implements ServerProtocolEngine, _logger.debug("RECV ConnectionTuneOk[" +" channelMax: " + channelMax + " frameMax: " + frameMax + " heartbeat: " + heartbeat + " ]"); } + assertState(ConnectionState.AWAIT_TUNE_OK); + initHeartbeats(heartbeat); int brokerFrameMax = getBroker().getContextValue(Integer.class, Broker.BROKER_FRAME_SIZE); @@ -1859,7 +1880,10 @@ public class AMQProtocolEngine implements ServerProtocolEngine, setMaximumNumberOfChannels( ((channelMax == 0l) || (channelMax > 0xFFFFL)) ? 0xFFFFL : channelMax); + } + _state = ConnectionState.AWAIT_OPEN; + } public int getBinaryDataLimit() @@ -1959,6 +1983,8 @@ public class AMQProtocolEngine implements ServerProtocolEngine, @Override public ServerChannelMethodProcessor getChannelMethodProcessor(final int channelId) { + assertState(ConnectionState.OPEN); + ServerChannelMethodProcessor channelMethodProcessor = getChannel(channelId); if(channelMethodProcessor == null) { diff --git a/qpid/java/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/InternalTestProtocolSession.java b/qpid/java/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/InternalTestProtocolSession.java index 0f198a8d46..f8098eb2ec 100644 --- a/qpid/java/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/InternalTestProtocolSession.java +++ b/qpid/java/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/InternalTestProtocolSession.java @@ -276,6 +276,12 @@ public class InternalTestProtocolSession extends AMQProtocolEngine implements Pr } } + void assertState(final ConnectionState requiredState) + { + // no-op + } + + private static final AtomicInteger portNumber = new AtomicInteger(0); private static class TestNetworkConnection implements NetworkConnection diff --git a/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/ConsumerTarget_1_0.java b/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/ConsumerTarget_1_0.java index b5e1bdafbb..a44768ffdc 100644 --- a/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/ConsumerTarget_1_0.java +++ b/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/ConsumerTarget_1_0.java @@ -347,6 +347,11 @@ class ConsumerTarget_1_0 extends AbstractConsumerTarget return _link.getSession(); } + public void flush() + { + _consumer.flush(); + } + private class DispositionAction implements UnsettledAction { diff --git a/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java b/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java index 36796851e0..18f5ba9e2e 100644 --- a/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java +++ b/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java @@ -21,23 +21,42 @@ package org.apache.qpid.server.protocol.v1_0; +import java.lang.ref.SoftReference; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; + import org.apache.qpid.server.message.AbstractServerMessageImpl; import org.apache.qpid.server.store.StoredMessage; public class Message_1_0 extends AbstractServerMessageImpl<Message_1_0, MessageMetaData_1_0> { - private List<ByteBuffer> _fragments; + private volatile SoftReference<List<ByteBuffer>> _fragmentsRef; private long _arrivalTime; + private final long _size; public Message_1_0(final StoredMessage<MessageMetaData_1_0> storedMessage) { super(storedMessage, null); - _fragments = restoreFragments(storedMessage); + final List<ByteBuffer> fragments = restoreFragments(getStoredMessage()); + _fragmentsRef = new SoftReference<>(fragments); + _size = calculateSize(fragments); + } + + private long calculateSize(final List<ByteBuffer> fragments) + { + + long size = 0l; + if(fragments != null) + { + for(ByteBuffer buf : fragments) + { + size += buf.remaining(); + } + } + return size; } private static List<ByteBuffer> restoreFragments(StoredMessage<MessageMetaData_1_0> storedMessage) @@ -65,7 +84,8 @@ public class Message_1_0 extends AbstractServerMessageImpl<Message_1_0, MessageM final Object connectionReference) { super(storedMessage, connectionReference); - _fragments = fragments; + _fragmentsRef = new SoftReference<>(fragments); + _size = calculateSize(fragments); _arrivalTime = System.currentTimeMillis(); } @@ -94,16 +114,7 @@ public class Message_1_0 extends AbstractServerMessageImpl<Message_1_0, MessageM public long getSize() { - long size = 0l; - if(_fragments != null) - { - for(ByteBuffer buf : _fragments) - { - size += buf.remaining(); - } - } - - return size; + return _size; } public long getExpiration() @@ -118,7 +129,14 @@ public class Message_1_0 extends AbstractServerMessageImpl<Message_1_0, MessageM public List<ByteBuffer> getFragments() { - return _fragments; + + List<ByteBuffer> fragments = _fragmentsRef.get(); + if(fragments == null) + { + fragments = restoreFragments(getStoredMessage()); + _fragmentsRef = new SoftReference<>(fragments); + } + return fragments; } } diff --git a/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLink_1_0.java b/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLink_1_0.java index f8e4853099..48ff420965 100644 --- a/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLink_1_0.java +++ b/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLink_1_0.java @@ -496,6 +496,7 @@ public class SendingLink_1_0 implements SendingLinkListener, Link_1_0, DeliveryS && hasCredit()) { _draining = true; + _target.flush(); } while(!_resumeAcceptedTransfers.isEmpty() && getEndpoint().hasCreditToSend()) diff --git a/qpid/java/broker-plugins/management-http/pom.xml b/qpid/java/broker-plugins/management-http/pom.xml index 47066874ed..50ff3e20f3 100644 --- a/qpid/java/broker-plugins/management-http/pom.xml +++ b/qpid/java/broker-plugins/management-http/pom.xml @@ -29,6 +29,10 @@ <name>Qpid HTTP Management Broker Plug-in</name> <description>HTTP Management broker plug-in</description> + <properties> + <dojo-version>1.10.3</dojo-version> + </properties> + <dependencies> <dependency> <groupId>org.apache.qpid</groupId> @@ -84,6 +88,7 @@ <groupId>org.dojotoolkit</groupId> <artifactId>dojo</artifactId> <version>${dojo-version}</version> + <classifier>distribution</classifier> <type>zip</type> </dependency> @@ -124,7 +129,7 @@ it gets picked up when using classpath wildcard expansion, which only collects .jar files --> <manifestEntries> - <Class-Path>dojo-${dojo-version}.zip</Class-Path> + <Class-Path>dojo-${dojo-version}-distribution.zip</Class-Path> </manifestEntries> </archive> </configuration> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java index 7b3e06f7fe..4e340c7b72 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java +++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java @@ -46,7 +46,6 @@ import org.eclipse.jetty.server.SessionManager; import org.eclipse.jetty.server.handler.ErrorHandler; import org.eclipse.jetty.server.nio.SelectChannelConnector; import org.eclipse.jetty.server.ssl.SslSelectChannelConnector; -import org.eclipse.jetty.server.ssl.SslSocketConnector; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; @@ -139,7 +138,7 @@ public class HttpManagement extends AbstractPluginAdapter<HttpManagement> implem try { _server.start(); - logOperationalListenMessages(_server); + logOperationalListenMessages(httpPorts); } catch (Exception e) { @@ -352,6 +351,17 @@ public class HttpManagement extends AbstractPluginAdapter<HttpManagement> implem } SslContextFactory factory = new SslContextFactory(); factory.addExcludeProtocols(SSLUtil.SSLV3_PROTOCOL); + + if(port.getDisabledCipherSuites() != null) + { + factory.addExcludeCipherSuites(port.getDisabledCipherSuites().toArray(new String[port.getDisabledCipherSuites().size()])); + } + + if(port.getEnabledCipherSuites() != null && !port.getEnabledCipherSuites().isEmpty()) + { + factory.setIncludeCipherSuites(port.getEnabledCipherSuites().toArray(new String[port.getEnabledCipherSuites().size()])); + } + boolean needClientCert = port.getNeedClientAuth() || port.getWantClientAuth(); if (needClientCert && trustStores.isEmpty()) @@ -437,20 +447,14 @@ public class HttpManagement extends AbstractPluginAdapter<HttpManagement> implem root.addServlet(servletHolder, "/api/v" + BrokerModel.MODEL_MAJOR_VERSION + "/" + name + "/*"); } - private void logOperationalListenMessages(Server server) + private void logOperationalListenMessages(Collection<Port<?>> ports) { - Connector[] connectors = server.getConnectors(); - for (Connector connector : connectors) + for (Port port : ports) { - getBroker().getEventLogger().message(ManagementConsoleMessages.LISTENING(stringifyConnectorScheme(connector), - connector.getPort())); - if (connector instanceof SslSocketConnector) + Set<Transport> transports = port.getTransports(); + for (Transport transport: transports) { - SslContextFactory sslContextFactory = ((SslSocketConnector)connector).getSslContextFactory(); - if (sslContextFactory != null && sslContextFactory.getKeyStorePath() != null) - { - getBroker().getEventLogger().message(ManagementConsoleMessages.SSL_KEYSTORE(sslContextFactory.getKeyStorePath())); - } + getBroker().getEventLogger().message(ManagementConsoleMessages.LISTENING(Protocol.HTTP.name(), transport.name(), port.getPort())); } } } @@ -460,15 +464,10 @@ public class HttpManagement extends AbstractPluginAdapter<HttpManagement> implem Connector[] connectors = server.getConnectors(); for (Connector connector : connectors) { - getBroker().getEventLogger().message(ManagementConsoleMessages.SHUTTING_DOWN(stringifyConnectorScheme(connector), - connector.getPort())); + getBroker().getEventLogger().message(ManagementConsoleMessages.SHUTTING_DOWN(Protocol.HTTP.name(), connector.getPort())); } } - private String stringifyConnectorScheme(Connector connector) - { - return connector instanceof SslSocketConnector ? "HTTPS" : "HTTP"; - } private Collection<Port<?>> getHttpPorts(Collection<Port<?>> ports) { diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementConfiguration.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementConfiguration.java index 445ce996ef..018b23daaf 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementConfiguration.java +++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementConfiguration.java @@ -45,6 +45,10 @@ public interface HttpManagementConfiguration<X extends HttpManagementConfigurati @ManagedAttribute( defaultValue = "600" ) public int getSessionTimeout(); + String QPID_HELP_URL = "qpid.helpURL"; + @ManagedContextDefault(name = QPID_HELP_URL) + String DEFAULT_HELP_URL = "http://qpid.apache.org/releases/qpid-${qpid.version}/java-broker/book"; + String HTTP_MANAGEMENT_COMPRESS_RESPONSES = "httpManagement.compressResponses"; @ManagedContextDefault(name = HTTP_MANAGEMENT_COMPRESS_RESPONSES) boolean DEFAULT_COMPRESS_RESPONSES = false; diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/ConfiguredObjectToMapConverter.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/ConfiguredObjectToMapConverter.java index 7d86bd3c8c..331b50ea7c 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/ConfiguredObjectToMapConverter.java +++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/ConfiguredObjectToMapConverter.java @@ -54,23 +54,17 @@ public class ConfiguredObjectToMapConverter Class<? extends ConfiguredObject> clazz, int depth, final boolean useActualValues, - final boolean includeSystemContext, - final boolean extractAsConfig) - { - return convertObjectToMap(confObject, clazz, depth, useActualValues, false, includeSystemContext, extractAsConfig); - } - - public Map<String, Object> convertObjectToMap(final ConfiguredObject<?> confObject, - Class<? extends ConfiguredObject> clazz, - int depth, - final boolean useActualValues, final boolean inheritedActuals, final boolean includeSystemContext, - final boolean extractAsConfig) + final boolean extractAsConfig, + final int oversizeThreshold, + final boolean isSecureTransport + ) { Map<String, Object> object = new LinkedHashMap<>(); - incorporateAttributesIntoMap(confObject, object, useActualValues, inheritedActuals, includeSystemContext, extractAsConfig); + incorporateAttributesIntoMap(confObject, object, useActualValues, inheritedActuals, includeSystemContext, + extractAsConfig, oversizeThreshold, isSecureTransport); if(!extractAsConfig) { incorporateStatisticsIntoMap(confObject, object); @@ -78,7 +72,8 @@ public class ConfiguredObjectToMapConverter if(depth > 0) { - incorporateChildrenIntoMap(confObject, clazz, depth, object, useActualValues, inheritedActuals, includeSystemContext, extractAsConfig); + incorporateChildrenIntoMap(confObject, clazz, depth, object, useActualValues, inheritedActuals, + includeSystemContext, extractAsConfig, oversizeThreshold, isSecureTransport); } return object; } @@ -90,7 +85,9 @@ public class ConfiguredObjectToMapConverter final boolean useActualValues, final boolean inheritedActuals, final boolean includeSystemContext, - final boolean extractAsConfig) + final boolean extractAsConfig, + final int oversizeThreshold, + final boolean isSecureTransport) { // if extracting as config add a fake attribute for each secondary parent if(extractAsConfig && confObject.getModel().getParentTypes(confObject.getCategoryClass()).size()>1) @@ -160,7 +157,39 @@ public class ConfiguredObjectToMapConverter } else if (value != null) { - object.put(name, value); + ConfiguredObjectAttribute<?, ?> attribute = confObject.getModel() + .getTypeRegistry() + .getAttributeTypes(confObject.getClass()) + .get(name); + + if (attribute.isSecure() && !(isSecureTransport && extractAsConfig)) + { + // do not expose actual secure attribute value + // getAttribute() returns encoded value + value = confObject.getAttribute(name); + } + + if(attribute.isOversized() && !extractAsConfig) + { + String valueString = String.valueOf(value); + if(valueString.length() > oversizeThreshold) + { + + String replacementValue = "".equals(attribute.getOversizedAltText()) + ? String.valueOf(value).substring(0, oversizeThreshold - 4) + "..." + : attribute.getOversizedAltText(); + + object.put(name, replacementValue); + } + else + { + object.put(name, value); + } + } + else + { + object.put(name, value); + } } else if (extractAsConfig) { @@ -220,7 +249,9 @@ public class ConfiguredObjectToMapConverter final boolean useActualValues, final boolean inheritedActuals, final boolean includeSystemContext, - final boolean extractAsConfig) + final boolean extractAsConfig, + final int oversizeThreshold, + final boolean isSecure) { List<Class<? extends ConfiguredObject>> childTypes = new ArrayList<>(confObject.getModel().getChildTypes(clazz)); @@ -262,7 +293,9 @@ public class ConfiguredObjectToMapConverter useActualValues, inheritedActuals, includeSystemContext, - extractAsConfig)); + extractAsConfig, + oversizeThreshold, + isSecure)); } } 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 01dd873aa5..b995bb442c 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 @@ -43,6 +43,7 @@ import org.apache.qpid.server.model.ConfiguredAutomatedAttribute; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.ConfiguredObjectAttribute; import org.apache.qpid.server.model.ConfiguredObjectTypeRegistry; +import org.apache.qpid.server.model.ManagedObject; import org.apache.qpid.server.model.Model; public class MetaDataServlet extends AbstractServlet @@ -103,6 +104,18 @@ public class MetaDataServlet extends AbstractServlet typeDetails.put("attributes", processAttributes(type)); typeDetails.put("managedInterfaces", getManagedInterfaces(type)); typeDetails.put("validChildTypes", getValidChildTypes(type)); + ManagedObject annotation = type.getAnnotation(ManagedObject.class); + if(annotation != null) + { + if(annotation.deprecated()) + { + typeDetails.put("deprecated",true); + } + if(!"".equals(annotation.description() ) ) + { + typeDetails.put("description", annotation.description()); + } + } return typeDetails; } @@ -175,7 +188,10 @@ public class MetaDataServlet extends AbstractServlet { attrDetails.put("secure",attribute.isSecure()); } - + if(attribute.isOversized()) + { + attrDetails.put("oversize", attribute.isOversized()); + } attributeDetails.put(attribute.getName(), attrDetails); } return attributeDetails; 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 71ec6e786f..19d498e240 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 @@ -56,6 +56,7 @@ public class RestServlet extends AbstractServlet private static final String HIERARCHY_INIT_PARAMETER = "hierarchy"; public static final String DEPTH_PARAM = "depth"; + public static final String OVERSIZE_PARAM = "oversize"; public static final String ACTUALS_PARAM = "actuals"; public static final String SORT_PARAM = "sort"; public static final String INCLUDE_SYS_CONTEXT_PARAM = "includeSysContext"; @@ -71,6 +72,7 @@ public class RestServlet extends AbstractServlet public static final Set<String> RESERVED_PARAMS = new HashSet<>(Arrays.asList(DEPTH_PARAM, SORT_PARAM, + OVERSIZE_PARAM, ACTUALS_PARAM, INCLUDE_SYS_CONTEXT_PARAM, EXTRACT_INITIAL_CONFIG_PARAM, @@ -345,17 +347,20 @@ public class RestServlet extends AbstractServlet boolean actuals; boolean includeSystemContext; boolean inheritedActuals; + int oversizeThreshold; if(extractInitialConfig) { depth = Integer.MAX_VALUE; + oversizeThreshold = Integer.MAX_VALUE; actuals = true; includeSystemContext = false; inheritedActuals = false; } else { - depth = getDepthParameterFromRequest(request); + depth = getIntParameterFromRequest(request, DEPTH_PARAM, 1); + oversizeThreshold = getIntParameterFromRequest(request, OVERSIZE_PARAM, 120); actuals = getBooleanParameterFromRequest(request, ACTUALS_PARAM); includeSystemContext = getBooleanParameterFromRequest(request, INCLUDE_SYS_CONTEXT_PARAM); inheritedActuals = getBooleanParameterFromRequest(request, INHERITED_ACTUALS_PARAM); @@ -364,8 +369,9 @@ public class RestServlet extends AbstractServlet List<Map<String, Object>> output = new ArrayList<>(); for(ConfiguredObject configuredObject : allObjects) { + output.add(_objectConverter.convertObjectToMap(configuredObject, getConfiguredClass(), - depth, actuals, inheritedActuals, includeSystemContext, extractInitialConfig)); + depth, actuals, inheritedActuals, includeSystemContext, extractInitialConfig, oversizeThreshold, request.isSecure())); } @@ -679,22 +685,24 @@ public class RestServlet extends AbstractServlet response.setDateHeader ("Expires", 0); } - private int getDepthParameterFromRequest(HttpServletRequest request) + private int getIntParameterFromRequest(final HttpServletRequest request, + final String paramName, + final int defaultValue) { - int depth = 1; - final String depthString = request.getParameter(DEPTH_PARAM); - if(depthString!=null) + int intValue = defaultValue; + final String stringValue = request.getParameter(paramName); + if(stringValue!=null) { try { - depth = Integer.parseInt(depthString); + intValue = Integer.parseInt(stringValue); } catch (NumberFormatException e) { - LOGGER.warn("Could not parse " + depthString + " as integer"); + LOGGER.warn("Could not parse " + stringValue + " as integer for parameter " + paramName); } } - return depth; + return intValue; } private boolean getBooleanParameterFromRequest(HttpServletRequest request, final String paramName) 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 index 07a0c4cf83..64f8078314 100644 --- 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 @@ -58,7 +58,7 @@ </div> </div> - <div class="dijitDialogPaneActionBar"> + <div class="dijitDialogPaneActionBar qpidDialogPaneActionBar"> <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> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/addAuthenticationProvider.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/addAuthenticationProvider.html index cf38cd425c..5a565e72e3 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/addAuthenticationProvider.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/addAuthenticationProvider.html @@ -56,7 +56,7 @@ <div id="addPreferencesProvider.form"></div> </div> - <div class="dijitDialogPaneActionBar"> + <div class="dijitDialogPaneActionBar qpidDialogPaneActionBar"> <button data-dojo-type="dijit/form/Button" id="addAuthenticationProvider.addButton" data-dojo-props="label: 'Save'" type="submit"></button> <button data-dojo-type="dijit/form/Button" id="addAuthenticationProvider.cancelButton" data-dojo-props="label: 'Cancel'" ></button> </div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/addBinding.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/addBinding.html index 1b30c6ddcc..d4ac5877cb 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/addBinding.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/addBinding.html @@ -56,7 +56,7 @@ </fieldset> </div> - <div class="dijitDialogPaneActionBar"> + <div class="dijitDialogPaneActionBar qpidDialogPaneActionBar"> <input type="submit" value="Create Binding" label="Create Binding" data-dojo-type="dijit/form/Button" /> </div> </form> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/addExchange.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/addExchange.html index 77d5ed0bc1..25e9752392 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/addExchange.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/addExchange.html @@ -66,7 +66,7 @@ <div class="clear"></div> - <div class="dijitDialogPaneActionBar"> + <div class="dijitDialogPaneActionBar qpidDialogPaneActionBar"> <input type="submit" value="Create Exchange" label="Create Exchange" dojoType="dijit.form.Button" /> </div> </form> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/addGroupProvider.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/addGroupProvider.html new file mode 100644 index 0000000000..b622fe94d2 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/addGroupProvider.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="addGroupProvider"> + <div id="addGroupProvider.contentPane"> + <form id="addGroupProvider.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="addGroupProvider.name" + data-dojo-type="dijit/form/ValidationTextBox" + data-dojo-props=" + name: 'name', + placeHolder: 'group provider name', + required: true, + promptMessage: 'Name of group provider, must be unique', + title: 'Enter a unique group 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="addGroupProvider.type" data-dojo-type="dijit/form/FilteringSelect" + data-dojo-props=" + name: 'type', + required: true, + placeHolder: 'group provider type', + promptMessage: 'Type of group provider', + title: 'Select type', + searchAttr: 'name'"> + </select> + </div> + </div> + <div class="clear"> + <div id="addGroupProvider.typeFields"></div> + </div> + </div> + </form> + <div class="clear"> + </div> + </div> + + <div class="dijitDialogPaneActionBar qpidDialogPaneActionBar"> + <button data-dojo-type="dijit/form/Button" id="addGroupProvider.addButton" data-dojo-props="label: 'Save'" type="submit"></button> + <button data-dojo-type="dijit/form/Button" id="addGroupProvider.cancelButton" data-dojo-props="label: 'Cancel'" ></button> + </div> + </div> +</div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/addPort.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/addPort.html index c76a230382..b787e701ec 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/addPort.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/addPort.html @@ -234,7 +234,7 @@ <input type="hidden" id="formAddPort.id" name="id"/> <div class="clear"></div> - <div class="dijitDialogPaneActionBar"> + <div class="dijitDialogPaneActionBar qpidDialogPaneActionBar"> <!-- submit buttons --> <input type="submit" value="Save Port" label="Save Port" dojoType="dijit.form.Button" /> </div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/addPreferencesProvider.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/addPreferencesProvider.html index e850f5ac7f..e3984e1ae2 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/addPreferencesProvider.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/addPreferencesProvider.html @@ -19,7 +19,7 @@ <div id="addPreferencesProvider.preferencesProvider" data-dojo-type="qpid/management/preferencesprovider/PreferencesProviderForm"></div> - <div class="dijitDialogPaneActionBar"> + <div class="dijitDialogPaneActionBar qpidDialogPaneActionBar"> <!-- submit buttons --> <input type="button" value="Save" data-dojo-props="label: 'Save'" data-dojo-type="dijit/form/Button" id="addPreferencesProvider.saveButton"/> <input type="button" value="Cancel" data-dojo-props="label: 'Cancel'" data-dojo-type="dijit/form/Button" id="addPreferencesProvider.cancelButton"/> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/addQueue.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/addQueue.html index 042d6d7ad7..61f0de22d8 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/addQueue.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/addQueue.html @@ -334,7 +334,7 @@ <div id="formAddQueue.context" ></div> </div> - <div class="dijitDialogPaneActionBar"> + <div class="dijitDialogPaneActionBar qpidDialogPaneActionBar"> <!-- submit buttons --> <input type="submit" value="Create Queue" label="Create Queue" dojoType="dijit.form.Button" /> </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 index dd6e7a3d38..a1903d456e 100644 --- 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 @@ -58,7 +58,7 @@ </div> </div> - <div class="dijitDialogPaneActionBar"> + <div class="dijitDialogPaneActionBar qpidDialogPaneActionBar"> <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> 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 383c782d60..a2ee2c1b4b 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 @@ -128,7 +128,7 @@ </div> </form> </div> - <div class="dijitDialogPaneActionBar"> + <div class="dijitDialogPaneActionBar qpidDialogPaneActionBar"> <button data-dojo-type="dijit/form/Button" id="addVirtualHostNodeAndVirtualHost.addButton" data-dojo-props="label: 'Add'" type="submit"></button> <button data-dojo-type="dijit/form/Button" id="addVirtualHostNodeAndVirtualHost.cancelButton" data-dojo-props="label: 'Cancel'" ></button> </div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/common/ResourceWidget.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/common/ResourceWidget.html new file mode 100644 index 0000000000..e47fa6ca6d --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/common/ResourceWidget.html @@ -0,0 +1,48 @@ +<!-- + - + - 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="dijit dijitReset dijitInline dijitLeft" id="widget_${id}" role="presentation"> + <input type="text" name="${name}_resourceLocation" + data-dojo-attach-point="resourceLocation,textbox,focusNode" + data-dojo-type="dijit/form/ValidationTextBox" + data-dojo-props="required:true,disabled:false"/> + + <div data-dojo-attach-point="uploadFields"> + <div data-dojo-attach-point="uploadData" style="width:auto;overflow:hidden;text-align:right"> + <span data-dojo-attach-point="selectedFile" class="infoMessage"></span> + <span data-dojo-attach-point="selectedFileStatus"></span> + </div> + <div style="text-align:right"> + <span data-dojo-attach-point="blah"></span> + <input name="${name}_uploadedFile" multiple="false" type="file" id="uploader_${id}" + data-dojo-attach-point="uploader" + data-dojo-type="dojox/form/Uploader" + data-dojo-props="label: 'Upload'"/> + <button data-dojo-attach-point="clearButton" data-dojo-type="dijit/form/Button" + data-dojo-props="label: 'Clear', disabled: true"/>Clear</button> + + </div> + <div class="clear"></div> + </div> + <div data-dojo-attach-point="unsupportedWarning" class="infoMessage hidden clear" style="overflow:scroll;"> + File upload requires a more recent browser with HTML5 support + </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 a18562fa1a..ec31709987 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 @@ -329,3 +329,11 @@ div .messages { max-height: 140px; overflow: auto; } + +.qpidDialogPaneActionBar +{ + margin-left:-10px; + margin-right:-10px; + margin-bottom:-10px; + margin-top:5px; +}
\ No newline at end of file diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/editBroker.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/editBroker.html index 85ca617c10..993a2c7505 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/editBroker.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/editBroker.html @@ -109,7 +109,7 @@ <div class="clear"></div> </div> - <div class="dijitDialogPaneActionBar"> + <div class="dijitDialogPaneActionBar qpidDialogPaneActionBar"> <button data-dojo-type="dijit/form/Button" id="editBroker.saveButton" data-dojo-props="label: 'Save'">Save</button> <button data-dojo-type="dijit/form/Button" id="editBroker.cancelButton" data-dojo-props="label: 'Cancel'" ></button> </div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/editQueue.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/editQueue.html index aff2b5dfa5..e7b33ed6f9 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/editQueue.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/editQueue.html @@ -289,7 +289,7 @@ <div id="formEditQueue.context" ></div> </div> </div> - <div class="dijitDialogPaneActionBar"> + <div class="dijitDialogPaneActionBar qpidDialogPaneActionBar"> <button data-dojo-type="dijit/form/Button" id="formEditQueue.saveButton" data-dojo-props="label: 'Save'">Save</button> <button data-dojo-type="dijit/form/Button" id="formEditQueue.cancelButton" data-dojo-props="label: 'Cancel'" ></button> </div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/editVirtualHost.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/editVirtualHost.html index f4826016ec..8e03dfdd17 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/editVirtualHost.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/editVirtualHost.html @@ -127,7 +127,7 @@ <div id="editVirtualHost.context" ></div> </div> </div> - <div class="dijitDialogPaneActionBar"> + <div class="dijitDialogPaneActionBar qpidDialogPaneActionBar"> <button data-dojo-type="dijit/form/Button" id="editVirtualHost.saveButton" data-dojo-props="label: 'Save'">Save</button> <button data-dojo-type="dijit/form/Button" id="editVirtualHost.cancelButton" data-dojo-props="label: 'Cancel'" ></button> </div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/editVirtualHostNode.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/editVirtualHostNode.html index 46e76c31f0..cee18f7185 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/editVirtualHostNode.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/editVirtualHostNode.html @@ -44,7 +44,7 @@ <div id="editVirtualHostNode.context" ></div> </div> </div> - <div class="dijitDialogPaneActionBar"> + <div class="dijitDialogPaneActionBar qpidDialogPaneActionBar"> <button data-dojo-type="dijit/form/Button" id="editVirtualHostNode.saveButton" data-dojo-props="label: 'Save'">Save</button> <button data-dojo-type="dijit/form/Button" id="editVirtualHostNode.cancelButton" data-dojo-props="label: 'Cancel'" ></button> </div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/footer.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/footer.html index 76d1d26695..44fa4fda36 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/footer.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/footer.html @@ -19,7 +19,7 @@ - --> -<div class="footer"><p>© 2004-<span class="currentYear">2014</span> The Apache Software Foundation. +<div class="footer"><p>© 2004-<span class="currentYear">2015</span> The Apache Software Foundation. <br/> Apache Qpid, Qpid, Apache, the Apache feather logo, and the Apache Qpid project logo are trademarks of The Apache Software Foundation. diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/grid/showColumnDefDialog.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/grid/showColumnDefDialog.html index 5b6b8ad774..535b9a1fe5 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/grid/showColumnDefDialog.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/grid/showColumnDefDialog.html @@ -23,7 +23,7 @@ <div>Select columns to display:</div> <div class="columnList"></div> </div> - <div class="dijitDialogPaneActionBar"> + <div class="dijitDialogPaneActionBar qpidDialogPaneActionBar"> <button value="Display" data-dojo-type="dijit.form.Button" class="displayButton" data-dojo-props="label: 'Display' "></button> <button value="Cancel" data-dojo-type="dijit.form.Button" data-dojo-props="label: 'Cancel'" diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/grid/showRowNumberLimitDialog.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/grid/showRowNumberLimitDialog.html index 087d54c0f9..cacdf49e66 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/grid/showRowNumberLimitDialog.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/grid/showRowNumberLimitDialog.html @@ -24,7 +24,7 @@ <input class="rowNumberLimit" data-dojo-type="dijit.form.NumberSpinner" data-dojo-props="invalidMessage: 'Invalid value', required: true, smallDelta: 1,mconstraints: {min:1,max:65535,places:0, pattern: '#####'}, label: 'Maximum number of rows:', name: 'rowNumberLimit'"></input> </div> - <div class="dijitDialogPaneActionBar"> + <div class="dijitDialogPaneActionBar qpidDialogPaneActionBar"> <button value="Submit" data-dojo-type="dijit.form.Button" class="submitButton" data-dojo-props="label: 'Submit' "></button> <button value="Cancel" data-dojo-type="dijit.form.Button" data-dojo-props="label: 'Cancel'" diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/group/addGroupMember.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/group/addGroupMember.html index 0372468f91..e479e8cb74 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/group/addGroupMember.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/group/addGroupMember.html @@ -30,8 +30,9 @@ </table> <br/> - <!-- submit buttons --> - <input type="submit" value="Add Group Member" label="Add Group Member" dojoType="dijit.form.Button" /> + <div class="dijitDialogPaneActionBar"> + <input type="submit" value="Add Group Member" label="Add Group Member" dojoType="dijit.form.Button" /> + </div> </form> </div> </div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/group/showGroup.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/group/showGroup.html index 4fddf727d0..c84e794ac1 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/group/showGroup.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/group/showGroup.html @@ -23,8 +23,10 @@ <br/> <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Group Members'"> <div class="groupMembers"></div> - <button data-dojo-type="dijit.form.Button" class="addGroupMemberButton" type="button">Add Group Member</button> - <button data-dojo-type="dijit.form.Button" class="removeGroupMemberButton" type="button">Remove Group Members</button> + <div class="dijitDialogPaneActionBar"> + <button data-dojo-type="dijit.form.Button" class="addGroupMemberButton" type="button">Add Group Member</button> + <button data-dojo-type="dijit.form.Button" class="removeGroupMemberButton" type="button">Remove Group Members</button> + </div> </div> </div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/groupprovider/addGroup.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/groupprovider/addGroup.html index 8d3431808a..29ce2ebe6c 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/groupprovider/addGroup.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/groupprovider/addGroup.html @@ -30,8 +30,9 @@ </table> <br/> - <!-- submit buttons --> - <input type="submit" value="Create Group" label="Create Group" dojoType="dijit.form.Button" /> + <div class="dijitDialogPaneActionBar"> + <input type="submit" value="Create Group" label="Create Group" dojoType="dijit.form.Button" /> + </div> </form> </div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/groupprovider/groupfile/add.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/groupprovider/groupfile/add.html new file mode 100644 index 0000000000..7fc458cd4f --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/groupprovider/groupfile/add.html @@ -0,0 +1,37 @@ +<!-- + - + - 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 tableContainer-labelCell">Path*:</div> + <div class="formLabel-controlCell tableContainer-valueCell"> + <input type="text" class="addGroupProviderPath" + data-dojo-type="dijit/form/ValidationTextBox" + data-dojo-props=" + name: 'path', + required: true, + placeHolder: 'path/to/group/file', + title: 'Enter path to file with groups', + promptMessage: 'Enter path to file with groups'"/> + </div> + </div> + + <div class="clear"></div> +</div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/groupprovider/groupfile/show.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/groupprovider/groupfile/show.html new file mode 100644 index 0000000000..740c65fd38 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/groupprovider/groupfile/show.html @@ -0,0 +1,25 @@ +<!-- + ~ 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 to file:</div> + <div ><span class="path" ></span></div> + </div> + <div class="clear"></div> +</div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/groupprovider/showFileGroupManager.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/groupprovider/showGroupManagingGroupProvider.html index d266971ee2..62a6c7537c 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/groupprovider/showFileGroupManager.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/groupprovider/showGroupManagingGroupProvider.html @@ -19,16 +19,12 @@ - --> <div class="FileGroupManager"> - <div class="clear"> - <div class="formLabel-labelCell">Path:</div> - <div class="path"></div> - </div> - <div class="clear"></div> - <br/> <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Groups'"> <div class="groups"></div> - <button data-dojo-type="dijit.form.Button" class="addGroupButton">Add Group</button> - <button data-dojo-type="dijit.form.Button" class="deleteGroupButton">Delete Groups</button> + <div class="dijitDialogPaneActionBar"> + <button data-dojo-type="dijit.form.Button" class="addGroupButton">Add Group</button> + <button data-dojo-type="dijit.form.Button" class="deleteGroupButton">Delete Groups</button> + </div> </div> </div> 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 379a25bbcd..896640fd67 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 @@ -125,7 +125,7 @@ </div> </div> </div> - <div class="dijitDialogPaneActionBar"> + <div class="dijitDialogPaneActionBar qpidDialogPaneActionBar"> <input type="button" id="errorDialog.button.cancel" value="Cancel" label="Cancel" dojoType="dijit.form.Button" onClick="dijit.byId('errorDialog').hide();"/> <input type="button" id="errorDialog.button.relogin" value="Login" label="Login" dojoType="dijit.form.Button" onClick="dijit.byId('errorDialog').hide(); window.location='logout';"/> </div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/FormWidgetMixin.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/FormWidgetMixin.js new file mode 100644 index 0000000000..11160e9608 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/FormWidgetMixin.js @@ -0,0 +1,102 @@ +/* + * + * 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/declare"], function(declare) +{ + return declare("qpid.common.FormWidgetMixin", null, + { + name: "", + value: "", + _onChangeActive: false, + + compare: function(val1, val2) + { + if(typeof val1 == "number" && typeof val2 == "number") + { + return (isNaN(val1) && isNaN(val2)) ? 0 : val1 - val2; + } + else if(val1 > val2) + { + return 1; + } + else if(val1 < val2) + { + return -1; + } + else + { + return 0; + } + }, + onChange: function() + { + }, + _setValueAttr: function(newValue, priorityChange) + { + this._handleOnChange(newValue, priorityChange); + }, + _handleOnChange: function(newValue, priorityChange) + { + this._set("value", newValue); + if(this._lastValueReported == undefined && (priorityChange === null || !this._onChangeActive)) + { + this._resetValue = this._lastValueReported = newValue; + } + this._pendingOnChange = this._pendingOnChange || (typeof newValue != typeof this._lastValueReported) + || (this.compare(newValue, this._lastValueReported) != 0); + if(( priorityChange || priorityChange === undefined) && this._pendingOnChange) + { + this._lastValueReported = newValue; + this._pendingOnChange = false; + if(this._onChangeActive) + { + if(this._onChangeHandle) + { + this._onChangeHandle.remove(); + } + this._onChangeHandle = this.defer(function() { this._onChangeHandle = null; this.onChange(newValue); }); + } + } + }, + create: function() + { + this.inherited(arguments); + this._onChangeActive = true; + }, + destroy: function() + { + if(this._onChangeHandle) + { + this._onChangeHandle.remove(); + this.onChange(this._lastValueReported); + } + this.inherited(arguments); + }, + undo: function() + { + this._setValueAttr(this._lastValueReported, false); + }, + reset: function() + { + this._hasBeenBlurred = false; + this._setValueAttr(this._resetValue, true); + } + }); +});
\ No newline at end of file diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/ResourceWidget.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/ResourceWidget.js new file mode 100644 index 0000000000..f603c96ff3 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/ResourceWidget.js @@ -0,0 +1,178 @@ +/* + * + * 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/declare", + "dojo/_base/array", + "dojo/_base/lang", + "qpid/common/util", + "dijit/_Widget", + "dijit/_TemplatedMixin", + "dijit/_WidgetsInTemplateMixin", + "qpid/common/FormWidgetMixin", + "dojo/text!common/ResourceWidget.html", + "dojox/html/entities", + "dojox/form/Uploader", + "dijit/form/Button", + "dijit/form/ValidationTextBox", + "dojox/validate/us", + "dojox/validate/web", + "dojo/domReady!"], +function (declare, array, lang, util, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, FormWidgetMixin, template, entities) +{ + + return declare("qpid.common.ResourceWidget", [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, FormWidgetMixin], + { + templateString: template, + fileReaderSupported: window.FileReader ? true : false, + displayWarningWhenFileReaderUnsupported: false, + isDebug: false, + + buildRendering: function() + { + //Strip out the apache comment header from the template html as comments unsupported. + this.templateString = this.templateString.replace(/<!--[\s\S]*?-->/g, ""); + this.inherited(arguments); + }, + postCreate: function() + { + this.inherited(arguments); + + if(this._resetValue === undefined) + { + this._lastValueReported = this._resetValue = this.value; + } + + var that = this; + + if (this.fileReaderSupported) + { + this.fileReader= new FileReader(); + this.fileReader.onload = function(evt) {that._uploadFileComplete(evt);}; + this.fileReader.onerror = function(ex) {console.error("Failed to load file for " + this.name, ex);}; + this.uploader.on("change", function(selected){that._fileChanged(selected)}); + this.clearButton.on("click", function(event){that._fileClearButtonClicked(event)}); + } + else + { + // Fall back for IE8/9 which do not support FileReader + this.uploadFields.style.display = "none"; + if (displayWarningWhenFileReaderUnsupported) + { + this.unsupportedWarning.className = this.unsupportedWarning.className.replace("hidden", ""); + } + } + this.resourceLocation.on("blur", function(){that._pathChanged()}); + this._originalValue = arguments.value; + if (this.placeHolder) + { + this.resourceLocation.set("placeHolder", this.placeHolder); + } + if (this.promptMessage) + { + this.resourceLocation.set("promptMessage", this.promptMessage); + } + if (this.title) + { + this.resourceLocation.set("title", this.title); + } + this.resourceLocation.set("required", this.required ? true : false); + this.uploadData.style.display = "none"; + }, + startup: function() + { + if (this.fileReaderSupported) + { + this.uploader.startup(); + } + }, + _fileChanged: function (evt) + { + var file = this.uploader.domNode.children[0].files[0]; + this.selectedFileName = file.name; + this.selectedFile.innerHTML = file.name; + this.selectedFileStatus.className = "loadingIcon"; + if (this.isDebug) + { + this._log("Beginning to read file " + file.name + " for " + this.name); + } + this.fileReader.readAsDataURL(file); + }, + _uploadFileComplete: function(evt) + { + var reader = evt.target; + var result = reader.result; + if (this.isDebug) + { + this._log(this.name + " file read complete, contents " + result); + } + this.set("value", result); + }, + _fileClearButtonClicked: function(event) + { + this.uploader.reset(); + this.set("value", this._resetValue); + }, + _pathChanged: function() + { + var serverPathValue = this.resourceLocation.get("value") || this._resetValue; + this.set("value", serverPathValue); + }, + _setValueAttr: function(newValue, priorityChange) + { + var isDataUrl = newValue && newValue.indexOf("data:") == 0; + if (isDataUrl) + { + this.uploadData.style.display = "block"; + this.selectedFileStatus.className = "loadedIcon"; + this.selectedFile.innerHTML = this.selectedFileName || "uploaded data"; + this.resourceLocation.set("value", ""); + this.resourceLocation.setDisabled(true); + this.resourceLocation.set("required", false); + this.clearButton.setDisabled(false); + this.selectedFileStatus.className = "loadedIcon"; + } + else + { + this.resourceLocation.set("value", newValue); + this.selectedFileName = null; + this.selectedFileStatus.className = ""; + this.selectedFile.innerHTML = ""; + this.resourceLocation.set("required", this.required ? true : false); + this.resourceLocation.setDisabled(false); + this.clearButton.setDisabled(true); + this.uploadData.style.display = "none"; + } + this.inherited(arguments); + }, + _log: function(message) + { + if (this.isDebug) + { + console.log(message); + } + }, + _setPlaceHolderAttr: function(newValue) + { + this.resourceLocation.set("placeHolder", newValue); + } + } + ); +}); 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 c62ba5d5d4..1520cb8f7a 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 @@ -29,7 +29,7 @@ define(["dojo/_base/xhr", _init: function () { var that = this; - xhr.get({sync: true, handleAs: "json", url: "service/metadata", load: function(metadata){that._onMetadata(metadata)}}); + xhr.get({sync: true, handleAs: "json", url: "service/metadata", load: function(data){that._onMetadata(data)}}); }, _onMetadata: function (metadata) { @@ -68,7 +68,8 @@ define(["dojo/_base/xhr", }, implementsManagedInterface: function (category, type, managedInterfaceName) { - return this.getMetaData(category, type).managedInterfaces.indexOf(managedInterfaceName) >= 0; + var managedInterfaces = this.getMetaData(category, type).managedInterfaces; + return array.indexOf(managedInterfaces, managedInterfaceName) >= 0 ; }, validChildTypes: function (category, type, childCategory) { 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 161ce4f83c..8545d2da75 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 @@ -33,12 +33,11 @@ define(["dojo/_base/xhr", "dojo/dom-style", "dojox/html/entities", "dojo/dom", - "qpid/management/addPreferencesProvider", "qpid/management/PreferencesProvider", "qpid/management/authenticationprovider/PrincipalDatabaseAuthenticationManager", "dojo/domReady!"], function (xhr, parser, query, connect, properties, updater, util, UpdatableStore, EnhancedGrid, - addAuthenticationProvider, event, registry, domStyle, entities, dom, addPreferencesProvider, PreferencesProvider, PrincipalDatabaseAuthenticationManager) { + addAuthenticationProvider, event, registry, domStyle, entities, dom, PreferencesProvider, PrincipalDatabaseAuthenticationManager) { function AuthenticationProvider(name, parent, controller) { this.name = name; @@ -79,14 +78,6 @@ define(["dojo/_base/xhr", that.deleteAuthenticationProvider(); }); - var addPreferencesProviderButton = query(".addPreferencesProviderButton", contentPane.containerNode)[0]; - var addPreferencesProviderWidget = registry.byNode(addPreferencesProviderButton); - connect.connect(addPreferencesProviderWidget, "onClick", - function(evt){ - event.stop(evt); - that.addPreferencesProvider(); - }); - authProviderUpdater.update(); if (util.isProviderManagingUsers(authProviderUpdater.authProviderData.type)) { @@ -136,14 +127,6 @@ define(["dojo/_base/xhr", } }; - AuthenticationProvider.prototype.addPreferencesProvider = function() { - if (this.authProviderUpdater && this.authProviderUpdater.authProviderData - && (!this.authProviderUpdater.authProviderData.preferencesproviders - || !this.authProviderUpdater.authProviderData.preferencesproviders[0])){ - addPreferencesProvider.show(this.name); - } - }; - function AuthProviderUpdater(node, authProviderObj, controller, authenticationProvider) { this.controller = controller; @@ -154,7 +137,6 @@ define(["dojo/_base/xhr", this.preferencesProviderType=dom.byId("preferencesProviderType"); this.preferencesProviderName=dom.byId("preferencesProviderName"); this.preferencesProviderState=dom.byId("preferencesProviderState"); - this.addPreferencesProviderButton = query(".addPreferencesProviderButton", node)[0]; this.editPreferencesProviderButton = query(".editPreferencesProviderButton", node)[0]; this.deletePreferencesProviderButton = query(".deletePreferencesProviderButton", node)[0]; this.preferencesProviderAttributes = dom.byId("preferencesProviderAttributes") @@ -169,7 +151,6 @@ this.authenticationProviderDetailsContainer = query(".authenticationProviderDeta { if (preferencesProviderData) { - this.addPreferencesProviderButton.style.display = 'none'; if (!this.preferencesProvider) { var preferencesProvider =new PreferencesProvider(preferencesProviderData.name, this.authProviderData); @@ -184,7 +165,6 @@ this.authenticationProviderDetailsContainer = query(".authenticationProviderDeta { this.preferencesProvider.update(null); } - this.addPreferencesProviderButton.style.display = 'inline'; } }; diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/GroupProvider.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/GroupProvider.js index 09473524b5..f739e52665 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/GroupProvider.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/GroupProvider.js @@ -22,18 +22,24 @@ define(["dojo/_base/xhr", "dojo/parser", "dojo/query", "dojo/_base/connect", + "dojo/_base/array", + "dojo/_base/event", "qpid/common/properties", "qpid/common/updater", "qpid/common/util", + "qpid/common/metadata", "qpid/common/UpdatableStore", "dojox/grid/EnhancedGrid", "dijit/registry", - "dojo/_base/event", "dojox/html/entities", + "dojo/text!showGroupProvider.html", + "qpid/management/addGroupProvider", "dojox/grid/enhanced/plugins/Pagination", "dojox/grid/enhanced/plugins/IndirectSelection", "dojo/domReady!"], - function (xhr, parser, query, connect, properties, updater, util, UpdatableStore, EnhancedGrid, registry, event, entities) { + function (xhr, parser, query, connect, array, event, properties, updater, util, metadata, UpdatableStore, + EnhancedGrid, registry, entities, template, addGroupProvider) + { function GroupProvider(name, parent, controller) { this.name = name; @@ -45,38 +51,63 @@ define(["dojo/_base/xhr", return "GroupProvider: " + this.name ; }; - GroupProvider.prototype.open = function(contentPane) { + GroupProvider.prototype.open = function(contentPane) + { var that = this; this.contentPane = contentPane; - xhr.get({url: "showGroupProvider.html", - sync: true, - load: function(data) { - contentPane.containerNode.innerHTML = data; - parser.parse(contentPane.containerNode); - - that.groupProviderAdapter = new GroupProviderUpdater(contentPane.containerNode, that.modelObj, that.controller); - - updater.add( that.groupProviderAdapter ); - - that.groupProviderAdapter.update(); - - var deleteButton = query(".deleteGroupProviderButton", contentPane.containerNode)[0]; - var deleteWidget = registry.byNode(deleteButton); - connect.connect(deleteWidget, "onClick", - function(evt){ - event.stop(evt); - that.deleteGroupProvider(); - }); - }}); + contentPane.containerNode.innerHTML = template; + parser.parse(contentPane.containerNode); + + this.groupProviderUpdater = new GroupProviderUpdater(contentPane.containerNode, this.modelObj, this.controller); + + // load data + this.groupProviderUpdater.update(); + + this.deleteButton = registry.byNode(query(".deleteGroupProviderButton", contentPane.containerNode)[0]); + this.deleteButton.on("click", function(evt){ event.stop(evt); that.deleteGroupProvider(); }); + + this.editButton = registry.byNode(query(".editGroupProviderButton", contentPane.containerNode)[0]); + this.editButton.on("click", function(evt){ event.stop(evt); that.editGroupProvider(); }); + + var type = this.groupProviderUpdater.groupProviderData.type; + var providerDetailsNode = query(".providerDetails", contentPane.containerNode)[0]; + + require(["qpid/management/groupprovider/"+ encodeURIComponent(type.toLowerCase()) + "/show"], + function(DetailsUI) + { + that.groupProviderUpdater.details = new DetailsUI({containerNode: providerDetailsNode, parent: that}); + that.groupProviderUpdater.details.update(that.groupProviderUpdater.groupProviderData); + }); + + var managedInterfaces = metadata.getMetaData("GroupProvider", type).managedInterfaces; + if (managedInterfaces) + { + + var managedInterfaceUI = this.groupProviderUpdater.managedInterfaces; + + array.forEach(managedInterfaces, + function(managedInterface) + { + require(["qpid/management/groupprovider/" + encodeURIComponent(managedInterface)], + function(ManagedInterface) + { + managedInterfaceUI[ManagedInterface] = new ManagedInterface(providerDetailsNode, that.modelObj, that.controller); + managedInterfaceUI[ManagedInterface].update(that.groupProviderUpdater.groupProviderData); + }); + }); + } + + updater.add( this.groupProviderUpdater ); }; + GroupProvider.prototype.close = function() { - updater.remove( this.groupProviderAdapter ); + updater.remove( this.groupProviderUpdater ); }; GroupProvider.prototype.deleteGroupProvider = function() { var warnMessage = ""; - if (this.groupProviderAdapter.groupProviderData && this.groupProviderAdapter.groupProviderData.type.indexOf("File") != -1) + if (this.groupProviderUpdater.groupProviderData && this.groupProviderUpdater.groupProviderData.type.indexOf("File") != -1) { warnMessage = "NOTE: provider deletion will also remove the group file on disk.\n\n"; } @@ -96,7 +127,23 @@ define(["dojo/_base/xhr", util.xhrErrorHandler(this.failureReason); } } - }; + }; + + GroupProvider.prototype.editGroupProvider = function() + { + xhr.get( + { + url: this.groupProviderUpdater.query, + sync: true, + content: { actuals: true }, + handleAs: "json", + load: function(actualData) + { + addGroupProvider.show(actualData[0]); + } + } + ); + } function GroupProviderUpdater(node, groupProviderObj, controller) { @@ -105,27 +152,8 @@ define(["dojo/_base/xhr", this.type = query(".type", node)[0]; this.state = query(".state", node)[0]; this.query = "api/latest/groupprovider/"+encodeURIComponent(groupProviderObj.name); - this.typeUI ={"GroupFile": "FileGroupManager"}; - var that = this; - - xhr.get({url: this.query, sync: properties.useSyncGet, handleAs: "json"}) - .then(function(data) - { - that.groupProviderData = data[0]; - - util.flattenStatistics( that.groupProviderData ); - - that.updateHeader(); - - var ui = that.typeUI[that.groupProviderData.type]; - require(["qpid/management/groupprovider/"+ ui], - function(SpecificProvider) { - that.details = new SpecificProvider(query(".providerDetails", node)[0], groupProviderObj, controller); - that.details.update(); - }); - - }); - + this.managedInterfaces = {}; + this.details = null; } GroupProviderUpdater.prototype.updateHeader = function() @@ -138,6 +166,28 @@ define(["dojo/_base/xhr", GroupProviderUpdater.prototype.update = function() { var that = this; + xhr.get({url: this.query, sync: true, handleAs: "json"}).then(function(data) {that._update(data[0]);}); + }; + + GroupProviderUpdater.prototype._update = function(data) + { + this.groupProviderData = data; + util.flattenStatistics( this.groupProviderData ); + this.updateHeader(); + + if (this.details) + { + this.details.update(this.groupProviderData); + } + + for(var managedInterface in this.managedInterfaces) + { + var managedInterfaceUI = this.managedInterfaces[managedInterface]; + if (managedInterfaceUI) + { + managedInterfaceUI.update(this.groupProviderData); + } + } }; return GroupProvider; 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 6cb9ad727d..0f23053c2d 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 @@ -54,10 +54,8 @@ define(["dojo/dom", parser.parse(contentPane.containerNode); that.keyStoreUpdater = new KeyStoreUpdater(contentPane.containerNode, that.modelObj, that.controller, that.url); - - updater.add( that.keyStoreUpdater ); - that.keyStoreUpdater.update(); + updater.add( that.keyStoreUpdater ); var deleteKeyStoreButton = query(".deleteStoreButton", contentPane.containerNode)[0]; var node = registry.byNode(deleteKeyStoreButton); @@ -132,13 +130,20 @@ define(["dojo/dom", that.keyStoreData = data[0]; that.updateHeader(); - require(["qpid/management/store/" + encodeURIComponent(that.keyStoreData.type.toLowerCase()) + "/show"], + if (that.details) + { + that.details.update(that.keyStoreData); + } + else + { + 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/PreferencesProvider.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/PreferencesProvider.js index 35ccbf9cae..0d40669823 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/PreferencesProvider.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/PreferencesProvider.js @@ -56,7 +56,6 @@ define(["dojo/_base/xhr", that.containerNode = node; that.parentObject = parentObject; that.preferencesProviderType=query(".preferencesProviderType", node)[0]; - that.preferencesProviderName=query(".preferencesProviderName", node)[0]; that.preferencesProviderState=query(".preferencesProviderState", node)[0]; that.editPreferencesProviderButton = query(".editPreferencesProviderButton", node)[0]; that.deletePreferencesProviderButton = query(".deletePreferencesProviderButton", node)[0]; @@ -137,7 +136,6 @@ define(["dojo/_base/xhr", this.editPreferencesProviderButton.style.display = 'inline'; this.deletePreferencesProviderButton.style.display = 'inline'; this.preferencesProviderType.innerHTML = entities.encode(String(data.type)); - this.preferencesProviderName.innerHTML = entities.encode(String(data.name)); this.preferencesProviderState.innerHTML = entities.encode(String(data.state)); if (!this.details) { 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 f3fa06ccba..82e2b204f9 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 @@ -54,10 +54,8 @@ define(["dojo/dom", parser.parse(contentPane.containerNode); that.keyStoreUpdater = new KeyStoreUpdater(contentPane.containerNode, that.modelObj, that.controller, that.url); - - updater.add( that.keyStoreUpdater ); - that.keyStoreUpdater.update(); + updater.add( that.keyStoreUpdater ); var deleteTrustStoreButton = query(".deleteStoreButton", contentPane.containerNode)[0]; var node = registry.byNode(deleteTrustStoreButton); @@ -129,14 +127,20 @@ define(["dojo/dom", { 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); - } - ); + if (that.details) + { + that.details.update(that.trustStoreData); + } + else + { + 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); + } + ); + } }); }; diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAuthenticationProvider.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAuthenticationProvider.js index e05fc7582d..17b7edcec9 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAuthenticationProvider.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAuthenticationProvider.js @@ -60,6 +60,7 @@ define(["dojo/_base/xhr", this.authenticationProviderName = registry.byId("addAuthenticationProvider.name"); this.authenticationProviderName.set("regExpGen", util.nameOrContextVarRegexp); + this.authenticationProviderName.on("change", function(newValue){that.preferencesProviderForm.preferencesProviderNameWidget.set("value",newValue);}); this.dialog = registry.byId("addAuthenticationProvider"); this.addButton = registry.byId("addAuthenticationProvider.addButton"); @@ -102,7 +103,7 @@ define(["dojo/_base/xhr", this.initialData = actualData; this.effectiveData = effectiveData; this.authenticationProviderType.set("value", actualData.type); - this.authenticationProviderName.set("value", actualData.name); + this.authenticationProviderType.set("disabled", true); this.authenticationProviderName.set("disabled", true); if (actualData.preferencesproviders && actualData.preferencesproviders[0]) @@ -112,7 +113,9 @@ define(["dojo/_base/xhr", else { this.preferencesProviderForm.reset(); + this.preferencesProviderForm.preferencesProviderNameWidget.set("value", actualData.name); } + this.authenticationProviderName.set("value", actualData.name); } else { diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addGroupProvider.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addGroupProvider.js index 82281ad3d3..f158b8ceb6 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addGroupProvider.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addGroupProvider.js @@ -18,7 +18,7 @@ * under the License. * */ -define(["dojo/_base/lang", +define([ "dojo/_base/xhr", "dojo/dom", "dojo/dom-construct", @@ -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!addGroupProvider.html", "dojo/store/Memory", "dojox/validate/us", "dojox/validate/web", @@ -42,140 +44,152 @@ define(["dojo/_base/lang", "dijit/layout/ContentPane", "dojox/layout/TableContainer", "dojo/domReady!"], - function (lang, xhr, dom, construct, registry, parser, array, event, json, util) { - - var addGroupProvider = {}; - - addGroupProvider.show = function(groupProvider) { - var fields = [{ - name: "name", - createWidget: function(groupProvider) { - return new dijit.form.ValidationTextBox({ - required: true, - value: groupProvider.name, - disabled: groupProvider.name ? true : false, - label: "Name*:", - regexp: "^[\x20-\x2e\x30-\x7F]{1,255}$", - promptMessage: "Name of group provider.", - placeHolder: "name", - name: "name"}); - } - }, { - name: "type", - createWidget: function(groupProvider) { - - 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=ListGroupProviderAttributes", - 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: groupProvider.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 (xhr, dom, construct, registry, parser, array, event, json, util, metadata, template) + { + + var addGroupProvider = + { + init: function() + { + var that=this; + this.containerNode = construct.create("div", {innerHTML: template}); + parser.parse(this.containerNode); + + this.groupProviderName = registry.byId("addGroupProvider.name"); + this.groupProviderName.set("regExpGen", util.nameOrContextVarRegexp); + + this.dialog = registry.byId("addGroupProvider"); + this.addButton = registry.byId("addGroupProvider.addButton"); + this.cancelButton = registry.byId("addGroupProvider.cancelButton"); + this.cancelButton.on("click", function(e){that._cancel(e);}); + this.addButton.on("click", function(e){that._add(e);}); + + this.groupProviderTypeFieldsContainer = dom.byId("addGroupProvider.typeFields"); + this.groupProviderForm = registry.byId("addGroupProvider.form"); + + this.groupProviderType = registry.byId("addGroupProvider.type"); + this.groupProviderType.on("change", function(type){that._groupProviderTypeChanged(type);}); + + var supportedTypes = metadata.getTypesForCategory("GroupProvider"); + supportedTypes.sort(); + var supportedTypesStore = util.makeTypeStore(supportedTypes); + this.groupProviderType.set("store", supportedTypesStore); + }, + show: function(actualData) + { + this.initialData = actualData; + this.groupProviderForm.reset(); + + if (actualData) + { + this._destroyTypeFields(this.containerNode); + this._initFields(actualData); + } + this.groupProviderName.set("disabled", actualData == null ? false : true); + this.groupProviderType.set("disabled", actualData == null ? false : true); + this.dialog.set("title", actualData == null ? "Add Group Provider" : "Edit Group Provider - " + actualData.name) + this.dialog.show(); + }, + _initFields:function(data) + { + var type = data["type"]; + var attributes = metadata.getMetaData("GroupProvider", type).attributes; + for(var name in attributes) + { + var widget = registry.byId("addGroupProvider."+name); + if (widget) + { + widget.set("value", data[name]); } - 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); - } + } + }, + _cancel: function(e) + { + event.stop(e); + this.dialog.hide(); + }, + _add: function(e) + { + event.stop(e); + this._submit(); + }, + _submit: function() + { + if (this.groupProviderForm.validate()) + { + var success = false,failureReason=null; + + var groupProviderData = util.getFormWidgetValues(this.groupProviderForm, this.initialData); + var encodedName = encodeURIComponent(this.groupProviderName.value); + var jsonString = json.stringify(groupProviderData); + + try { + xhr.put( + { + url: "api/latest/groupprovider/" + encodedName, + 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); } - } - }; - typeList.on("change", onChangeHandler); - onChangeHandler(typeList.value); - return new dijit.layout.ContentPane({content: typeContainer, style:{padding: 0}}); - } - }]; - util.showSetAttributesDialog( - fields, - groupProvider ? groupProvider : {}, - "api/latest/groupprovider" + (name ? "/" + encodeURIComponent(name.name) : ""), - groupProvider ? "Edit group provider - " + groupProvider.name : "Add group provider", - "Group", - groupProvider && groupProvider.type ? groupProvider.type : "Group", - groupProvider ? false : true); + if (success == true) + { + this.dialog.hide(); + } + else + { + util.xhrErrorHandler(failureReason); + } + } + else + { + alert('Form contains invalid data. Please correct first'); + } + }, + _groupProviderTypeChanged: function(type) + { + this._destroyTypeFields(this.groupProviderTypeFieldsContainer); + if (type) + { + var that = this; + require([ "qpid/management/groupprovider/" + type.toLowerCase() + "/add"], function(typeUI) + { + try + { + typeUI.show({containerNode: that.groupProviderTypeFieldsContainer, parent: that, data: that.initialData}); + util.applyMetadataToWidgets(that.groupProviderTypeFieldsContainer, "GroupProvider", type); + } + catch(e) + { + console.warn(e); + } + }); + } + }, + _destroyTypeFields: function(typeFieldsContainer) + { + var widgets = registry.findWidgets(typeFieldsContainer); + array.forEach(widgets, function(item) { item.destroyRecursive();}); + construct.empty(typeFieldsContainer); + } }; + + try + { + addGroupProvider.init(); + } + catch(e) + { + console.warn(e); + } return addGroupProvider; + });
\ 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 index 98068f2376..5a42f12870 100644 --- 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 @@ -80,16 +80,17 @@ define(["dojo/_base/lang", }, show: function(effectiveData) { + this.effectiveData = 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.set("title", effectiveData == null ? "Add Key Store" : "Edit Key Store - " + effectiveData.name) this.dialog.show(); }, _initFields:function(data) diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/group/Group.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/group/Group.js index 8f63a8c935..8ac6be04cc 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/group/Group.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/group/Group.js @@ -34,11 +34,12 @@ define(["dojo/_base/xhr", "dojox/grid/EnhancedGrid", "dojo/data/ObjectStore", "qpid/management/group/addGroupMember", + "dojox/html/entities", "dojox/grid/enhanced/plugins/Pagination", "dojox/grid/enhanced/plugins/IndirectSelection", "dojo/domReady!"], function (xhr, parser, query, registry, connect, event, json, properties, updater, util, formatter, - UpdatableStore, JsonRest, EnhancedGrid, ObjectStore, addGroupMember) { + UpdatableStore, JsonRest, EnhancedGrid, ObjectStore, addGroupMember, entities) { function Group(name, parent, controller) { this.name = name; @@ -78,10 +79,8 @@ define(["dojo/_base/xhr", parser.parse(contentPane.containerNode); that.groupUpdater = new GroupUpdater(contentPane.containerNode, that, that.controller); - - updater.add( that.groupUpdater ); - that.groupUpdater.update(); + updater.add( that.groupUpdater ); var addGroupMemberButton = query(".addGroupMemberButton", contentPane.containerNode)[0]; connect.connect(registry.byNode(addGroupMemberButton), "onClick", @@ -128,7 +127,7 @@ define(["dojo/_base/xhr", "durable", "lifetimePolicy", "type"]); - + this.name.innerHTML = entities.encode(String(groupObj.getGroupName())); this.query = "api/latest/groupmember/"+ encodeURIComponent(groupObj.getGroupProviderName()) + "/" + encodeURIComponent(groupObj.getGroupName()); xhr.get({url: this.query, sync: properties.useSyncGet, handleAs: "json"}).then(function(data) diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/groupprovider/FileGroupManager.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/groupprovider/GroupManagingGroupProvider.js index 4ee411633f..ea12280d0d 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/groupprovider/FileGroupManager.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/groupprovider/GroupManagingGroupProvider.js @@ -34,6 +34,7 @@ define(["dojo/_base/xhr", "qpid/common/updater", "qpid/common/UpdatableStore", "dojox/grid/EnhancedGrid", + "dojo/text!groupprovider/showGroupManagingGroupProvider.html", "dojox/grid/enhanced/plugins/Pagination", "dojox/grid/enhanced/plugins/IndirectSelection", "dojox/validate/us", "dojox/validate/web", @@ -44,49 +45,17 @@ define(["dojo/_base/xhr", "dijit/form/Form", "dijit/form/DateTextBox", "dojo/domReady!"], - function (xhr, dom, parser, query, construct, connect, win, event, json, registry, entities, util, properties, updater, UpdatableStore, EnhancedGrid) { - function DatabaseGroupManager(containerNode, groupProviderObj, controller) { + function (xhr, dom, parser, query, construct, connect, win, event, json, registry, entities, util, properties, + updater, UpdatableStore, EnhancedGrid, template) + { + function GroupManagingGroupProvider(containerNode, groupProviderObj, controller) + { var node = construct.create("div", null, containerNode, "last"); var that = this; this.name = groupProviderObj.name; - xhr.get({url: "groupprovider/showFileGroupManager.html", - sync: true, - load: function(data) { - node.innerHTML = data; - parser.parse(node); - - - that.groupDatabaseUpdater= new GroupProviderUpdater(node, groupProviderObj, controller); - - updater.add( that.groupDatabaseUpdater); - - that.groupDatabaseUpdater.update(); - - - }}); - } - - DatabaseGroupManager.prototype.update = function() { - this.groupDatabaseUpdater.update(); - }; - - DatabaseGroupManager.prototype.close = function() { - updater.remove( this.groupDatabaseUpdater ); - }; - - function GroupProviderUpdater(node, groupProviderObj, controller) - { + node.innerHTML = template; + parser.parse(node); this.controller = controller; - this.query = "api/latest/groupprovider/"+encodeURIComponent(groupProviderObj.name); - this.name = groupProviderObj.name; - var that = this; - - xhr.get({url: this.query, sync: properties.useSyncGet, handleAs: "json"}) - .then(function(data) { - that.path = query(".path", node)[0]; - that.groupProviderData = data[0]; - - util.flattenStatistics( that.groupProviderData ); var groupDiv = query(".groups", node)[0]; @@ -95,7 +64,7 @@ define(["dojo/_base/xhr", keepSelection: true, plugins: { pagination: { - pageSizes: ["10", "25", "50", "100"], + pageSizes: [10, 25, 50, 100], description: true, sizeSwitch: true, pageStepper: true, @@ -106,10 +75,7 @@ define(["dojo/_base/xhr", indirectSelection: true }}; - - - that.groupsGrid = - new UpdatableStore(that.groupProviderData.groups, groupDiv, + this.groupsGrid = new UpdatableStore([], groupDiv, [ { name: "Group Name", field: "name", width: "100%" } ], function(obj) { connect.connect(obj.grid, "onRowDblClick", obj.grid, @@ -120,22 +86,13 @@ define(["dojo/_base/xhr", that.controller.show("group", name, groupProviderObj, theItem.id); }); }, gridProperties, EnhancedGrid); - - - var addGroupButton = query(".addGroupButton", node)[0]; - connect.connect(registry.byNode(addGroupButton), "onClick", function(evt){ addGroup.show(groupProviderObj.name) }); - - var deleteGroupButton = query(".deleteGroupButton", node)[0]; - var deleteWidget = registry.byNode(deleteGroupButton); - connect.connect(deleteWidget, "onClick", - function(evt){ - event.stop(evt); - that.deleteGroups(); - }); - }); + var addGroupButton = query(".addGroupButton", node)[0]; + registry.byNode(addGroupButton).on("click", function(evt){ addGroup.show(groupProviderObj.name) }); + var deleteWidget = registry.byNode(query(".deleteGroupButton", node)[0]); + deleteWidget.on("click", function(evt){ event.stop(evt); that.deleteGroups(); }); } - GroupProviderUpdater.prototype.deleteGroups = function() + GroupManagingGroupProvider.prototype.deleteGroups = function() { var grid = this.groupsGrid.grid; var data = grid.selection.getSelected(); @@ -169,22 +126,12 @@ define(["dojo/_base/xhr", } }; - GroupProviderUpdater.prototype.update = function() + GroupManagingGroupProvider.prototype.update = function(data) { - - var that = this; - - xhr.get({url: this.query, sync: properties.useSyncGet, handleAs: "json"}) - .then(function(data) { - that.groupProviderData = data[0]; - that.path.innerHTML = entities.encode(String(that.groupProviderData.path)); - util.flattenStatistics( that.groupProviderData ); - - that.groupsGrid.update(that.groupProviderData.groups); - - }); - - + if (data) + { + this.groupsGrid.update(data.groups); + } }; var addGroup = {}; @@ -258,5 +205,5 @@ define(["dojo/_base/xhr", registry.byId("addGroup").show(); }; - return DatabaseGroupManager; + return GroupManagingGroupProvider; }); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/groupprovider/groupfile/add.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/groupprovider/groupfile/add.js new file mode 100644 index 0000000000..f28f250134 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/groupprovider/groupfile/add.js @@ -0,0 +1,37 @@ +/* + * + * 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) + { + + return { show: function(data) + { + var that=this; + util.parseHtmlIntoDiv(data.containerNode, "groupprovider/groupfile/add.html"); + if (data.data) + { + var pathWidget = registry.byNode(query(".addGroupProviderPath", data.containerNode)[0]); + pathWidget.set("value", data.data.path); + } + } + }; + } +); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/groupprovider/groupfile/show.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/groupprovider/groupfile/show.js new file mode 100644 index 0000000000..a559140898 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/groupprovider/groupfile/show.js @@ -0,0 +1,37 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +define(["qpid/common/util", "dojo/domReady!"], + function (util, metadata) + { + + function GroupFile(data) + { + util.buildUI(data.containerNode, data.parent, "groupprovider/groupfile/show.html", ["path"], this); + } + + GroupFile.prototype.update = function(data) + { + util.updateUI(data, ["path"], this); + } + + return GroupFile; + } +); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/groupprovider/managedgroupprovider/add.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/groupprovider/managedgroupprovider/add.js new file mode 100644 index 0000000000..fd8e09dcda --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/groupprovider/managedgroupprovider/add.js @@ -0,0 +1,26 @@ +/* + * + * 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([], + function (dom, query, array, registry, util, metadata) + { + return { show: function(data) { /* nothing to do */ } }; + } +); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/groupprovider/managedgroupprovider/show.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/groupprovider/managedgroupprovider/show.js new file mode 100644 index 0000000000..ed6a0e155b --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/groupprovider/managedgroupprovider/show.js @@ -0,0 +1,35 @@ +/* + * + * 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([], + function () + { + + function ManagedGroupProvider(data) + { + } + + ManagedGroupProvider.prototype.update = function(data) + { + } + + return ManagedGroupProvider; + } +); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/preferencesprovider/PreferencesProviderForm.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/preferencesprovider/PreferencesProviderForm.js index 5eaaa89242..ef8273328b 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/preferencesprovider/PreferencesProviderForm.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/preferencesprovider/PreferencesProviderForm.js @@ -125,7 +125,8 @@ function (util, metadata, xhr, declare, array, domConstruct, win, query, json, _ this.preferencesProviderNameWidget.set("value", data.name); if (data.type == this.preferencesProviderTypeWidget.get("value")) { - this._toggleWidgets(data.type); + // re-create UI anyway + this._preferencesProviderTypeChanged(data.type); } else { @@ -193,6 +194,10 @@ function (util, metadata, xhr, declare, array, domConstruct, win, query, json, _ { this.reset(); } + else + { + this._toggleWidgets(this.preferencesProviderTypeWidget.value); + } }, }); }); 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 index b158b9e051..b4c45d8f99 100644 --- 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 @@ -25,8 +25,6 @@ define(["dojo/dom","dojo/query", "dojo/_base/array", "dijit/registry","qpid/comm { init: function() { - // Readers are HTML5 - this.reader = window.FileReader ? new FileReader() : undefined; }, show: function(data) { @@ -34,79 +32,16 @@ define(["dojo/dom","dojo/query", "dojo/_base/array", "dijit/registry","qpid/comm 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.keyStoreOldBrowserWarning = dom.byId("addStore.oldBrowserWarning"); 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 + if (!window.FileReader) { - // 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) { @@ -115,27 +50,20 @@ define(["dojo/dom","dojo/query", "dojo/_base/array", "dijit/registry","qpid/comm array.forEach(widgets, function(item) { var name = item.id.replace("addStore.",""); - if (name in attributes && item.type != "password") + if (name in attributes ) { - item.set("value", effectiveData[name]); + var attribute = attributes[name]; + if (attribute.secure || attribute.oversize) + { + item.set("required", false); + item.set("placeHolder", effectiveData[name]); + } + else + { + 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); - } } }; 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 index 9d113a9d9e..e04ee1a835 100644 --- 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 @@ -25,8 +25,6 @@ define(["dojo/dom","dojo/query", "dojo/_base/array", "dijit/registry","qpid/comm { init: function() { - // Readers are HTML5 - this.reader = window.FileReader ? new FileReader() : undefined; }, show: function(data) { @@ -34,79 +32,17 @@ define(["dojo/dom","dojo/query", "dojo/_base/array", "dijit/registry","qpid/comm 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.keyStoreOldBrowserWarning = dom.byId("addStore.oldBrowserWarning"); 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 + if (!window.FileReader) { // 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) { @@ -115,27 +51,21 @@ define(["dojo/dom","dojo/query", "dojo/_base/array", "dijit/registry","qpid/comm array.forEach(widgets, function(item) { var name = item.id.replace("addStore.",""); - if (name in attributes && item.type != "password") + if (name in attributes ) { - item.set("value", effectiveData[name]); + var attribute = attributes[name]; + if (attribute.secure || attribute.oversize) + { + item.set("required", false); + item.set("placeHolder", effectiveData[name]); + } + else + { + 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); - } } }; diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/nonjavakeystore/add.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/nonjavakeystore/add.js new file mode 100644 index 0000000000..0d74699d79 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/nonjavakeystore/add.js @@ -0,0 +1,81 @@ +/* + * + * 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", "qpid/common/ResourceWidget"], + function (dom, query, array, registry, util, metadata) + { + var addKeyStore = + { + init: function() + { + }, + show: function(data) + { + var that=this; + util.parseHtmlIntoDiv(data.containerNode, "store/nonjavakeystore/add.html"); + + this.keyStoreOldBrowserWarning = dom.byId("addStore.oldBrowserWarning"); + this.addButton = data.parent.addButton; + this.containerNode = data.containerNode; + + if (!window.FileReader) + { + this.keyStoreOldBrowserWarning.innerHTML = "File upload requires a more recent browser with HTML5 support"; + this.keyStoreOldBrowserWarning.className = this.keyStoreOldBrowserWarning.className.replace("hidden", ""); + } + }, + update: function(effectiveData) + { + if (effectiveData) + { + var attributes = metadata.getMetaData("KeyStore", "NonJavaKeyStore").attributes; + var widgets = registry.findWidgets(this.containerNode); + array.forEach(widgets, function(item) + { + var name = item.id.replace("addStore.",""); + if (name in attributes ) + { + var attribute = attributes[name]; + if (attribute.oversize || attribute.secure) + { + item.set("required", false); + item.set("placeHolder", effectiveData[name]); + } + else + { + item.set("value", effectiveData[name]); + } + } + }); + } + } + }; + + 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/nonjavakeystore/show.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/nonjavakeystore/show.js new file mode 100644 index 0000000000..c31b020e3e --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/nonjavakeystore/show.js @@ -0,0 +1,61 @@ +/* + * 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", "qpid/management/UserPreferences", "dojox/html/entities", "dojo/domReady!"], + function (util, metadata, UserPreferences, entities) + { + + function toDate(value) + { + return value ? entities.encode(String(UserPreferences.formatDateTime(value, {addOffset: true, appendTimeZone: true}))) : ""; + } + + var dateFields = ["certificateValidEnd","certificateValidStart"]; + + function NonJavaKeyStore(data) + { + this.fields = []; + var attributes = metadata.getMetaData("KeyStore", "NonJavaKeyStore").attributes; + for(var name in attributes) + { + if (dateFields.indexOf(name) == -1) + { + this.fields.push(name); + } + } + var allFields = this.fields.concat(dateFields); + util.buildUI(data.containerNode, data.parent, "store/nonjavakeystore/show.html",allFields, this); + } + + NonJavaKeyStore.prototype.update = function(data) + { + util.updateUI(data, this.fields, this); + if (data) + { + for(var idx in dateFields) + { + var name = dateFields[idx]; + this[name].innerHTML = toDate(data[name]); + } + } + } + + return NonJavaKeyStore; + } +); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/nonjavatruststore/add.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/nonjavatruststore/add.js new file mode 100644 index 0000000000..53e3b43082 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/nonjavatruststore/add.js @@ -0,0 +1,81 @@ +/* + * + * 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() + { + }, + show: function(data) + { + var that=this; + util.parseHtmlIntoDiv(data.containerNode, "store/nonjavatruststore/add.html"); + + this.keyStoreOldBrowserWarning = dom.byId("addStore.oldBrowserWarning"); + this.addButton = data.parent.addButton; + this.containerNode = data.containerNode; + + if (!window.FileReader) + { + this.keyStoreOldBrowserWarning.innerHTML = "File upload requires a more recent browser with HTML5 support"; + this.keyStoreOldBrowserWarning.className = this.keyStoreOldBrowserWarning.className.replace("hidden", ""); + } + }, + update: function(effectiveData) + { + if (effectiveData) + { + var attributes = metadata.getMetaData("TrustStore", "NonJavaTrustStore").attributes; + var widgets = registry.findWidgets(this.containerNode); + array.forEach(widgets, function(item) + { + var name = item.id.replace("addStore.",""); + if (name in attributes ) + { + var attribute = attributes[name]; + if (attribute.oversize || attribute.secure) + { + item.set("required", false); + item.set("placeHolder", effectiveData[name]); + } + else + { + item.set("value", effectiveData[name]); + } + } + }); + } + } + }; + + 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/nonjavatruststore/show.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/nonjavatruststore/show.js new file mode 100644 index 0000000000..89b0b5d88f --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/nonjavatruststore/show.js @@ -0,0 +1,67 @@ +/* + * 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/query", + "qpid/common/util", + "qpid/common/metadata", + "dojox/grid/DataGrid", + "qpid/common/UpdatableStore", + "qpid/management/UserPreferences", + "dojo/domReady!"], + function (query, util, metadata, DataGrid, UpdatableStore, UserPreferences) + { + + + function NonJavaTrustStore(data) + { + this.fields = []; + var attributes = metadata.getMetaData("TrustStore", "NonJavaTrustStore").attributes; + for(var name in attributes) + { + this.fields.push(name); + } + util.buildUI(data.containerNode, data.parent, "store/nonjavatruststore/show.html", this.fields, this); + var gridNode = query(".details", data.containerNode)[0]; + var dateTimeFormatter = function(value){ return value ? UserPreferences.formatDateTime(value, {addOffset: true, appendTimeZone: true}) : "";}; + this.detailsGrid = new UpdatableStore([], + gridNode, + [ + { name: 'Subject', field: 'SUBJECT_NAME', width: '25%' }, + { name: 'Issuer', field: 'ISSUER_NAME', width: '25%' }, + { name: 'Valid from', field: 'VALID_START', width: '25%', formatter: dateTimeFormatter }, + { name: 'Valid to', field: 'VALID_END', width: '25%', formatter: dateTimeFormatter} + ]); + } + + NonJavaTrustStore.prototype.update = function(data) + { + util.updateUI(data, this.fields, this); + var details = data.certificateDetails; + for(var i=0; i < details.length; i++) + { + details[i].id = details[i].SUBJECT_NAME + "_" + details[i].ISSUER_NAME + "_" + details[i].VALID_START + "_" + details[i].VALID_END; + } + this.detailsGrid.grid.beginUpdate(); + this.detailsGrid.update(details); + this.detailsGrid.grid.endUpdate(); + } + + return NonJavaTrustStore; + } +); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/login.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/login.html index aaa2855bd2..6e7f05e41b 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/login.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/login.html @@ -104,7 +104,7 @@ <div data-dojo-type="dijit.form.ValidationTextBox" type="password" id="password" name="password" data-dojo-props="label:'Password:',required:true, intermediateChanges:true"></div> </div> </div> - <div class="dijitDialogPaneActionBar"> + <div class="dijitDialogPaneActionBar qpidDialogPaneActionBar"> <button data-dojo-type="dijit.form.Button" type="submit" id="loginButton">Login</button> </div> </div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/logs/showLogFileDownloadDialog.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/logs/showLogFileDownloadDialog.html index bc633d059a..d48682a566 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/logs/showLogFileDownloadDialog.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/logs/showLogFileDownloadDialog.html @@ -23,7 +23,7 @@ <div><b>Select log files to download</b></div> <div class="logFilesGrid" style='height:300px;width: 580px'></div> </div> - <div class="dijitDialogPaneActionBar"> + <div class="dijitDialogPaneActionBar qpidDialogPaneActionBar"> <button value="Download" data-dojo-type="dijit.form.Button" class="downloadLogsButton" data-dojo-props="iconClass: 'downloadLogsIcon', label: 'Download' "></button> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/preferencesprovider/preferencesProviderForm.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/preferencesprovider/preferencesProviderForm.html index 979b3abe8d..b995d4e8dd 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/preferencesprovider/preferencesProviderForm.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/preferencesprovider/preferencesProviderForm.html @@ -23,7 +23,7 @@ <div class="formBox"> <fieldset> <legend>Preferences Provider</legend> - <div class="clear"> + <div class="clear hidden"> <div class="formLabel-labelCell tableContainer-labelCell">Name*:</div> <div class="formLabel-controlCell tableContainer-valueCell"> <input type="text" diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/showAuthProvider.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/showAuthProvider.html index a669d7800d..992da02027 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/showAuthProvider.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/showAuthProvider.html @@ -37,7 +37,6 @@ <div class="clear dijitDialogPaneActionBar"> <button data-dojo-type="dijit.form.Button" class="editAuthenticationProviderButton" type="button" data-dojo-props="disabled: true">Edit</button> <button data-dojo-type="dijit.form.Button" class="deleteAuthenticationProviderButton" type="button">Delete</button> - <button data-dojo-type="dijit.form.Button" class="addPreferencesProviderButton">Add Preferences Provider</button> </div> </div> <br/> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/showGroupProvider.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/showGroupProvider.html index e095a0a427..3793a4407a 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/showGroupProvider.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/showGroupProvider.html @@ -35,9 +35,10 @@ <div class="clear"></div> <div class="providerDetails"></div> - + <br/> <div class="dijitDialogPaneActionBar"> - <input class="deleteGroupProviderButton" type="button" value="Delete Group provider" label="Delete Group Provider" dojoType="dijit.form.Button" /> + <input class="deleteGroupProviderButton" type="button" value="Delete" label="Delete" data-dojo-type="dijit.form.Button" /> + <input class="editGroupProviderButton" type="button" value="Edit" label="Edit" data-dojo-type="dijit.form.Button" data-dojo-props="disabled:true"/> </div> </div> </div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/showPreferences.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/showPreferences.html index 2695d8f099..8dff5132bd 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/showPreferences.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/showPreferences.html @@ -40,7 +40,7 @@ </tr> </table> </div> - <div class="dijitDialogPaneActionBar"> + <div class="dijitDialogPaneActionBar qpidDialogPaneActionBar"> <button data-dojo-type="dijit/form/Button" data-dojo-props="label: 'Set'" id="preferences.setButton">Set</button> <button data-dojo-type="dijit/form/Button" data-dojo-props="label: 'Set and Close'" id="preferences.setAndCloseButton">Set and Close</button> </div> @@ -70,7 +70,7 @@ </tr> </thead> </table> - <div class="dijitDialogPaneActionBar"> + <div class="dijitDialogPaneActionBar qpidDialogPaneActionBar"> <button id="preferences.deleteButton" data-dojo-type="dijit/form/Button" data-dojo-props="label:'Delete', title:'Delete preferences for selected users'">Delete</button> <button id="preferences.deleteAndCloseButton" data-dojo-type="dijit/form/Button" data-dojo-props="label: 'Delete and Close', title:'Delete preferences for selected users and close the dialog'">Delete and Close</button> </div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/showPreferencesProvider.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/showPreferencesProvider.html index 5d14aace76..49eb355ff3 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/showPreferencesProvider.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/showPreferencesProvider.html @@ -25,10 +25,6 @@ <div class="preferencesProviderType"></div> </div> <div class="clear"> - <div class="formLabel-labelCell">Name:</div> - <div class="preferencesProviderName"></div> - </div> - <div class="clear"> <div class="formLabel-labelCell">State:</div> <div class="preferencesProviderState"></div> </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 index 1732688ba7..676ae4007b 100644 --- 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 @@ -22,42 +22,14 @@ <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" + <input type="text" id="addStore.storeUrl" + data-dojo-type="qpid/common/ResourceWidget" data-dojo-props=" - name: 'serverPath', + name: 'storeUrl', 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"> 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 index 36180d8a39..15b1692300 100644 --- 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 @@ -22,39 +22,14 @@ <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" + <input type="text" id="addStore.storeUrl" + data-dojo-type="qpid/common/ResourceWidget" data-dojo-props=" - name: 'serverPath', + name: 'storeUrl', 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> 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 index 1c3744b83c..99190d1f90 100644 --- 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 @@ -19,8 +19,8 @@ <div> <div class="clear"> - <div class="formLabel-labelCell">Path:</div> - <div ><span class="path" ></span></div> + <div class="formLabel-labelCell">Store Url:</div> + <div ><span class="storeUrl" ></span></div> </div> <div class="clear"> <div class="formLabel-labelCell">Peers only:</div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/store/nonjavakeystore/add.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/store/nonjavakeystore/add.html new file mode 100644 index 0000000000..b7af1c6b47 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/store/nonjavakeystore/add.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> + <div id="addStore.oldBrowserWarning" class="infoMessage hidden clear"></div> + + <div class="clear"> + <div id="addStore.privateKeyLabel" class="formLabel-labelCell tableContainer-labelCell">Private Key (Server path or upload)*:</div> + <div class="formLabel-controlCell tableContainer-valueCell"> + <input type="text" id="addStore.privateKeyUrl" + data-dojo-type="qpid/common/ResourceWidget" + data-dojo-props=" + name: 'privateKeyUrl', + placeHolder: 'path to file with private key in PEM/DER format', + required: true, + promptMessage: 'Enter broker server path to file containing unencrypted private key in DER or PEM format', + title: 'Enter broker server path to file containing unencrypted private key in DER or PEM format'" /> + + </div> + </div> + + <div class="clear"> + <div id="addStore.serverPathLabel" class="formLabel-labelCell tableContainer-labelCell">Certificate (Server path or upload)*:</div> + <div class="formLabel-controlCell tableContainer-valueCell"> + <input type="text" id="addStore.certificateUrl" + data-dojo-type="qpid/common/ResourceWidget" + data-dojo-props=" + name: 'certificateUrl', + placeHolder: 'path to file with certificate in PEM/DER format', + required: true, + promptMessage: 'Enter broker server path to file containing certificate in DER or PEM format', + title: 'Enter broker server path to file containing certificate in DER or PEM format'" /> + </div> + </div> + + <div class="clear"> + <div id="addStore.intermediateCertificateLabel" class="formLabel-labelCell tableContainer-labelCell">Intermediate Certificates (Server path or upload):</div> + <div class="formLabel-controlCell tableContainer-valueCell"> + <input type="text" id="addStore.intermediateCertificateUrl" + data-dojo-type="qpid/common/ResourceWidget" + data-dojo-props=" + name: 'intermediateCertificateUrl', + placeHolder: 'path to file with certificates in PEM/DER format', + required: false, + promptMessage: 'Enter broker server path to file containing intermediate certificates in DER or PEM format', + title: 'Enter path to file containing intermediate certificates in format DER or PEM'" /> + </div> + </div> +</div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/store/nonjavakeystore/show.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/store/nonjavakeystore/show.html new file mode 100644 index 0000000000..51ebd06012 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/store/nonjavakeystore/show.html @@ -0,0 +1,47 @@ +<!-- + ~ 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 privateKeyUrlContainer"> + <div class="formLabel-labelCell">Private Key:</div> + <div ><span class="privateKeyUrl" ></span></div> + </div> + <div class="clear certificateUrlContainer"> + <div class="formLabel-labelCell">Certificate:</div> + <div><span class="certificateUrl" ></span></div> + </div> + <div class="clear intermediateCertificateUrlContainer"> + <div class="formLabel-labelCell">Intermediate Certificate:</div> + <div><span class="intermediateCertificateUrl" ></span></div> + </div> + <div class="clear"> + <div class="formLabel-labelCell">Subject:</div> + <div><span class="subjectName" ></span></div> + </div> + <div class="clear"> + <div class="formLabel-labelCell">Certificate valid to:</div> + <div><span class="certificateValidEnd" ></span></div> + </div> + <div class="clear"> + <div class="formLabel-labelCell">Certificate valid from:</div> + <div><span class="certificateValidStart" ></span></div> + </div> + <div class="clear"></div> +</div> + diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/store/nonjavatruststore/add.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/store/nonjavatruststore/add.html new file mode 100644 index 0000000000..4ec2678575 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/store/nonjavatruststore/add.html @@ -0,0 +1,38 @@ +<!-- + ~ 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.certificatesLabel" class="formLabel-labelCell tableContainer-labelCell">Certificates (Server path or upload)*:</div> + <div class="formLabel-controlCell tableContainer-valueCell"> + <input type="text" id="addStore.certificatesUrl" + data-dojo-type="qpid/common/ResourceWidget" + data-dojo-props=" + name: 'certificatesUrl', + placeHolder: 'path to file with certificate(s) in PEM/DER format', + required: true, + promptMessage: 'Enter broker server path to file containing certificate(s) in DER or PEM format', + title: 'Enter broker server path to file containing certificate(s) in DER or PEM format'" /> + </div> + </div> + +</div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/store/nonjavatruststore/show.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/store/nonjavatruststore/show.html new file mode 100644 index 0000000000..b45f457e41 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/store/nonjavatruststore/show.html @@ -0,0 +1,31 @@ +<!-- + ~ 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 certificatesUrlContainer"> + <div class="formLabel-labelCell">Certificate:</div> + <div><span class="certificatesUrl" ></span></div> + </div> + <div class="clear"></div> + <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Certificate details'" class="detailsGridPanel"> + <div class="details"></div> + </div> + <div></div> +</div> + diff --git a/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/ConfiguredObjectToMapConverterTest.java b/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/ConfiguredObjectToMapConverterTest.java index ac595154bb..b3c9bd911f 100644 --- a/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/ConfiguredObjectToMapConverterTest.java +++ b/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/ConfiguredObjectToMapConverterTest.java @@ -20,6 +20,7 @@ package org.apache.qpid.server.management.plugin.servlet.rest; import static org.apache.qpid.server.management.plugin.servlet.rest.ConfiguredObjectToMapConverter.STATISTICS_MAP_KEY; +import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; @@ -27,6 +28,7 @@ import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -37,6 +39,8 @@ import java.util.Set; import junit.framework.TestCase; import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.ConfiguredObjectAttribute; +import org.apache.qpid.server.model.ConfiguredObjectTypeRegistry; import org.apache.qpid.server.model.Model; public class ConfiguredObjectToMapConverterTest extends TestCase @@ -57,8 +61,15 @@ public class ConfiguredObjectToMapConverterTest extends TestCase when(_configuredObject.getStatistics()).thenReturn(Collections.singletonMap(statisticName, (Number) statisticValue)); - Map<String, Object> resultMap = _converter.convertObjectToMap(_configuredObject, ConfiguredObject.class, 0, - false, false, false); + Map<String, Object> resultMap = _converter.convertObjectToMap(_configuredObject, + ConfiguredObject.class, + 0, + false, + false, + false, + false, + 120, + false); Map<String, Object> statsAsMap = (Map<String, Object>) resultMap.get(STATISTICS_MAP_KEY); assertNotNull("Statistics should be part of map", statsAsMap); assertEquals("Unexpected number of statistics", 1, statsAsMap.size()); @@ -69,10 +80,19 @@ public class ConfiguredObjectToMapConverterTest extends TestCase { final String attributeName = "attribute"; final String attributeValue = "value"; + Model model = createTestModel(); + when(_configuredObject.getModel()).thenReturn(model); configureMockToReturnOneAttribute(_configuredObject, attributeName, attributeValue); - Map<String, Object> resultMap = _converter.convertObjectToMap(_configuredObject, ConfiguredObject.class, 0, - false, false, false); + Map<String, Object> resultMap = _converter.convertObjectToMap(_configuredObject, + ConfiguredObject.class, + 0, + false, + false, + false, + false, + 120, + false); assertEquals("Unexpected number of attributes", 1, resultMap.size()); assertEquals("Unexpected attribute value", attributeValue, resultMap.get(attributeName)); } @@ -89,8 +109,15 @@ public class ConfiguredObjectToMapConverterTest extends TestCase configureMockToReturnOneAttribute(_configuredObject, attributeName, attributeValue); - Map<String, Object> resultMap = _converter.convertObjectToMap(_configuredObject, ConfiguredObject.class, 0, - false, false, false); + Map<String, Object> resultMap = _converter.convertObjectToMap(_configuredObject, + ConfiguredObject.class, + 0, + false, + false, + false, + false, + 120, + false); assertEquals("Unexpected number of attributes", 1, resultMap.size()); assertEquals("Unexpected attribute value", "attributeConfiguredObjectName", resultMap.get(attributeName)); } @@ -108,8 +135,15 @@ public class ConfiguredObjectToMapConverterTest extends TestCase configureMockToReturnOneAttribute(mockChild, childAttributeName, childAttributeValue); when(_configuredObject.getChildren(TestChild.class)).thenReturn(Arrays.asList(mockChild)); - Map<String, Object> resultMap = _converter.convertObjectToMap(_configuredObject, ConfiguredObject.class, 1, - false, false, false); + Map<String, Object> resultMap = _converter.convertObjectToMap(_configuredObject, + ConfiguredObject.class, + 1, + false, + false, + false, + false, + 120, + false); assertEquals("Unexpected parent map size", 1, resultMap.size()); final List<Map<String, Object>> childList = (List<Map<String, Object>>) resultMap.get("testchilds"); @@ -146,8 +180,15 @@ public class ConfiguredObjectToMapConverterTest extends TestCase when(_configuredObject.getChildren(TestChild.class)).thenReturn(Arrays.asList(mockChild)); - Map<String, Object> resultMap = _converter.convertObjectToMap(_configuredObject, ConfiguredObject.class, 1, true, - false, false); + Map<String, Object> resultMap = _converter.convertObjectToMap(_configuredObject, + ConfiguredObject.class, + 1, + true, + false, + false, + false, + 120, + false); assertEquals("Unexpected parent map size", 2, resultMap.size()); assertEquals("Incorrect context", resultMap.get(ConfiguredObject.CONTEXT), actualContext); List<Map<String, Object>> childList = (List<Map<String, Object>>) resultMap.get("testchilds"); @@ -158,7 +199,15 @@ public class ConfiguredObjectToMapConverterTest extends TestCase assertEquals("Unexpected child attribute value", childActualAttributeValue, childMap.get(childAttributeName)); - resultMap = _converter.convertObjectToMap(_configuredObject, ConfiguredObject.class, 1, false, false, false); + resultMap = _converter.convertObjectToMap(_configuredObject, + ConfiguredObject.class, + 1, + false, + false, + false, + false, + 120, + false); assertEquals("Unexpected parent map size", 2, resultMap.size()); Map<String, Object> inheritedContext = new HashMap<>(); inheritedContext.put("key","value"); @@ -174,12 +223,177 @@ public class ConfiguredObjectToMapConverterTest extends TestCase } + public void testOversizedAttributes() + { + + Model model = createTestModel(); + ConfiguredObjectTypeRegistry typeRegistry = model.getTypeRegistry(); + final Map<String, ConfiguredObjectAttribute<?, ?>> attributeTypes = + typeRegistry.getAttributeTypes(TestChild.class); + final ConfiguredObjectAttribute longAttr = mock(ConfiguredObjectAttribute.class); + when(longAttr.isOversized()).thenReturn(true); + when(longAttr.getOversizedAltText()).thenReturn(""); + when(attributeTypes.get(eq("longAttr"))).thenReturn(longAttr); + + TestChild mockChild = mock(TestChild.class); + when(mockChild.getModel()).thenReturn(model); + when(_configuredObject.getModel()).thenReturn(model); + configureMockToReturnOneAttribute(mockChild, "longAttr", "this is not long"); + when(_configuredObject.getChildren(TestChild.class)).thenReturn(Arrays.asList(mockChild)); + + + Map<String, Object> resultMap = _converter.convertObjectToMap(_configuredObject, + ConfiguredObject.class, + 1, + false, + false, + false, + false, + 20, + false); + Object children = resultMap.get("testchilds"); + assertNotNull(children); + assertTrue(children instanceof Collection); + assertTrue(((Collection)children).size()==1); + Object attrs = ((Collection)children).iterator().next(); + assertTrue(attrs instanceof Map); + assertEquals("this is not long", ((Map) attrs).get("longAttr")); + + + + resultMap = _converter.convertObjectToMap(_configuredObject, + ConfiguredObject.class, + 1, + false, + false, + false, + false, + 8, + false); + + children = resultMap.get("testchilds"); + assertNotNull(children); + assertTrue(children instanceof Collection); + assertTrue(((Collection)children).size()==1); + attrs = ((Collection)children).iterator().next(); + assertTrue(attrs instanceof Map); + assertEquals("this...", ((Map) attrs).get("longAttr")); + + + + + when(longAttr.getOversizedAltText()).thenReturn("test alt text"); + + resultMap = _converter.convertObjectToMap(_configuredObject, + ConfiguredObject.class, + 1, + false, + false, + false, + false, + 8, + false); + + children = resultMap.get("testchilds"); + assertNotNull(children); + assertTrue(children instanceof Collection); + assertTrue(((Collection)children).size()==1); + attrs = ((Collection)children).iterator().next(); + assertTrue(attrs instanceof Map); + assertEquals("test alt text", ((Map) attrs).get("longAttr")); + + + } + + public void testSecureAttributes() + { + + Model model = createTestModel(); + ConfiguredObjectTypeRegistry typeRegistry = model.getTypeRegistry(); + Map<String, ConfiguredObjectAttribute<?, ?>> attributeTypes = typeRegistry.getAttributeTypes(TestChild.class); + ConfiguredObjectAttribute secureAttribute = mock(ConfiguredObjectAttribute.class); + when(secureAttribute.isSecure()).thenReturn(true); + when(attributeTypes.get(eq("secureAttribute"))).thenReturn(secureAttribute); + + TestChild mockChild = mock(TestChild.class); + when(mockChild.getModel()).thenReturn(model); + when(_configuredObject.getModel()).thenReturn(model); + + // set encoded value + configureMockToReturnOneAttribute(mockChild, "secureAttribute", "*****"); + + // set actual values + when(mockChild.getActualAttributes()).thenReturn(Collections.singletonMap("secureAttribute", "secret")); + when(_configuredObject.getChildren(TestChild.class)).thenReturn(Arrays.asList(mockChild)); + when(model.getParentTypes(TestChild.class)).thenReturn(Collections.<Class<? extends ConfiguredObject>>singleton(TestChild.class)); + when(_configuredObject.getCategoryClass()).thenReturn(TestChild.class); + when(mockChild.isDurable()).thenReturn(true); + + Map<String, Object> resultMap = _converter.convertObjectToMap(_configuredObject, + ConfiguredObject.class, + 1, + false, + false, + false, + false, + 20, + false); + Object children = resultMap.get("testchilds"); + assertNotNull(children); + assertTrue(children instanceof Collection); + assertTrue(((Collection)children).size()==1); + Object attrs = ((Collection)children).iterator().next(); + assertTrue(attrs instanceof Map); + assertEquals("*****", ((Map) attrs).get("secureAttribute")); + + resultMap = _converter.convertObjectToMap(_configuredObject, + ConfiguredObject.class, + 1, + true, + true, + false, + true, + 20, + true); + + children = resultMap.get("testchilds"); + assertNotNull(children); + assertTrue(children instanceof Collection); + assertTrue(((Collection)children).size()==1); + attrs = ((Collection)children).iterator().next(); + assertTrue(attrs instanceof Map); + assertEquals("secret", ((Map) attrs).get("secureAttribute")); + + resultMap = _converter.convertObjectToMap(_configuredObject, + ConfiguredObject.class, + 1, + true, + true, + false, + false, + 20, + true); + + children = resultMap.get("testchilds"); + assertNotNull(children); + assertTrue(children instanceof Collection); + assertTrue(((Collection)children).size()==1); + attrs = ((Collection)children).iterator().next(); + assertTrue(attrs instanceof Map); + assertEquals("*****", ((Map) attrs).get("secureAttribute")); + } + private Model createTestModel() { Model model = mock(Model.class); final List<Class<? extends ConfiguredObject>> list = new ArrayList<Class<? extends ConfiguredObject>>(); list.add(TestChild.class); when(model.getChildTypes(ConfiguredObject.class)).thenReturn(list); + final ConfiguredObjectTypeRegistry typeRegistry = mock(ConfiguredObjectTypeRegistry.class); + final Map<String, ConfiguredObjectAttribute<?, ?>> attrTypes = mock(Map.class); + when(attrTypes.get(any(String.class))).thenReturn(mock(ConfiguredObjectAttribute.class)); + when(typeRegistry.getAttributeTypes(any(Class.class))).thenReturn(attrTypes); + when(model.getTypeRegistry()).thenReturn(typeRegistry); return model; } diff --git a/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java b/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java index 78eba66158..040973ff6e 100644 --- a/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java +++ b/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java @@ -36,6 +36,7 @@ import java.rmi.server.RMIServerSocketFactory; import java.rmi.server.UnicastRemoteObject; import java.security.GeneralSecurityException; import java.util.HashMap; +import java.util.Set; import javax.management.JMException; import javax.management.MBeanServer; @@ -142,11 +143,9 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry throw new ServerScopedRuntimeException("Unable to create SSLContext for key store", e); } - getEventLogger().message(ManagementConsoleMessages.SSL_KEYSTORE(keyStore.getName())); - //create the SSL RMI socket factories csf = new SslRMIClientSocketFactory(); - ssf = new QpidSslRMIServerSocketFactory(sslContext); + ssf = new QpidSslRMIServerSocketFactory(sslContext,_connectorPort.getEnabledCipherSuites(), _connectorPort.getDisabledCipherSuites()); } else { @@ -252,8 +251,12 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry _cs.start(); - String connectorServer = (connectorSslEnabled ? "SSL " : "") + "JMX RMIConnectorServer"; - getEventLogger().message(ManagementConsoleMessages.LISTENING(connectorServer, jmxPortConnectorServer)); + Set<Transport> connectorTransports = _connectorPort.getTransports(); + for (Transport transport: connectorTransports) + { + getEventLogger().message(ManagementConsoleMessages.LISTENING("JMX RMIConnectorServer", transport.name(), jmxPortConnectorServer)); + } + getEventLogger().message(ManagementConsoleMessages.READY(OPERATIONAL_LOGGING_NAME)); } @@ -263,7 +266,7 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry final RMIServerSocketFactory ssf = getRmiServerSocketFactory(useCustomRmiRegistry); Registry rmiRegistry = LocateRegistry.createRegistry(jmxPortRegistryServer, null, ssf); - getEventLogger().message(ManagementConsoleMessages.LISTENING("RMI Registry", jmxPortRegistryServer)); + getEventLogger().message(ManagementConsoleMessages.LISTENING("RMI Registry", Transport.TCP.name(), jmxPortRegistryServer)); return rmiRegistry; } diff --git a/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/QpidSslRMIServerSocketFactory.java b/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/QpidSslRMIServerSocketFactory.java index 5c15a40427..8af9d87672 100644 --- a/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/QpidSslRMIServerSocketFactory.java +++ b/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/QpidSslRMIServerSocketFactory.java @@ -24,6 +24,7 @@ import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; +import java.util.Collection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; @@ -35,6 +36,8 @@ import org.apache.qpid.transport.network.security.ssl.SSLUtil; public class QpidSslRMIServerSocketFactory extends SslRMIServerSocketFactory { private final SSLContext _sslContext; + private final Collection<String> _enabledCipherSuites; + private final Collection<String> _disabledCipherSuites; /** * SslRMIServerSocketFactory which creates the ServerSocket using the @@ -43,9 +46,12 @@ public class QpidSslRMIServerSocketFactory extends SslRMIServerSocketFactory * key store. * * @param sslContext previously created sslContext using the desired key store. - * @throws NullPointerException if the provided {@link SSLContext} is null. + * @param enabledCipherSuites + *@param disabledCipherSuites @throws NullPointerException if the provided {@link SSLContext} is null. */ - public QpidSslRMIServerSocketFactory(SSLContext sslContext) throws NullPointerException + public QpidSslRMIServerSocketFactory(SSLContext sslContext, + final Collection<String> enabledCipherSuites, + final Collection<String> disabledCipherSuites) throws NullPointerException { super(); @@ -55,6 +61,8 @@ public class QpidSslRMIServerSocketFactory extends SslRMIServerSocketFactory } _sslContext = sslContext; + _enabledCipherSuites = enabledCipherSuites; + _disabledCipherSuites = disabledCipherSuites; //TODO: settings + implementation for SSL client auth, updating equals and hashCode appropriately. } @@ -77,6 +85,7 @@ public class QpidSslRMIServerSocketFactory extends SslRMIServerSocketFactory true); sslSocket.setUseClientMode(false); SSLUtil.removeSSLv3Support(sslSocket); + SSLUtil.updateEnabledCipherSuites(sslSocket, _enabledCipherSuites, _disabledCipherSuites); return sslSocket; } }; diff --git a/qpid/java/broker/bin/qpid-server.bat b/qpid/java/broker/bin/qpid-server.bat index 9c3403edc7..de10e72483 100755 --- a/qpid/java/broker/bin/qpid-server.bat +++ b/qpid/java/broker/bin/qpid-server.bat @@ -20,6 +20,8 @@ @echo off
REM Script to run the Qpid Java Broker
+SETLOCAL
+
rem Guess QPID_HOME if not defined
set CURRENT_DIR=%cd%
if not "%QPID_HOME%" == "" goto gotHome
@@ -199,3 +201,4 @@ if "%debug%" == "true" echo %COMMAND% %COMMAND%
:end
+ENDLOCAL
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java index f4c6926a17..85fe7af0fb 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java @@ -42,6 +42,7 @@ import org.apache.qpid.common.QpidProperties; import org.apache.qpid.framing.ProtocolVersion; import org.apache.qpid.server.configuration.IllegalConfigurationException; import org.apache.qpid.server.util.Action; +import org.apache.qpid.server.util.StringUtil; import org.apache.qpid.util.FileUtils; /** @@ -50,6 +51,8 @@ import org.apache.qpid.util.FileUtils; */ public class Main { + private static final int MANAGEMENT_MODE_PASSWORD_LENGTH = 10; + private static final Option OPTION_HELP = new Option("h", "help", false, "print this message"); private static final Option OPTION_VERSION = new Option("v", "version", false, "print the version information and exit"); @@ -305,10 +308,11 @@ public class Main options.setManagementModeQuiesceVirtualHosts(quiesceVhosts); String password = _commandLine.getOptionValue(OPTION_MM_PASSWORD.getOpt()); - if (password != null) + if (password == null) { - options.setManagementModePassword(password); + password = new StringUtil().randomAlphaNumericString(MANAGEMENT_MODE_PASSWORD_LENGTH); } + options.setManagementModePassword(password); } setExceptionHandler(); @@ -328,14 +332,19 @@ public class Main initialPropertiesLocation = (new File(initialProperties)).toURI().toURL(); } - Properties props = new Properties(); - props.load(initialPropertiesLocation.openStream()); + Properties props = new Properties(QpidProperties.asProperties()); + if(initialPropertiesLocation != null) + { + props.load(initialPropertiesLocation.openStream()); + } + Set<String> propertyNames = new HashSet<>(props.stringPropertyNames()); propertyNames.removeAll(System.getProperties().stringPropertyNames()); - for(String propName : propertyNames) + for (String propName : propertyNames) { System.setProperty(propName, props.getProperty(propName)); } + } private void copyInitialConfigFile(final BrokerOptions options, final File destinationFile) diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java index 850fa993f5..636048cac2 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java @@ -188,7 +188,7 @@ public class MainTest extends QpidTestCase assertTrue(options.isManagementMode()); assertEquals(password, options.getManagementModePassword()); - options = startDummyMain("-mmpass " + password); + options = startDummyMain("-mm -mmpass " + password); assertNotNull(options.getManagementModePassword()); } diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java index 70d91ad817..4c596b88a0 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java @@ -32,6 +32,7 @@ import java.util.LinkedList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; @@ -64,7 +65,9 @@ import org.apache.qpid.AMQUnresolvedAddressException; import org.apache.qpid.client.failover.FailoverException; import org.apache.qpid.client.failover.FailoverProtectedOperation; import org.apache.qpid.client.protocol.AMQProtocolHandler; +import org.apache.qpid.client.security.CallbackHandlerRegistry; import org.apache.qpid.client.state.AMQStateManager; +import org.apache.qpid.common.QpidProperties; import org.apache.qpid.configuration.ClientProperties; import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; @@ -192,6 +195,22 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect private boolean _compressMessages; private int _messageCompressionThresholdSize; + static + { + if (_logger.isDebugEnabled()) + { + _logger.debug("Qpid version : " + QpidProperties.getVersionString()); + } + + // The registering of any additional SASL mechanisms with the Java Security API requires + // SecurityManager permissions. In execution environments such as web containers, + // this may require adjustments to the Java security.policy. + CallbackHandlerRegistry registry = CallbackHandlerRegistry.getInstance(); + if (_logger.isDebugEnabled()) + { + _logger.debug("Loaded mechanisms " + registry.getMechanisms()); + } + } /** * @param broker brokerdetails * @param username username @@ -847,13 +866,17 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect public void close(long timeout) throws JMSException { - close(new ArrayList<AMQSession>(_sessions.values()), timeout); - } + boolean closed; - public void close(List<AMQSession> sessions, long timeout) throws JMSException - { - if (!setClosed()) + synchronized (_sessionCreationLock) + { + closed = setClosed(); + } + + if (!closed) { + List<AMQSession> sessions = new ArrayList<>(_sessions.values()); + setClosing(true); try { @@ -868,54 +891,52 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect private void doClose(List<AMQSession> sessions, long timeout) throws JMSException { - synchronized (_sessionCreationLock) + if (!sessions.isEmpty()) { - if (!sessions.isEmpty()) + AMQSession session = sessions.remove(0); + synchronized (session.getMessageDeliveryLock()) { - AMQSession session = sessions.remove(0); - synchronized (session.getMessageDeliveryLock()) - { - doClose(sessions, timeout); - } + doClose(sessions, timeout); } - else + } + else + { + synchronized (getFailoverMutex()) { - synchronized (getFailoverMutex()) + try { try { - try - { - closeAllSessions(null, timeout); - } - finally - { - //This MUST occur after we have successfully closed all Channels/Sessions - shutdownTaskPool(timeout); - } + closeAllSessions(null, timeout); } - catch (JMSException e) + finally { - _logger.error("Error closing connection", e); - JMSException jmse = new JMSException("Error closing connection: " + e); - jmse.setLinkedException(e); - jmse.initCause(e); - throw jmse; + //This MUST occur after we have successfully closed all Channels/Sessions + shutdownTaskPool(timeout); } - finally + } + catch (JMSException e) + { + _logger.error("Error closing connection", e); + JMSException jmse = new JMSException("Error closing connection: " + e); + jmse.setLinkedException(e); + jmse.initCause(e); + throw jmse; + } + finally + { + try + { + _delegate.closeConnection(timeout); + } + catch (Exception e) { - try - { - _delegate.closeConnection(timeout); - } - catch (Exception e) - { - _logger.warn("Error closing underlying protocol connection", e); - } + _logger.warn("Error closing underlying protocol connection", e); } } } } + } private void shutdownTaskPool(final long timeout) @@ -1290,28 +1311,29 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect try { - // get the failover mutex before trying to close - synchronized (getFailoverMutex()) + // decide if we are going to close the session + if (hardError(cause)) { - // decide if we are going to close the session - if (hardError(cause)) - { - closer = (!setClosed()) || closer; - { - _logger.info("Closing AMQConnection due to :" + cause); - } - } - else + closer = (!setClosed()) || closer; { - _logger.info("Not a hard-error connection not closing: " + cause); + _logger.info("Closing AMQConnection due to :" + cause); } + } + else + { + _logger.info("Not a hard-error connection not closing: " + cause); + } - // if we are closing the connection, close sessions first - if (closer) + + // if we are closing the connection, close sessions first + if (closer) + { + // get the failover mutex before trying to close + synchronized (getFailoverMutex()) { try { - closeAllSessions(cause, -1); // FIXME: when doing this end up with RejectedExecutionException from executor. + closeAllSessions(cause, -1); } catch (JMSException e) { @@ -1328,16 +1350,32 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect private void deliverJMSExceptionToExceptionListenerOrLog(final JMSException je, final Throwable cause) { - // deliver the exception if there is a listener - ExceptionListener exceptionListener = getExceptionListenerNoCheck(); + final ExceptionListener exceptionListener = getExceptionListenerNoCheck(); if (exceptionListener != null) { - exceptionListener.onException(je); - } - else + performConnectionTask(new Runnable() + { + @Override + public void run() + { + // deliver the exception if there is a listener + try + { + exceptionListener.onException(je); + } + catch (RuntimeException e) + { + _logger.error("Exception occurred in ExceptionListener", e); + } + } + }); + } + else { _logger.error("Throwable Received but no listener set: " + cause); } + + } private boolean hardError(Throwable cause) @@ -1448,7 +1486,17 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect public void performConnectionTask(Runnable task) { - _taskPool.execute(task); + try + { + _taskPool.execute(task); + } + catch (RejectedExecutionException e) + { + if(!(isClosed() || isClosing())) + { + throw e; + } + } } public AMQSession getSession(int channelId) diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java index 4e9164c3b0..fdeab7ae70 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java @@ -291,7 +291,7 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec public void closed(Connection conn) { - ConnectionException exc = exception; + final ConnectionException exc = exception; exception = null; if (exc == null) @@ -299,7 +299,7 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec return; } - ConnectionClose close = exc.getClose(); + final ConnectionClose close = exc.getClose(); if (close == null || close.getReplyCode() == ConnectionCloseCode.CONNECTION_FORCED) { _conn.getProtocolHandler().setFailoverLatch(new CountDownLatch(1)); @@ -332,23 +332,31 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec _conn.setClosed(); - ExceptionListener listener = _conn.getExceptionListenerNoCheck(); + final ExceptionListener listener = _conn.getExceptionListenerNoCheck(); if (listener == null) { _logger.error("connection exception: " + conn, exc); } else { - String code = null; - if (close != null) + _conn.performConnectionTask(new Runnable() { - code = close.getReplyCode().toString(); - } + @Override + public void run() + { + String code = null; + if (close != null) + { + code = close.getReplyCode().toString(); + } + + JMSException ex = new JMSException(exc.getMessage(), code); + ex.setLinkedException(exc); + ex.initCause(exc); + listener.onException(ex); + } + }); - JMSException ex = new JMSException(exc.getMessage(), code); - ex.setLinkedException(exc); - ex.initCause(exc); - listener.onException(ex); } } diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java index 29460bb42d..12e9285af8 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java @@ -808,7 +808,16 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic */ public void close(long timeout) throws JMSException { - close(timeout, true); + synchronized (_messageDeliveryLock) + { + // We must close down all producers and consumers in an orderly fashion. This is the only method + // that can be called from a different thread of control from the one controlling the session. + synchronized (getFailoverMutex()) + { + + close(timeout, true); + } + } } private void close(long timeout, boolean sendClose) throws JMSException @@ -822,52 +831,44 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic if (!setClosed()) { setClosing(true); - synchronized (getFailoverMutex()) + // we pass null since this is not an error case + closeProducersAndConsumers(null); + + try { - // We must close down all producers and consumers in an orderly fashion. This is the only method - // that can be called from a different thread of control from the one controlling the session. - synchronized (_messageDeliveryLock) + // If the connection is open or we are in the process + // of closing the connection then send a cance + // no point otherwise as the connection will be gone + if (!_connection.isClosed() || _connection.isClosing()) { - // we pass null since this is not an error case - closeProducersAndConsumers(null); - - try - { - // If the connection is open or we are in the process - // of closing the connection then send a cance - // no point otherwise as the connection will be gone - if (!_connection.isClosed() || _connection.isClosing()) - { - if (sendClose) - { - sendClose(timeout); - } - } - } - catch (AMQException e) - { - JMSException jmse = new JMSException("Error closing session: " + e); - jmse.setLinkedException(e); - jmse.initCause(e); - throw jmse; - } - // This is ignored because the channel is already marked as closed so the fail-over process will - // not re-open it. - catch (FailoverException e) - { - _logger.debug( - "Got FailoverException during channel close, ignored as channel already marked as closed."); - } - catch (TransportException e) - { - throw toJMSException("Error closing session:" + e.getMessage(), e); - } - finally + if (sendClose) { - _connection.deregisterSession(_channelId); + sendClose(timeout); } } } + catch (AMQException e) + { + JMSException jmse = new JMSException("Error closing session: " + e); + jmse.setLinkedException(e); + jmse.initCause(e); + throw jmse; + } + // This is ignored because the channel is already marked as closed so the fail-over process will + // not re-open it. + catch (FailoverException e) + { + _logger.debug( + "Got FailoverException during channel close, ignored as channel already marked as closed."); + } + catch (TransportException e) + { + throw toJMSException("Error closing session:" + e.getMessage(), e); + } + finally + { + _connection.deregisterSession(_channelId); + } } } @@ -899,24 +900,22 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic if (!setClosed()) { - synchronized (_messageDeliveryLock) + // An AMQException has an error code and message already and will be passed in when closure occurs as a + // result of a channel close request + AMQException amqe; + if (e instanceof AMQException) { - // An AMQException has an error code and message already and will be passed in when closure occurs as a - // result of a channel close request - AMQException amqe; - if (e instanceof AMQException) - { - amqe = (AMQException) e; - } - else - { - amqe = new AMQException("Closing session forcibly", e); - } - - _connection.deregisterSession(_channelId); - closeProducersAndConsumers(amqe); + amqe = (AMQException) e; + } + else + { + amqe = new AMQException("Closing session forcibly", e); } + + _connection.deregisterSession(_channelId); + closeProducersAndConsumers(amqe); } + } protected void stopDispatcherThread() diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java index bb0f0d9b13..143de271a1 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java @@ -772,42 +772,47 @@ public class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, BasicMe private void returnBouncedMessage(final ReturnMessage msg) { - getAMQConnection().performConnectionTask(new Runnable() + try { - public void run() + // Bounced message is processed here, away from the mina thread + AbstractJMSMessage bouncedMessage = + getMessageFactoryRegistry().createMessage(0, + false, + msg.getExchange(), + msg.getRoutingKey(), + msg.getContentHeader(), + msg.getBodies(), + _queueDestinationCache, + _topicDestinationCache, + AMQDestination.UNKNOWN_TYPE); + AMQConstant errorCode = AMQConstant.getConstant(msg.getReplyCode()); + AMQShortString reason = msg.getReplyText(); + _logger.debug("Message returned with error code " + errorCode + " (" + reason + ")"); + + // @TODO should this be moved to an exception handler of sorts. Somewhere errors are converted to correct execeptions. + if (errorCode == AMQConstant.NO_CONSUMERS) { - try - { - // Bounced message is processed here, away from the mina thread - AbstractJMSMessage bouncedMessage = - getMessageFactoryRegistry().createMessage(0, false, msg.getExchange(), - msg.getRoutingKey(), msg.getContentHeader(), msg.getBodies(), _queueDestinationCache, - _topicDestinationCache, AMQDestination.UNKNOWN_TYPE); - AMQConstant errorCode = AMQConstant.getConstant(msg.getReplyCode()); - AMQShortString reason = msg.getReplyText(); - _logger.debug("Message returned with error code " + errorCode + " (" + reason + ")"); - - // @TODO should this be moved to an exception handler of sorts. Somewhere errors are converted to correct execeptions. - if (errorCode == AMQConstant.NO_CONSUMERS) - { - getAMQConnection().exceptionReceived(new AMQNoConsumersException("Error: " + reason, bouncedMessage, null)); - } else if (errorCode == AMQConstant.NO_ROUTE) - { - getAMQConnection().exceptionReceived(new AMQNoRouteException("Error: " + reason, bouncedMessage, null)); - } else - { - getAMQConnection().exceptionReceived( - new AMQUndeliveredException(errorCode, "Error: " + reason, bouncedMessage, null)); - } - - } catch (Exception e) - { - _logger.error( - "Caught exception trying to raise undelivered message exception (dump follows) - ignoring...", - e); - } + getAMQConnection().exceptionReceived(new AMQNoConsumersException("Error: " + reason, + bouncedMessage, + null)); } - }); + else if (errorCode == AMQConstant.NO_ROUTE) + { + getAMQConnection().exceptionReceived(new AMQNoRouteException("Error: " + reason, bouncedMessage, null)); + } + else + { + getAMQConnection().exceptionReceived( + new AMQUndeliveredException(errorCode, "Error: " + reason, bouncedMessage, null)); + } + + } + catch (Exception e) + { + _logger.error( + "Caught exception trying to raise undelivered message exception (dump follows) - ignoring...", + e); + } } diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java index b1e606b8e9..9cef1f8dce 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java @@ -598,35 +598,38 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa if (sendClose) { + // The Synchronized block only needs to protect network traffic. - synchronized (_connection.getFailoverMutex()) + + try { - try + // If the session is open or we are in the process + // of closing the session then send a cance + // no point otherwise as the connection will be gone + if (!_session.isClosed() || _session.isClosing()) { - // If the session is open or we are in the process - // of closing the session then send a cance - // no point otherwise as the connection will be gone - if (!_session.isClosed() || _session.isClosing()) + synchronized(_session.getMessageDeliveryLock()) { - synchronized(_session.getMessageDeliveryLock()) + synchronized (_connection.getFailoverMutex()) { sendCancel(); } } } - catch (AMQException e) - { - throw new JMSAMQException("Error closing consumer: " + e, e); - } - catch (FailoverException e) - { - throw new JMSAMQException("FailoverException interrupted basic cancel.", e); - } - catch (TransportException e) - { - throw _session.toJMSException("Exception while closing consumer: " + e.getMessage(), e); - } } + catch (AMQException e) + { + throw new JMSAMQException("Error closing consumer: " + e, e); + } + catch (FailoverException e) + { + throw new JMSAMQException("FailoverException interrupted basic cancel.", e); + } + catch (TransportException e) + { + throw _session.toJMSException("Exception while closing consumer: " + e.getMessage(), e); + } + } else { diff --git a/qpid/java/client/src/test/java/org/apache/qpid/client/MockAMQConnection.java b/qpid/java/client/src/test/java/org/apache/qpid/client/MockAMQConnection.java index 009598d8a4..ceb2a323ca 100644 --- a/qpid/java/client/src/test/java/org/apache/qpid/client/MockAMQConnection.java +++ b/qpid/java/client/src/test/java/org/apache/qpid/client/MockAMQConnection.java @@ -20,14 +20,14 @@ */ package org.apache.qpid.client; +import java.io.IOException; + import org.apache.qpid.AMQException; import org.apache.qpid.client.state.AMQState; import org.apache.qpid.framing.ProtocolVersion; import org.apache.qpid.jms.BrokerDetails; import org.apache.qpid.url.URLSyntaxException; -import java.io.IOException; - public class MockAMQConnection extends AMQConnection { public MockAMQConnection(String broker, String username, String password, String clientName, String virtualHost) @@ -60,4 +60,10 @@ public class MockAMQConnection extends AMQConnection { return super.getDelegate(); } + + @Override + public void performConnectionTask(final Runnable task) + { + task.run(); + } } diff --git a/qpid/java/common/src/main/java/org/apache/qpid/codec/ServerDecoder.java b/qpid/java/common/src/main/java/org/apache/qpid/codec/ServerDecoder.java index 32a45da60c..deed32346f 100644 --- a/qpid/java/common/src/main/java/org/apache/qpid/codec/ServerDecoder.java +++ b/qpid/java/common/src/main/java/org/apache/qpid/codec/ServerDecoder.java @@ -42,7 +42,6 @@ public class ServerDecoder extends AMQDecoder<ServerMethodProcessor<? extends Se throws AMQFrameDecodingException, IOException { ServerMethodProcessor<? extends ServerChannelMethodProcessor> methodProcessor = getMethodProcessor(); - ServerChannelMethodProcessor channelMethodProcessor = methodProcessor.getChannelMethodProcessor(channelId); final int classAndMethod = in.readInt(); int classId = classAndMethod >> 16; int methodId = classAndMethod & 0xFFFF; @@ -115,116 +114,117 @@ public class ServerDecoder extends AMQDecoder<ServerMethodProcessor<? extends Se ChannelOpenBody.process(channelId, in, methodProcessor); break; case 0x00140014: - ChannelFlowBody.process(in, channelMethodProcessor); + ChannelFlowBody.process(in, methodProcessor.getChannelMethodProcessor(channelId)); break; case 0x00140015: - ChannelFlowOkBody.process(in, channelMethodProcessor); + ChannelFlowOkBody.process(in, methodProcessor.getChannelMethodProcessor(channelId)); break; case 0x00140028: - ChannelCloseBody.process(in, channelMethodProcessor); + ChannelCloseBody.process(in, methodProcessor.getChannelMethodProcessor(channelId)); break; case 0x00140029: - channelMethodProcessor.receiveChannelCloseOk(); + methodProcessor.getChannelMethodProcessor(channelId).receiveChannelCloseOk(); break; // ACCESS_CLASS: case 0x001e000a: - AccessRequestBody.process(in, channelMethodProcessor); + AccessRequestBody.process(in, methodProcessor.getChannelMethodProcessor(channelId)); break; // EXCHANGE_CLASS: case 0x0028000a: - ExchangeDeclareBody.process(in, channelMethodProcessor); + ExchangeDeclareBody.process(in, methodProcessor.getChannelMethodProcessor(channelId)); break; case 0x00280014: - ExchangeDeleteBody.process(in, channelMethodProcessor); + ExchangeDeleteBody.process(in, methodProcessor.getChannelMethodProcessor(channelId)); break; case 0x00280016: - ExchangeBoundBody.process(in, channelMethodProcessor); + ExchangeBoundBody.process(in, methodProcessor.getChannelMethodProcessor(channelId)); break; // QUEUE_CLASS: case 0x0032000a: - QueueDeclareBody.process(in, channelMethodProcessor); + QueueDeclareBody.process(in, methodProcessor.getChannelMethodProcessor(channelId)); break; case 0x00320014: - QueueBindBody.process(in, channelMethodProcessor); + QueueBindBody.process(in, methodProcessor.getChannelMethodProcessor(channelId)); break; case 0x0032001e: - QueuePurgeBody.process(in, channelMethodProcessor); + QueuePurgeBody.process(in, methodProcessor.getChannelMethodProcessor(channelId)); break; case 0x00320028: - QueueDeleteBody.process(in, channelMethodProcessor); + QueueDeleteBody.process(in, methodProcessor.getChannelMethodProcessor(channelId)); break; case 0x00320032: - QueueUnbindBody.process(in, channelMethodProcessor); + QueueUnbindBody.process(in, methodProcessor.getChannelMethodProcessor(channelId)); break; // BASIC_CLASS: case 0x003c000a: - BasicQosBody.process(in, channelMethodProcessor); + BasicQosBody.process(in, methodProcessor.getChannelMethodProcessor(channelId)); break; case 0x003c0014: - BasicConsumeBody.process(in, channelMethodProcessor); + BasicConsumeBody.process(in, methodProcessor.getChannelMethodProcessor(channelId)); break; case 0x003c001e: - BasicCancelBody.process(in, channelMethodProcessor); + BasicCancelBody.process(in, methodProcessor.getChannelMethodProcessor(channelId)); break; case 0x003c0028: - BasicPublishBody.process(in, channelMethodProcessor); + BasicPublishBody.process(in, methodProcessor.getChannelMethodProcessor(channelId)); break; case 0x003c0046: - BasicGetBody.process(in, channelMethodProcessor); + BasicGetBody.process(in, methodProcessor.getChannelMethodProcessor(channelId)); break; case 0x003c0050: - BasicAckBody.process(in, channelMethodProcessor); + BasicAckBody.process(in, methodProcessor.getChannelMethodProcessor(channelId)); break; case 0x003c005a: - BasicRejectBody.process(in, channelMethodProcessor); + BasicRejectBody.process(in, methodProcessor.getChannelMethodProcessor(channelId)); break; case 0x003c0064: - BasicRecoverBody.process(in, methodProcessor.getProtocolVersion(), channelMethodProcessor); + BasicRecoverBody.process(in, methodProcessor.getProtocolVersion(), + methodProcessor.getChannelMethodProcessor(channelId)); break; case 0x003c0066: - BasicRecoverSyncBody.process(in, channelMethodProcessor); + BasicRecoverSyncBody.process(in, methodProcessor.getChannelMethodProcessor(channelId)); break; case 0x003c006e: - BasicRecoverSyncBody.process(in, channelMethodProcessor); + BasicRecoverSyncBody.process(in, methodProcessor.getChannelMethodProcessor(channelId)); break; case 0x003c0078: - BasicNackBody.process(in, channelMethodProcessor); + BasicNackBody.process(in, methodProcessor.getChannelMethodProcessor(channelId)); break; // CONFIRM CLASS: case 0x0055000a: - ConfirmSelectBody.process(in, channelMethodProcessor); + ConfirmSelectBody.process(in, methodProcessor.getChannelMethodProcessor(channelId)); break; // TX_CLASS: case 0x005a000a: - if(!channelMethodProcessor.ignoreAllButCloseOk()) + if(!methodProcessor.getChannelMethodProcessor(channelId).ignoreAllButCloseOk()) { - channelMethodProcessor.receiveTxSelect(); + methodProcessor.getChannelMethodProcessor(channelId).receiveTxSelect(); } break; case 0x005a0014: - if(!channelMethodProcessor.ignoreAllButCloseOk()) + if(!methodProcessor.getChannelMethodProcessor(channelId).ignoreAllButCloseOk()) { - channelMethodProcessor.receiveTxCommit(); + methodProcessor.getChannelMethodProcessor(channelId).receiveTxCommit(); } break; case 0x005a001e: - if(!channelMethodProcessor.ignoreAllButCloseOk()) + if(!methodProcessor.getChannelMethodProcessor(channelId).ignoreAllButCloseOk()) { - channelMethodProcessor.receiveTxRollback(); + methodProcessor.getChannelMethodProcessor(channelId).receiveTxRollback(); } break; diff --git a/qpid/java/common/src/main/java/org/apache/qpid/common/QpidProperties.java b/qpid/java/common/src/main/java/org/apache/qpid/common/QpidProperties.java index cdd44d3443..d077cc9717 100644 --- a/qpid/java/common/src/main/java/org/apache/qpid/common/QpidProperties.java +++ b/qpid/java/common/src/main/java/org/apache/qpid/common/QpidProperties.java @@ -20,12 +20,8 @@ */ package org.apache.qpid.common; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.io.IOException; import java.io.InputStream; -import java.util.Map; import java.util.Properties; /** @@ -37,18 +33,9 @@ import java.util.Properties; * * <p>To get the build version of any Qpid code call the {@link #main} method. This version string is usually also * printed to the console on broker start up. - * <p> - * TODO Code to locate/load/log properties can be factored into a reusable properties utils class. Avoid having this - * same snippet of loading code scattered in many places. - * <p> - * TODO Could also add a build number property for a sequential build number assigned by an automated build system, for - * build reproducability purposes. */ public class QpidProperties { - /** Used for debugging purposes. */ - private static final Logger _logger = LoggerFactory.getLogger(QpidProperties.class); - /** The name of the version properties file to load from the class path. */ public static final String VERSION_RESOURCE = "qpidversion.properties"; @@ -68,53 +55,43 @@ public class QpidProperties private static final String DEFAULT = "unknown"; /** Holds the product name. */ - private static String productName = DEFAULT; + private static final String productName; /** Holds the product version. */ - private static String releaseVersion = DEFAULT; + private static final String releaseVersion; /** Holds the source code revision. */ - private static String buildVersion = DEFAULT; + private static final String buildVersion; + + private static final Properties properties = new Properties(); // Loads the values from the version properties file. static { - Properties props = new Properties(); - try + try(InputStream propertyStream = QpidProperties.class.getClassLoader().getResourceAsStream(VERSION_RESOURCE)) { - InputStream propertyStream = QpidProperties.class.getClassLoader().getResourceAsStream(VERSION_RESOURCE); - if (propertyStream == null) + if (propertyStream != null) { - _logger.warn("Unable to find resource " + VERSION_RESOURCE + " from classloader"); - } - else - { - props.load(propertyStream); - - if (_logger.isDebugEnabled()) - { - _logger.debug("Dumping QpidProperties"); - for (Map.Entry<Object, Object> entry : props.entrySet()) - { - _logger.debug("Property: " + entry.getKey() + " Value: " + entry.getValue()); - } - - _logger.debug("End of property dump"); - } - - productName = readPropertyValue(props, PRODUCT_NAME_PROPERTY); - String versionSuffix = (String) props.get(RELEASE_VERSION_SUFFIX); - String version = readPropertyValue(props, RELEASE_VERSION_PROPERTY); - releaseVersion = versionSuffix == null || "".equals(versionSuffix) ? version : version + ";" + versionSuffix; - buildVersion = readPropertyValue(props, BUILD_VERSION_PROPERTY); + properties.load(propertyStream); } } catch (IOException e) { - // Log a warning about this and leave the values initialized to unknown. - _logger.error("Could not load version.properties resource: " + e, e); + // Ignore, most likely running within an IDE, values will have the DEFAULT text } + + String versionSuffix = properties.getProperty(RELEASE_VERSION_SUFFIX); + String version = properties.getProperty(RELEASE_VERSION_PROPERTY, DEFAULT); + + productName = properties.getProperty(PRODUCT_NAME_PROPERTY, DEFAULT); + releaseVersion = versionSuffix == null || "".equals(versionSuffix) ? version : version + ";" + versionSuffix; + buildVersion = properties.getProperty(BUILD_VERSION_PROPERTY, DEFAULT); + } + + public static Properties asProperties() + { + return new Properties(properties); } /** @@ -158,27 +135,6 @@ public class QpidProperties } /** - * Helper method to extract a named property from properties. - * - * @param props The properties. - * @param propertyName The named property to extract. - * - * @return The extracted property or a default value if the properties do not contain the named property. - * - * @todo A bit pointless. - */ - private static String readPropertyValue(Properties props, String propertyName) - { - String retVal = (String) props.get(propertyName); - if (retVal == null) - { - retVal = DEFAULT; - } - - return retVal; - } - - /** * Prints the versioning information to the console. This is extremely usefull for identifying Qpid code in the * wild, where the origination of the code has been forgotten. * diff --git a/qpid/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java b/qpid/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java index 86f5ddeeed..89e4c3ccdd 100644 --- a/qpid/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java +++ b/qpid/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java @@ -18,6 +18,17 @@ package org.apache.qpid.configuration; +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashSet; +import java.util.Properties; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * This class centralized the Qpid client properties. * @@ -25,6 +36,8 @@ package org.apache.qpid.configuration; */ public class ClientProperties { + private static final Logger LOGGER = LoggerFactory.getLogger(ClientProperties.class); + /** * Currently with Qpid it is not possible to change the client ID. * If one is not specified upon connection construction, an id is generated automatically. @@ -292,6 +305,48 @@ public class ClientProperties */ public static final String QPID_USE_LEGACY_GETQUEUEDEPTH_BEHAVIOUR = "qpid.use_legacy_getqueuedepth_behavior"; + static + { + // force load of common properties + Class<CommonProperties> commonPropertiesClass = CommonProperties.class; + + Properties props = new Properties(); + String initialProperties = System.getProperty("qpid.client_properties_file"); + URL initialPropertiesLocation = null; + try + { + if (initialProperties == null) + { + initialPropertiesLocation = ClientProperties.class.getClassLoader().getResource("qpid-client.properties"); + } + else + { + initialPropertiesLocation = (new File(initialProperties)).toURI().toURL(); + } + + if (initialPropertiesLocation != null) + { + props.load(initialPropertiesLocation.openStream()); + } + } + catch (MalformedURLException e) + { + LOGGER.warn("Could not open client properties file '"+initialProperties+"'.", e); + } + catch (IOException e) + { + LOGGER.warn("Could not open client properties file '" + initialPropertiesLocation + "'.", e); + } + + Set<String> propertyNames = new HashSet<>(props.stringPropertyNames()); + propertyNames.removeAll(System.getProperties().stringPropertyNames()); + for (String propName : propertyNames) + { + System.setProperty(propName, props.getProperty(propName)); + } + + } + private ClientProperties() { //No instances diff --git a/qpid/java/common/src/main/java/org/apache/qpid/configuration/CommonProperties.java b/qpid/java/common/src/main/java/org/apache/qpid/configuration/CommonProperties.java index 6bae93a1b8..a052a02748 100644 --- a/qpid/java/common/src/main/java/org/apache/qpid/configuration/CommonProperties.java +++ b/qpid/java/common/src/main/java/org/apache/qpid/configuration/CommonProperties.java @@ -20,6 +20,19 @@ */ package org.apache.qpid.configuration; +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashSet; +import java.util.Properties; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.qpid.common.QpidProperties; + /** * Centralised record of Qpid common properties. * @@ -27,6 +40,8 @@ package org.apache.qpid.configuration; */ public class CommonProperties { + private static final Logger LOGGER = LoggerFactory.getLogger(CommonProperties.class); + /** * The timeout used by the IO layer for timeouts such as send timeout in IoSender, and the close timeout for IoSender and IoReceiver */ @@ -36,6 +51,45 @@ public class CommonProperties public static final String HANDSHAKE_TIMEOUT_PROP_NAME = "qpid.handshake_timeout"; public static final int HANDSHAKE_TIMEOUT_DEFAULT = 2; + static + { + + Properties props = new Properties(QpidProperties.asProperties()); + String initialProperties = System.getProperty("qpid.common_properties_file"); + URL initialPropertiesLocation = null; + try + { + if (initialProperties == null) + { + initialPropertiesLocation = CommonProperties.class.getClassLoader().getResource("qpid-common.properties"); + } + else + { + initialPropertiesLocation = (new File(initialProperties)).toURI().toURL(); + } + + if (initialPropertiesLocation != null) + { + props.load(initialPropertiesLocation.openStream()); + } + } + catch (MalformedURLException e) + { + LOGGER.warn("Could not open common properties file '"+initialProperties+"'.", e); + } + catch (IOException e) + { + LOGGER.warn("Could not open common properties file '" + initialPropertiesLocation + "'.", e); + } + + Set<String> propertyNames = new HashSet<>(props.stringPropertyNames()); + propertyNames.removeAll(System.getProperties().stringPropertyNames()); + for (String propName : propertyNames) + { + System.setProperty(propName, props.getProperty(propName)); + } + + } private CommonProperties() { diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java index 39f27b0fe0..e7b16362e2 100644 --- a/qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java +++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java @@ -535,6 +535,8 @@ public class Connection extends ConnectionInvoker connectionLost.set(true); synchronized (lock) { + log.error(e, "exception: %s", e.getMessage()); + switch (state) { case OPENING: diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkTransportConfiguration.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkTransportConfiguration.java index 12f8d801dc..7af3b7af39 100644 --- a/qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkTransportConfiguration.java +++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkTransportConfiguration.java @@ -21,6 +21,7 @@ package org.apache.qpid.transport; import java.net.InetSocketAddress; +import java.util.Collection; /** * This interface provides a means for NetworkDrivers to configure TCP options such as incoming and outgoing @@ -30,17 +31,21 @@ import java.net.InetSocketAddress; public interface NetworkTransportConfiguration { // Taken from Socket - Boolean getTcpNoDelay(); + boolean getTcpNoDelay(); // The amount of memory in bytes to allocate to the incoming buffer - Integer getReceiveBufferSize(); + int getReceiveBufferSize(); // The amount of memory in bytes to allocate to the outgoing buffer - Integer getSendBufferSize(); + int getSendBufferSize(); InetSocketAddress getAddress(); boolean needClientAuth(); boolean wantClientAuth(); + + Collection<String> getEnabledCipherSuites(); + + Collection<String> getDisabledCipherSuites(); } diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoSender.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoSender.java index 61beae4c25..cd01cddb05 100644 --- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoSender.java +++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoSender.java @@ -26,12 +26,15 @@ import java.net.Socket; import java.nio.ByteBuffer; import java.util.concurrent.atomic.AtomicBoolean; +import javax.net.ssl.SSLSocket; + import org.apache.qpid.thread.Threading; import org.apache.qpid.transport.ByteBufferSender; import org.apache.qpid.transport.SenderClosedException; import org.apache.qpid.transport.SenderException; import org.apache.qpid.transport.TransportException; import org.apache.qpid.transport.util.Logger; +import org.apache.qpid.util.SystemUtils; public final class IoSender implements Runnable, ByteBufferSender @@ -58,6 +61,12 @@ public final class IoSender implements Runnable, ByteBufferSender private final Thread senderThread; private IoReceiver _receiver; private final String _remoteSocketAddress; + private static final boolean shutdownBroken; + + static + { + shutdownBroken = SystemUtils.isWindows(); + } private volatile Throwable exception = null; @@ -314,6 +323,18 @@ public final class IoSender implements Runnable, ByteBufferSender } } } + + if (!shutdownBroken && !(socket instanceof SSLSocket)) + { + try + { + socket.shutdownOutput(); + } + catch (IOException e) + { + //pass + } + } } public void setReceiver(IoReceiver receiver) diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/NonBlockingConnection.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/NonBlockingConnection.java index fe6e707f7e..2f3ba81285 100644 --- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/NonBlockingConnection.java +++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/NonBlockingConnection.java @@ -23,6 +23,7 @@ package org.apache.qpid.transport.network.io; import java.net.SocketAddress; import java.nio.channels.SocketChannel; import java.security.Principal; +import java.util.Collection; import java.util.Set; import javax.net.ssl.SSLContext; @@ -61,7 +62,10 @@ public class NonBlockingConnection implements NetworkConnection final SSLContext sslContext, final boolean wantClientAuth, final boolean needClientAuth, - final Runnable onTransportEncryptionAction, final SelectorThread selectorThread) + final Collection<String> enabledCipherSuites, + final Collection<String> disabledCipherSuites, + final Runnable onTransportEncryptionAction, + final SelectorThread selectorThread) { _socketChannel = socketChannel; _timeout = timeout; @@ -69,10 +73,20 @@ public class NonBlockingConnection implements NetworkConnection _selector = selectorThread; _nonBlockingSenderReceiver = new NonBlockingSenderReceiver(this, - delegate, receiveBufferSize, ticker, encryptionSet, sslContext, wantClientAuth, needClientAuth, onTransportEncryptionAction); + delegate, + receiveBufferSize, + ticker, + encryptionSet, + sslContext, + wantClientAuth, + needClientAuth, + enabledCipherSuites, + disabledCipherSuites, + onTransportEncryptionAction); } + public Ticker getTicker() { return _ticker; diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/NonBlockingNetworkTransport.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/NonBlockingNetworkTransport.java index 6c96c0a18e..1c49efc294 100644 --- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/NonBlockingNetworkTransport.java +++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/NonBlockingNetworkTransport.java @@ -152,6 +152,8 @@ public class NonBlockingNetworkTransport _sslContext, _config.wantClientAuth(), _config.needClientAuth(), + _config.getEnabledCipherSuites(), + _config.getDisabledCipherSuites(), new Runnable() { diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/NonBlockingSenderReceiver.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/NonBlockingSenderReceiver.java index 02099dee15..6599f4443c 100644 --- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/NonBlockingSenderReceiver.java +++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/NonBlockingSenderReceiver.java @@ -24,6 +24,7 @@ import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import java.security.Principal; import java.util.ArrayList; +import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.ListIterator; @@ -87,6 +88,8 @@ public class NonBlockingSenderReceiver implements ByteBufferSender final SSLContext sslContext, final boolean wantClientAuth, final boolean needClientAuth, + final Collection<String> enabledCipherSuites, + final Collection<String> disabledCipherSuites, final Runnable onTransportEncryptionAction) { _connection = connection; @@ -112,6 +115,8 @@ public class NonBlockingSenderReceiver implements ByteBufferSender _sslEngine = _sslContext.createSSLEngine(); _sslEngine.setUseClientMode(false); SSLUtil.removeSSLv3Support(_sslEngine); + SSLUtil.updateEnabledCipherSuites(_sslEngine, enabledCipherSuites, disabledCipherSuites); + if(needClientAuth) { _sslEngine.setNeedClientAuth(true); diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLReceiver.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLReceiver.java index ce3bace9e8..49e4ad631a 100644 --- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLReceiver.java +++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLReceiver.java @@ -187,7 +187,10 @@ public class SSLReceiver implements ByteBufferReceiver } catch(SSLException e) { - log.error(e, "Error caught in SSLReceiver"); + if (log.isDebugEnabled()) + { + log.debug(e, "Error caught in SSLReceiver"); + } _sslStatus.setSslErrorFlag(); synchronized(_sslStatus.getSslLock()) { diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLSender.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLSender.java index 755f7430ba..3d133cb9b7 100644 --- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLSender.java +++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLSender.java @@ -142,7 +142,7 @@ public class SSLSender implements ByteBufferSender public void send(ByteBuffer appData) { - if (closed.get()) + if (closed.get() && !_sslStatus.getSslErrorFlag()) { throw new SenderException("SSL Sender is closed"); } diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLUtil.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLUtil.java index b6ae2ab4a3..67dde84440 100644 --- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLUtil.java +++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLUtil.java @@ -24,6 +24,9 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; import java.net.URL; import java.security.GeneralSecurityException; import java.security.KeyStore; @@ -33,7 +36,10 @@ import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; @@ -266,7 +272,35 @@ public class SSLUtil return ks; } - public static void removeSSLv3Support(final SSLEngine engine) + private static interface SSLEntity + { + String[] getEnabledCipherSuites(); + + void setEnabledCipherSuites(String[] strings); + + String[] getEnabledProtocols(); + + void setEnabledProtocols(String[] protocols); + + String[] getSupportedCipherSuites(); + + String[] getSupportedProtocols(); + } + + private static SSLEntity asSSLEntity(final Object object, final Class<?> clazz) + { + return (SSLEntity) Proxy.newProxyInstance(SSLEntity.class.getClassLoader(), new Class[] { SSLEntity.class }, new InvocationHandler() + { + @Override + public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable + { + Method delegateMethod = clazz.getMethod(method.getName(), method.getParameterTypes()); + return delegateMethod.invoke(object, args); + } + }) ; + } + + private static void removeSSLv3Support(final SSLEntity engine) { List<String> enabledProtocols = Arrays.asList(engine.getEnabledProtocols()); if(enabledProtocols.contains(SSLV3_PROTOCOL)) @@ -277,26 +311,61 @@ public class SSLUtil } } - public static void removeSSLv3Support(final SSLSocket socket) + public static void removeSSLv3Support(final SSLEngine engine) { - List<String> enabledProtocols = Arrays.asList(socket.getEnabledProtocols()); - if(enabledProtocols.contains(SSLV3_PROTOCOL)) - { - List<String> allowedProtocols = new ArrayList<>(enabledProtocols); - allowedProtocols.remove(SSLV3_PROTOCOL); - socket.setEnabledProtocols(allowedProtocols.toArray(new String[allowedProtocols.size()])); - } + removeSSLv3Support(asSSLEntity(engine, SSLEngine.class)); } + public static void removeSSLv3Support(final SSLSocket socket) + { + removeSSLv3Support(asSSLEntity(socket, SSLSocket.class)); + } public static void removeSSLv3Support(final SSLServerSocket socket) { - List<String> enabledProtocols = Arrays.asList(socket.getEnabledProtocols()); - if(enabledProtocols.contains(SSLV3_PROTOCOL)) + removeSSLv3Support(asSSLEntity(socket, SSLServerSocket.class)); + } + + private static void updateEnabledCipherSuites(final SSLEntity entity, + final Collection<String> enabledCipherSuites, + final Collection<String> disabledCipherSuites) + { + if(enabledCipherSuites != null && !enabledCipherSuites.isEmpty()) { - List<String> allowedProtocols = new ArrayList<>(enabledProtocols); - allowedProtocols.remove(SSLV3_PROTOCOL); - socket.setEnabledProtocols(allowedProtocols.toArray(new String[allowedProtocols.size()])); + final Set<String> supportedSuites = + new HashSet<>(Arrays.asList(entity.getSupportedCipherSuites())); + supportedSuites.retainAll(enabledCipherSuites); + entity.setEnabledCipherSuites(supportedSuites.toArray(new String[supportedSuites.size()])); + } + + if(disabledCipherSuites != null && !disabledCipherSuites.isEmpty()) + { + final Set<String> enabledSuites = new HashSet<>(Arrays.asList(entity.getEnabledCipherSuites())); + enabledSuites.removeAll(disabledCipherSuites); + entity.setEnabledCipherSuites(enabledSuites.toArray(new String[enabledSuites.size()])); } + + } + + + public static void updateEnabledCipherSuites(final SSLEngine engine, + final Collection<String> enabledCipherSuites, + final Collection<String> disabledCipherSuites) + { + updateEnabledCipherSuites(asSSLEntity(engine, SSLEngine.class), enabledCipherSuites, disabledCipherSuites); + } + + public static void updateEnabledCipherSuites(final SSLServerSocket socket, + final Collection<String> enabledCipherSuites, + final Collection<String> disabledCipherSuites) + { + updateEnabledCipherSuites(asSSLEntity(socket, SSLServerSocket.class), enabledCipherSuites, disabledCipherSuites); + } + + public static void updateEnabledCipherSuites(final SSLSocket socket, + final Collection<String> enabledCipherSuites, + final Collection<String> disabledCipherSuites) + { + updateEnabledCipherSuites(asSSLEntity(socket, SSLSocket.class), enabledCipherSuites, disabledCipherSuites); } } diff --git a/qpid/java/pom.xml b/qpid/java/pom.xml index 6e0cde4434..2ef2223177 100644 --- a/qpid/java/pom.xml +++ b/qpid/java/pom.xml @@ -74,6 +74,7 @@ <dollar.sign>$</dollar.sign> <at.sign>@</at.sign> <bdb-version>5.0.104</bdb-version> + <derby-version>10.11.1.1</derby-version> </properties> <modules> diff --git a/qpid/java/systests/etc/config-systests.json b/qpid/java/systests/etc/config-systests.json index fa5e7f7724..05ba4f2178 100644 --- a/qpid/java/systests/etc/config-systests.json +++ b/qpid/java/systests/etc/config-systests.json @@ -21,7 +21,7 @@ { "name": "Broker", "defaultVirtualHost" : "test", - "modelVersion": "2.1", + "modelVersion": "3.0", "authenticationproviders" : [ { "name" : "plain", "type" : "PlainPasswordFile", @@ -29,12 +29,12 @@ } ], "keystores" : [ { "name" : "systestsKeyStore", - "path" : "${QPID_HOME}${file.separator}..${file.separator}test-profiles${file.separator}test_resources${file.separator}ssl${file.separator}java_broker_keystore.jks", + "storeUrl" : "${QPID_HOME}${file.separator}..${file.separator}test-profiles${file.separator}test_resources${file.separator}ssl${file.separator}java_broker_keystore.jks", "password" : "password" } ], "truststores" : [ { "name" : "systestsTrustStore", - "path" : "${QPID_HOME}${file.separator}..${file.separator}test-profiles${file.separator}test_resources${file.separator}ssl${file.separator}java_broker_truststore.jks", + "storeUrl" : "${QPID_HOME}${file.separator}..${file.separator}test-profiles${file.separator}test_resources${file.separator}ssl${file.separator}java_broker_truststore.jks", "password" : "password" } ], "ports" : [ { diff --git a/qpid/java/systests/src/test/java/org/apache/qpid/client/session/QueueDeclareTest.java b/qpid/java/systests/src/test/java/org/apache/qpid/client/session/QueueDeclareTest.java index fefed5b4ab..f0013a82d7 100644 --- a/qpid/java/systests/src/test/java/org/apache/qpid/client/session/QueueDeclareTest.java +++ b/qpid/java/systests/src/test/java/org/apache/qpid/client/session/QueueDeclareTest.java @@ -20,48 +20,77 @@ */ package org.apache.qpid.client.session; -import java.util.Collections; - import javax.jms.Connection; +import javax.jms.Destination; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.Session; -import org.apache.qpid.client.AMQQueue; +import org.apache.qpid.client.AMQDestination; import org.apache.qpid.client.AMQSession; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.FieldTable; import org.apache.qpid.test.utils.QpidBrokerTestCase; -import org.apache.qpid.url.AMQBindingURL; public class QueueDeclareTest extends QpidBrokerTestCase { private Connection _connection; private AMQSession<?, ?> _session; - protected void setUp() throws Exception { super.setUp(); _connection = getConnection(); + _connection.start(); _session = (AMQSession<?, ?>) _connection.createSession(true, Session.SESSION_TRANSACTED); } public void testDeclareAndBindWhenQueueIsNotSpecifiedInDestinationUrl() throws Exception { - AMQQueue destination = new AMQQueue(new AMQBindingURL("topic://amq.topic//?routingkey='testTopic'")); + AMQDestination destination = (AMQDestination) _session.createQueue("topic://amq.topic//?routingkey='testTopic'"); - assertEquals("Queue name is generated in parser", AMQShortString.EMPTY_STRING, destination.getAMQQueueName()); + assertEquals("Non empty queue name unexpectedly generated by parser : " + destination.getAMQQueueName(), AMQShortString.EMPTY_STRING, destination.getAMQQueueName()); - _session.declareAndBind(destination, FieldTable.convertToFieldTable(Collections.<String, Object> emptyMap())); + _session.declareAndBind(destination); - assertFalse("Unexpected queue name: [" + destination.getAMQQueueName() + "]", AMQShortString.EMPTY_STRING.equals(destination.getAMQQueueName())); + assertFalse("Non empty queue name should have been generated by declareAndBind", + AMQShortString.EMPTY_STRING.equals(destination.getAMQQueueName())); sendMessage(_session, destination, 1); + receiveMessage(destination); + } + + public void testDeclareIgnoresNonDurableFlagIfDurableQueueAlreadyExists() throws Exception + { + String format = "direct://amq.direct//%s?durable='%s'"; + AMQDestination durable = (AMQDestination) _session.createQueue(String.format(format, getTestQueueName(), true)); + AMQDestination nondurable = (AMQDestination) _session.createQueue(String.format(format, getTestQueueName(), false)); + + verifyDurabiltyIgnoreIfQueueExists(durable, nondurable); + } + + public void testDeclareIgnoresDurableFlagIfNonDurableQueueAlreadyExists() throws Exception + { + String format = "direct://amq.direct//%s?durable='%s'"; + AMQDestination nondurable = (AMQDestination) _session.createQueue(String.format(format, getTestQueueName(), false)); + AMQDestination durable = (AMQDestination) _session.createQueue(String.format(format, getTestQueueName(), true)); + verifyDurabiltyIgnoreIfQueueExists(nondurable, durable); + } + + private void verifyDurabiltyIgnoreIfQueueExists(final AMQDestination firstDeclare, final AMQDestination secondDeclare) throws Exception + { + _session.declareAndBind(firstDeclare); + + sendMessage(_session, firstDeclare, 1); + + _session.declareAndBind(secondDeclare); + receiveMessage(secondDeclare); + } + + private void receiveMessage(final Destination destination) throws Exception + { MessageConsumer consumer = _session.createConsumer(destination); - _connection.start(); - Message message = consumer.receive(1000l); + Message message = consumer.receive(RECEIVE_TIMEOUT); assertNotNull("Message not received", message); _session.commit(); } diff --git a/qpid/java/systests/src/test/java/org/apache/qpid/client/ssl/SSLTest.java b/qpid/java/systests/src/test/java/org/apache/qpid/client/ssl/SSLTest.java index 7c82ea8e55..72dea9b18b 100644 --- a/qpid/java/systests/src/test/java/org/apache/qpid/client/ssl/SSLTest.java +++ b/qpid/java/systests/src/test/java/org/apache/qpid/client/ssl/SSLTest.java @@ -112,7 +112,9 @@ public class SSLTest extends QpidBrokerTestCase } catch (JMSException e) { - assertTrue("Unexpected exception message", e.getMessage().contains("Unrecognized SSL message, plaintext connection?")); + // PASS + assertTrue("Unexpected exception message : " + e.getMessage(), + e.getMessage().contains("Unrecognized SSL message, plaintext connection?")); } } } diff --git a/qpid/java/systests/src/test/java/org/apache/qpid/server/logging/ChannelLoggingTest.java b/qpid/java/systests/src/test/java/org/apache/qpid/server/logging/ChannelLoggingTest.java index 047151684f..7a18bb5ed2 100644 --- a/qpid/java/systests/src/test/java/org/apache/qpid/server/logging/ChannelLoggingTest.java +++ b/qpid/java/systests/src/test/java/org/apache/qpid/server/logging/ChannelLoggingTest.java @@ -20,7 +20,6 @@ */ package org.apache.qpid.server.logging; -import org.apache.qpid.AMQChannelClosedException; import org.apache.qpid.AMQException; import org.apache.qpid.client.AMQConnection; import org.apache.qpid.client.AMQDestination; @@ -306,54 +305,6 @@ public class ChannelLoggingTest extends AbstractTestLogging validateChannelClose(results); } - public void testChannelClosedOnQueueArgumentsMismatch() throws Exception - { - assertLoggingNotYetOccured(CHANNEL_PREFIX); - - Connection connection = getConnection(); - - // Create a session and then close it - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - waitForMessage("CHN-1001"); - - String testQueueName = getTestQueueName(); - - Queue nonDurableQueue = (Queue) session.createQueue("direct://amq.direct/" + testQueueName + "/" + testQueueName - + "?durable='false'"); - - ((AMQSession<?,?>)session).declareAndBind((AMQDestination)nonDurableQueue); - - Queue durableQueue = (Queue) session.createQueue("direct://amq.direct/" + testQueueName + "/" + testQueueName - + "?durable='true'"); - try - { - ((AMQSession<?,?>)session).declareAndBind((AMQDestination) durableQueue); - fail("Exception not thrown"); - } - catch (AMQChannelClosedException acce) - { - // pass - } - catch (Exception e) - { - fail("Wrong exception thrown " + e); - } - waitForMessage("CHN-1003"); - - List<String> results = findMatches(CHANNEL_PREFIX); - assertTrue("No CHN messages logged", results.size() > 0); - - String closeLog = results.get(results.size() -1); - int closeMessageID = closeLog.indexOf("CHN-1003"); - assertFalse("CHN-1003 is not found", closeMessageID == -1); - - String closeMessage = closeLog.substring(closeMessageID); - assertTrue("Unexpected close channel message :" + closeMessage, Pattern.matches(CHANNEL_CLOSE_FORCED_MESSAGE_PATTERN, closeMessage)); - - session.close(); - connection.close(); - } - public void testChannelClosedOnExclusiveQueueDeclaredOnDifferentSession() throws Exception { assertLoggingNotYetOccured(CHANNEL_PREFIX); diff --git a/qpid/java/systests/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationTest.java b/qpid/java/systests/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationTest.java index 5522187ee5..e855a721ee 100644 --- a/qpid/java/systests/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationTest.java +++ b/qpid/java/systests/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationTest.java @@ -203,7 +203,7 @@ public class ExternalAuthenticationTest extends QpidBrokerTestCase //add the peersOnly store to the config Map<String, Object> sslTrustStoreAttributes = new HashMap<String, Object>(); sslTrustStoreAttributes.put(TrustStore.NAME, peerStoreName); - sslTrustStoreAttributes.put(FileTrustStore.PATH, BROKER_PEERSTORE); + sslTrustStoreAttributes.put(FileTrustStore.STORE_URL, BROKER_PEERSTORE); sslTrustStoreAttributes.put(FileTrustStore.PASSWORD, BROKER_PEERSTORE_PASSWORD); sslTrustStoreAttributes.put(FileTrustStore.PEERS_ONLY, true); getBrokerConfiguration().addObjectConfiguration(TrustStore.class, sslTrustStoreAttributes); diff --git a/qpid/java/systests/src/test/java/org/apache/qpid/systest/management/jmx/ManagementLoggingTest.java b/qpid/java/systests/src/test/java/org/apache/qpid/systest/management/jmx/ManagementLoggingTest.java index 4df81845d8..a5a167f633 100644 --- a/qpid/java/systests/src/test/java/org/apache/qpid/systest/management/jmx/ManagementLoggingTest.java +++ b/qpid/java/systests/src/test/java/org/apache/qpid/systest/management/jmx/ManagementLoggingTest.java @@ -211,47 +211,6 @@ public class ManagementLoggingTest extends AbstractTestLogging } /** - * Description: - * Using the default configuration with SSL enabled for the management port the SSL Keystore path should be reported via MNG-1006 - * Input: - * Management SSL enabled default configuration. - * Output: - * - * <date> MESSAGE MNG-1006 : Using SSL Keystore : test_resources/ssl/keystore.jks - * - * Validation Steps: - * - * 1. The MNG ID is correct - * 2. The keystore path is as specified in the configuration - */ - public void testManagementStartupSSLKeystore() throws Exception - { - if (isJavaBroker()) - { - setSystemProperty("javax.net.debug", "ssl"); - startBrokerAndCreateMonitor(true, true); - - List<String> results = waitAndFindMatches("MNG-1006"); - - assertTrue("MNGer message not logged", results.size() > 0); - - String log = getLogMessage(results, 0); - - //1 - validateMessageID("MNG-1006", log); - - // Validate we only have two MNG-1002 (one via stdout, one via log4j) - results = findMatches("MNG-1006"); - assertEquals("Upexpected SSL Keystore message count", - 1, results.size()); - - // Validate the keystore path is as expected - assertTrue("SSL Keystore entry expected.:" + getMessageString(log), - getMessageString(log).endsWith("systestsKeyStore")); - } - } - - /** * Description: Tests the management connection open/close are logged correctly. * * Output: diff --git a/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/AccessControlProviderRestTest.java b/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/AccessControlProviderRestTest.java index 0dda8e077b..26f7f16bec 100644 --- a/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/AccessControlProviderRestTest.java +++ b/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/AccessControlProviderRestTest.java @@ -29,6 +29,7 @@ import java.util.UUID; import org.apache.qpid.server.BrokerOptions; import org.apache.qpid.server.management.plugin.HttpManagement; +import org.apache.qpid.server.management.plugin.servlet.rest.RestServlet; import org.apache.qpid.server.model.AccessControlProvider; import org.apache.qpid.server.model.Plugin; import org.apache.qpid.server.model.State; @@ -183,7 +184,7 @@ public class AccessControlProviderRestTest extends QpidRestTestCase getRestTestHelper().setUsernameAndPassword(BrokerOptions.MANAGEMENT_MODE_USER_NAME, MANAGEMENT_MODE_PASSWORD); - Map<String, Object> acl = getRestTestHelper().getJsonAsSingletonList("accesscontrolprovider/" + TestBrokerConfiguration.ENTRY_NAME_ACL_FILE); + Map<String, Object> acl = getRestTestHelper().getJsonAsSingletonList("accesscontrolprovider/" + TestBrokerConfiguration.ENTRY_NAME_ACL_FILE + "?" + RestServlet.OVERSIZE_PARAM + "=" + (file.getAbsolutePath().length()+10)); assertEquals("Unexpected id", id.toString(), acl.get(AccessControlProvider.ID)); assertEquals("Unexpected path", file.getAbsolutePath() , acl.get(FileAccessControlProviderConstants.PATH)); assertEquals("Unexpected state", State.ERRORED.name() , acl.get(AccessControlProvider.STATE)); diff --git a/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/KeyStoreRestTest.java b/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/KeyStoreRestTest.java index 03b0a7a304..a3bf1ab3cb 100644 --- a/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/KeyStoreRestTest.java +++ b/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/KeyStoreRestTest.java @@ -28,6 +28,7 @@ import javax.servlet.http.HttpServletResponse; import org.apache.qpid.server.model.AbstractConfiguredObject; +import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.KeyStore; import org.apache.qpid.server.security.FileKeyStore; import org.apache.qpid.test.utils.TestBrokerConfiguration; @@ -52,8 +53,12 @@ public class KeyStoreRestTest extends QpidRestTestCase List<Map<String, Object>> keyStores = assertNumberOfKeyStores(1); Map<String, Object> keystore = keyStores.get(0); - assertKeyStoreAttributes(keystore, TestBrokerConfiguration.ENTRY_NAME_SSL_KEYSTORE, - QPID_HOME + "/../" + TestSSLConstants.BROKER_KEYSTORE, null); + + assertEquals("Unexpected name", TestBrokerConfiguration.ENTRY_NAME_SSL_KEYSTORE, keystore.get(KeyStore.NAME)); + assertEquals("unexpected path to key store", AbstractConfiguredObject.SECURED_STRING_VALUE, keystore.get(FileKeyStore.STORE_URL)); + assertEquals("unexpected (dummy) password of default systests key store", AbstractConfiguredObject.SECURED_STRING_VALUE, keystore.get(FileKeyStore.PASSWORD)); + assertEquals("unexpected type of default systests key store", java.security.KeyStore.getDefaultType(), keystore.get(FileKeyStore.KEY_STORE_TYPE)); + assertFalse("should not be a certificateAlias attribute", keystore.containsKey(FileKeyStore.CERTIFICATE_ALIAS)); } public void testCreate() throws Exception @@ -67,10 +72,14 @@ public class KeyStoreRestTest extends QpidRestTestCase createKeyStore(name, certAlias, TestSSLConstants.KEYSTORE, TestSSLConstants.KEYSTORE_PASSWORD); assertNumberOfKeyStores(2); - List<Map<String, Object>> keyStores = getRestTestHelper().getJsonAsList("keystore/" + name); + List<Map<String, Object>> keyStores = getRestTestHelper().getJsonAsList("keystore/" + name + "?actuals=true"); assertNotNull("details cannot be null", keyStores); - assertKeyStoreAttributes(keyStores.get(0), name, TestSSLConstants.KEYSTORE, certAlias); + Map<String, Object> keystore = keyStores.get(0); + assertEquals("Unexpected name", name, keystore.get(KeyStore.NAME)); + assertEquals("unexpected path to key store", AbstractConfiguredObject.SECURED_STRING_VALUE, keystore.get(FileKeyStore.STORE_URL)); + assertEquals("unexpected password", AbstractConfiguredObject.SECURED_STRING_VALUE, keystore.get(FileKeyStore.PASSWORD)); + assertEquals("unexpected alias", certAlias, keystore.get(FileKeyStore.CERTIFICATE_ALIAS)); } public void testCreateWithDataUrl() throws Exception @@ -85,10 +94,14 @@ public class KeyStoreRestTest extends QpidRestTestCase createKeyStore(name, null, dataUrlForKeyStore, TestSSLConstants.KEYSTORE_PASSWORD); assertNumberOfKeyStores(2); - List<Map<String, Object>> keyStores = getRestTestHelper().getJsonAsList("keystore/" + name); + List<Map<String, Object>> keyStores = getRestTestHelper().getJsonAsList("keystore/" + name + "?actuals=true"); assertNotNull("details cannot be null", keyStores); - assertKeyStoreAttributes(keyStores.get(0), name, dataUrlForKeyStore, null); + Map<String, Object> keystore = keyStores.get(0); + assertEquals("Unexpected name", name, keystore.get(KeyStore.NAME)); + assertEquals("unexpected data", AbstractConfiguredObject.SECURED_STRING_VALUE, keystore.get(FileKeyStore.STORE_URL)); + assertEquals("unexpected password", AbstractConfiguredObject.SECURED_STRING_VALUE, keystore.get(FileKeyStore.PASSWORD)); + assertEquals("unexpected alias", null, keystore.get(FileKeyStore.CERTIFICATE_ALIAS)); } public void testDelete() throws Exception @@ -104,15 +117,17 @@ public class KeyStoreRestTest extends QpidRestTestCase getRestTestHelper().submitRequest("keystore/" + name, "DELETE", HttpServletResponse.SC_OK); - List<Map<String, Object>> keyStore = getRestTestHelper().getJsonAsList("keystore/" + name); + List<Map<String, Object>> keyStore = getRestTestHelper().getJsonAsList("keystore/" + name + "?actuals=true"); assertNotNull("details should not be null", keyStore); assertTrue("details should be empty as the keystore no longer exists", keyStore.isEmpty()); //check only the default systests key store remains List<Map<String, Object>> keyStores = assertNumberOfKeyStores(1); Map<String, Object> keystore = keyStores.get(0); - assertKeyStoreAttributes(keystore, TestBrokerConfiguration.ENTRY_NAME_SSL_KEYSTORE, - QPID_HOME + "/../" + TestSSLConstants.BROKER_KEYSTORE, null); + assertEquals("Unexpected name", TestBrokerConfiguration.ENTRY_NAME_SSL_KEYSTORE, keystore.get(KeyStore.NAME)); + assertEquals("unexpected path to key store", AbstractConfiguredObject.SECURED_STRING_VALUE, keystore.get(FileKeyStore.STORE_URL)); + assertEquals("unexpected (dummy) password of default systests key store", AbstractConfiguredObject.SECURED_STRING_VALUE, keystore.get(FileKeyStore.PASSWORD)); + assertFalse("should not be a certificateAlias attribute", keystore.containsKey(FileKeyStore.CERTIFICATE_ALIAS)); } public void testUpdate() throws Exception @@ -127,14 +142,18 @@ public class KeyStoreRestTest extends QpidRestTestCase Map<String, Object> attributes = new HashMap<String, Object>(); attributes.put(KeyStore.NAME, name); - attributes.put(FileKeyStore.PATH, TestSSLConstants.UNTRUSTED_KEYSTORE); + attributes.put(FileKeyStore.STORE_URL, TestSSLConstants.UNTRUSTED_KEYSTORE); getRestTestHelper().submitRequest("keystore/" + name, "PUT", attributes, HttpServletResponse.SC_OK); - List<Map<String, Object>> keyStore = getRestTestHelper().getJsonAsList("keystore/" + name); - assertNotNull("details should not be null", keyStore); + List<Map<String, Object>> keyStores = getRestTestHelper().getJsonAsList("keystore/" + name + "?actuals=true"); + assertNotNull("details should not be null", keyStores); - assertKeyStoreAttributes(keyStore.get(0), name, TestSSLConstants.UNTRUSTED_KEYSTORE, null); + Map<String, Object> keystore = keyStores.get(0); + assertEquals("Unexpected name", name, keystore.get(KeyStore.NAME)); + assertEquals("unexpected data", AbstractConfiguredObject.SECURED_STRING_VALUE, keystore.get(FileKeyStore.STORE_URL)); + assertEquals("unexpected password", AbstractConfiguredObject.SECURED_STRING_VALUE, keystore.get(FileKeyStore.PASSWORD)); + assertEquals("unexpected alias", null, keystore.get(FileKeyStore.CERTIFICATE_ALIAS)); } @@ -151,7 +170,7 @@ public class KeyStoreRestTest extends QpidRestTestCase { Map<String, Object> keyStoreAttributes = new HashMap<>(); keyStoreAttributes.put(KeyStore.NAME, name); - keyStoreAttributes.put(FileKeyStore.PATH, keyStorePath); + keyStoreAttributes.put(FileKeyStore.STORE_URL, keyStorePath); keyStoreAttributes.put(FileKeyStore.PASSWORD, keystorePassword); if (certAlias != null) { @@ -161,26 +180,4 @@ public class KeyStoreRestTest extends QpidRestTestCase getRestTestHelper().submitRequest("keystore/" + name, "PUT", keyStoreAttributes, HttpServletResponse.SC_CREATED); } - private void assertKeyStoreAttributes(Map<String, Object> keystore, String name, String path, String certAlias) - { - assertEquals("default systests key store is missing", - name, keystore.get(KeyStore.NAME)); - assertEquals("unexpected path to key store", - path, keystore.get(FileKeyStore.PATH)); - assertEquals("unexpected (dummy) password of default systests key store", - AbstractConfiguredObject.SECURED_STRING_VALUE, keystore.get(FileKeyStore.PASSWORD)); - assertEquals("unexpected type of default systests key store", - java.security.KeyStore.getDefaultType(), keystore.get(FileKeyStore.KEY_STORE_TYPE)); - if(certAlias == null) - { - assertFalse("should not be a certificateAlias attribute", - keystore.containsKey(FileKeyStore.CERTIFICATE_ALIAS)); - } - else - { - assertEquals("unexpected certificateAlias value", - certAlias, keystore.get(FileKeyStore.CERTIFICATE_ALIAS)); - - } - } } diff --git a/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/TrustStoreRestTest.java b/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/TrustStoreRestTest.java index 6cca3fc12c..c1ea83e0dd 100644 --- a/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/TrustStoreRestTest.java +++ b/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/TrustStoreRestTest.java @@ -27,6 +27,7 @@ import java.util.Map; import javax.servlet.http.HttpServletResponse; import org.apache.qpid.server.model.AbstractConfiguredObject; +import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.TrustStore; import org.apache.qpid.server.security.FileTrustStore; import org.apache.qpid.test.utils.TestBrokerConfiguration; @@ -36,6 +37,7 @@ import org.apache.qpid.util.FileUtils; public class TrustStoreRestTest extends QpidRestTestCase { + @Override public void setUp() throws Exception { @@ -51,8 +53,14 @@ public class TrustStoreRestTest extends QpidRestTestCase List<Map<String, Object>> trustStores = assertNumberOfTrustStores(1); Map<String, Object> truststore = trustStores.get(0); - assertTrustStoreAttributes(truststore, TestBrokerConfiguration.ENTRY_NAME_SSL_TRUSTSTORE, - QPID_HOME + "/../" + TestSSLConstants.BROKER_TRUSTSTORE, false); + assertEquals("default systests trust store is missing", + TestBrokerConfiguration.ENTRY_NAME_SSL_TRUSTSTORE, truststore.get(TrustStore.NAME)); + assertEquals("unexpected store URL", ConfiguredObject.OVER_SIZED_ATTRIBUTE_ALTERNATIVE_TEXT, truststore.get(FileTrustStore.STORE_URL)); + assertEquals("unexpected (dummy) password of default systests trust store", + AbstractConfiguredObject.SECURED_STRING_VALUE, truststore.get(FileTrustStore.PASSWORD)); + assertEquals("unexpected type of default systests trust store", + java.security.KeyStore.getDefaultType(), truststore.get(FileTrustStore.TRUST_STORE_TYPE)); + assertEquals("unexpected peersOnly value", false, truststore.get(FileTrustStore.PEERS_ONLY)); } public void testCreate() throws Exception @@ -68,7 +76,12 @@ public class TrustStoreRestTest extends QpidRestTestCase List<Map<String, Object>> trustStores = getRestTestHelper().getJsonAsList("truststore/" + name); assertNotNull("details cannot be null", trustStores); - assertTrustStoreAttributes(trustStores.get(0), name, TestSSLConstants.TRUSTSTORE, true); + Map<String, Object> truststore = trustStores.get(0); + assertEquals("unexpected trust store name", name, truststore.get(TrustStore.NAME)); + assertEquals("unexpected store URL", TestSSLConstants.TRUSTSTORE, truststore.get(FileTrustStore.STORE_URL)); + assertEquals("unexpected password value", AbstractConfiguredObject.SECURED_STRING_VALUE, truststore.get(FileTrustStore.PASSWORD)); + assertEquals("unexpected type", java.security.KeyStore.getDefaultType(), truststore.get(FileTrustStore.TRUST_STORE_TYPE)); + assertEquals("unexpected peersOnly value", true, truststore.get(FileTrustStore.PEERS_ONLY)); } public void testCreateUsingDataUrl() throws Exception @@ -88,7 +101,12 @@ public class TrustStoreRestTest extends QpidRestTestCase List<Map<String, Object>> trustStores = getRestTestHelper().getJsonAsList("truststore/" + name); assertNotNull("details cannot be null", trustStores); - assertTrustStoreAttributes(trustStores.get(0), name, dataUrlForTruststore, false); + Map<String, Object> truststore = trustStores.get(0); + assertEquals("nexpected trust store name", name, truststore.get(TrustStore.NAME)); + assertEquals("unexpected store URL value", ConfiguredObject.OVER_SIZED_ATTRIBUTE_ALTERNATIVE_TEXT, truststore.get(FileTrustStore.STORE_URL)); + assertEquals("unexpected password value", AbstractConfiguredObject.SECURED_STRING_VALUE, truststore.get(FileTrustStore.PASSWORD)); + assertEquals("unexpected type of trust store", java.security.KeyStore.getDefaultType(), truststore.get(FileTrustStore.TRUST_STORE_TYPE)); + assertEquals("unexpected peersOnly value", false, truststore.get(FileTrustStore.PEERS_ONLY)); } public void testDelete() throws Exception @@ -110,8 +128,11 @@ public class TrustStoreRestTest extends QpidRestTestCase //check only the default systests trust store remains List<Map<String, Object>> trustStores = assertNumberOfTrustStores(1); Map<String, Object> truststore = trustStores.get(0); - assertTrustStoreAttributes(truststore, TestBrokerConfiguration.ENTRY_NAME_SSL_TRUSTSTORE, - QPID_HOME + "/../" + TestSSLConstants.BROKER_TRUSTSTORE, false); + assertEquals("unexpected name", TestBrokerConfiguration.ENTRY_NAME_SSL_TRUSTSTORE, truststore.get(TrustStore.NAME)); + assertEquals("unexpected store URL value", ConfiguredObject.OVER_SIZED_ATTRIBUTE_ALTERNATIVE_TEXT, truststore.get(FileTrustStore.STORE_URL)); + assertEquals("unexpected password value", AbstractConfiguredObject.SECURED_STRING_VALUE, truststore.get(FileTrustStore.PASSWORD)); + assertEquals("unexpected type of trust store", java.security.KeyStore.getDefaultType(), truststore.get(FileTrustStore.TRUST_STORE_TYPE)); + assertEquals("unexpected peersOnly value", false, truststore.get(FileTrustStore.PEERS_ONLY)); } @@ -127,14 +148,19 @@ public class TrustStoreRestTest extends QpidRestTestCase Map<String, Object> attributes = new HashMap<String, Object>(); attributes.put(TrustStore.NAME, name); - attributes.put(FileTrustStore.PATH, TestSSLConstants.TRUSTSTORE); + attributes.put(FileTrustStore.STORE_URL, TestSSLConstants.TRUSTSTORE); getRestTestHelper().submitRequest("truststore/" + name , "PUT", attributes, HttpServletResponse.SC_OK); List<Map<String, Object>> trustStore = getRestTestHelper().getJsonAsList("truststore/" + name); assertNotNull("details should not be null", trustStore); - assertTrustStoreAttributes(trustStore.get(0), name, TestSSLConstants.TRUSTSTORE, false); + Map<String, Object> truststore = trustStore.get(0); + assertEquals("unexpected name", name, truststore.get(TrustStore.NAME)); + assertEquals("unexpected path to trust store", TestSSLConstants.TRUSTSTORE, truststore.get(FileTrustStore.STORE_URL)); + assertEquals("unexpected password", AbstractConfiguredObject.SECURED_STRING_VALUE, truststore.get(FileTrustStore.PASSWORD)); + assertEquals("unexpected type", java.security.KeyStore.getDefaultType(), truststore.get(FileTrustStore.TRUST_STORE_TYPE)); + assertEquals("unexpected peersOnly value", false, truststore.get(FileTrustStore.PEERS_ONLY)); } private List<Map<String, Object>> assertNumberOfTrustStores(int numberOfTrustStores) throws Exception @@ -151,24 +177,11 @@ public class TrustStoreRestTest extends QpidRestTestCase Map<String, Object> trustStoreAttributes = new HashMap<String, Object>(); trustStoreAttributes.put(TrustStore.NAME, name); //deliberately using the client trust store to differentiate from the one we are already for broker - trustStoreAttributes.put(FileTrustStore.PATH, truststorePath); + trustStoreAttributes.put(FileTrustStore.STORE_URL, truststorePath); trustStoreAttributes.put(FileTrustStore.PASSWORD, truststorePassword); trustStoreAttributes.put(FileTrustStore.PEERS_ONLY, peersOnly); getRestTestHelper().submitRequest("truststore/" + name, "PUT", trustStoreAttributes, HttpServletResponse.SC_CREATED); } - private void assertTrustStoreAttributes(Map<String, Object> truststore, String name, String path, boolean peersOnly) - { - assertEquals("default systests trust store is missing", - name, truststore.get(TrustStore.NAME)); - assertEquals("unexpected path to trust store", - path, truststore.get(FileTrustStore.PATH)); - assertEquals("unexpected (dummy) password of default systests trust store", - AbstractConfiguredObject.SECURED_STRING_VALUE, truststore.get(FileTrustStore.PASSWORD)); - assertEquals("unexpected type of default systests trust store", - java.security.KeyStore.getDefaultType(), truststore.get(FileTrustStore.TRUST_STORE_TYPE)); - assertEquals("unexpected peersOnly value", - peersOnly, truststore.get(FileTrustStore.PEERS_ONLY)); - } } diff --git a/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/acl/BrokerACLTest.java b/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/acl/BrokerACLTest.java index 86ebf11575..c05e95c4d4 100644 --- a/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/acl/BrokerACLTest.java +++ b/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/acl/BrokerACLTest.java @@ -183,7 +183,7 @@ public class BrokerACLTest extends QpidRestTestCase assertEquals("Setting of provider attribites should be allowed", 403, responseCode); Map<String, Object> provider = getRestTestHelper().getJsonAsSingletonList("authenticationprovider/" + providerName); - assertEquals("Unexpected PATH attribute value", + assertEquals("Unexpected STORE_URL attribute value", providerData.get(ExternalFileBasedAuthenticationManager.PATH), provider.get(ExternalFileBasedAuthenticationManager.PATH)); } @@ -922,7 +922,7 @@ public class BrokerACLTest extends QpidRestTestCase { Map<String, Object> keyStoreAttributes = new HashMap<String, Object>(); keyStoreAttributes.put(KeyStore.NAME, name); - keyStoreAttributes.put(FileKeyStore.PATH, TestSSLConstants.KEYSTORE); + keyStoreAttributes.put(FileKeyStore.STORE_URL, TestSSLConstants.KEYSTORE); keyStoreAttributes.put(FileKeyStore.PASSWORD, TestSSLConstants.KEYSTORE_PASSWORD); keyStoreAttributes.put(FileKeyStore.CERTIFICATE_ALIAS, certAlias); @@ -933,7 +933,7 @@ public class BrokerACLTest extends QpidRestTestCase { Map<String, Object> trustStoreAttributes = new HashMap<String, Object>(); trustStoreAttributes.put(TrustStore.NAME, name); - trustStoreAttributes.put(FileTrustStore.PATH, TestSSLConstants.KEYSTORE); + trustStoreAttributes.put(FileTrustStore.STORE_URL, TestSSLConstants.KEYSTORE); trustStoreAttributes.put(FileTrustStore.PASSWORD, TestSSLConstants.KEYSTORE_PASSWORD); trustStoreAttributes.put(FileTrustStore.PEERS_ONLY, peersOnly); diff --git a/qpid/java/systests/src/test/java/org/apache/qpid/test/unit/close/MessageRequeueTest.java b/qpid/java/systests/src/test/java/org/apache/qpid/test/unit/close/MessageRequeueTest.java deleted file mode 100644 index 5895d670a7..0000000000 --- a/qpid/java/systests/src/test/java/org/apache/qpid/test/unit/close/MessageRequeueTest.java +++ /dev/null @@ -1,371 +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.test.unit.close; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.apache.qpid.AMQException; -import org.apache.qpid.client.message.AbstractJMSMessage; -import org.apache.qpid.test.utils.QpidBrokerTestCase; -import org.apache.qpid.test.utils.QpidClientConnection; -import org.apache.qpid.url.URLSyntaxException; - -import javax.jms.Connection; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.Queue; -import javax.jms.Session; -import java.util.concurrent.atomic.AtomicInteger; - -public class MessageRequeueTest extends QpidBrokerTestCase -{ - private static final Logger _logger = LoggerFactory.getLogger(MessageRequeueTest.class); - - protected static AtomicInteger consumerIds = new AtomicInteger(0); - protected final Integer numTestMessages = 150; - - protected final int consumeTimeout = 3000; - - protected final String queue = "direct://amq.direct//message-requeue-test-queue"; - protected String payload = "Message:"; - - protected final String BROKER = "tcp://127.0.0.1:5672"; - private boolean testReception = true; - - private long[] receieved = new long[numTestMessages + 1]; - private boolean passed = false; - private QpidClientConnection conn; - - - protected void setUp() throws Exception - { - super.setUp(); - - conn = new QpidClientConnection(BROKER); - - conn.connect(); - // clear queue - conn.consume(queue, consumeTimeout); - // load test data - _logger.info("creating test data, " + numTestMessages + " messages"); - conn.put(queue, payload, numTestMessages); - // close this connection - conn.disconnect(); - } - - protected void tearDown() throws Exception - { - - if (!passed) // clean up - { - QpidClientConnection conn = new QpidClientConnection(BROKER); - - conn.connect(); - // clear queue - conn.consume(queue, consumeTimeout); - - conn.disconnect(); - } - - super.tearDown(); - } - - /** - * multiple consumers - * - * @throws javax.jms.JMSException if a JMS problem occurs - * @throws InterruptedException on timeout - */ - public void testDrain() throws Exception - { - QpidClientConnection conn = new QpidClientConnection(BROKER); - - conn.connect(); - - _logger.info("consuming queue " + queue); - Queue q = conn.getSession().createQueue(queue); - - final MessageConsumer consumer = conn.getSession().createConsumer(q); - int messagesReceived = 0; - - long[] messageLog = new long[numTestMessages + 1]; - - _logger.info("consuming..."); - Message msg = consumer.receive(1000); - while (msg != null) - { - messagesReceived++; - - long dt = ((AbstractJMSMessage) msg).getDeliveryTag(); - - int msgindex = msg.getIntProperty("index"); - if (messageLog[msgindex] != 0) - { - _logger.error("Received Message(" + msgindex + ":" + ((AbstractJMSMessage) msg).getDeliveryTag() - + ") more than once."); - } - - if (_logger.isInfoEnabled()) - { - _logger.info("Received Message(" + System.identityHashCode(msgindex) + ") " + "DT:" + dt + "IN:" + msgindex); - } - - if (dt == 0) - { - _logger.error("DT is zero for msg:" + msgindex); - } - - messageLog[msgindex] = dt; - - // get Next message - msg = consumer.receive(1000); - } - - _logger.info("consuming done."); - conn.getSession().commit(); - consumer.close(); - - int index = 0; - StringBuilder list = new StringBuilder(); - list.append("Failed to receive:"); - int failed = 0; - - _logger.info("consumed: " + messagesReceived); - - assertEquals("number of consumed messages does not match initial data", (int) numTestMessages, messagesReceived); - // with 0_10 we can have a delivery tag of 0 - if (!conn.isBroker010()) - { - for (long b : messageLog) - { - if ((b == 0) && (index != 0)) // delivery tag of zero shouldn't exist - { - _logger.error("Index: " + index + " was not received."); - list.append(" "); - list.append(index); - list.append(":"); - list.append(b); - failed++; - } - - index++; - } - - assertEquals(list.toString(), 0, failed); - } - - conn.disconnect(); - passed = true; - } - - /** multiple consumers - * Based on code subbmitted by client FT-304 - */ - public void testTwoCompetingConsumers() - { - Consumer c1 = new Consumer(); - Consumer c2 = new Consumer(); - Consumer c3 = new Consumer(); - Consumer c4 = new Consumer(); - - Thread t1 = new Thread(c1); - Thread t2 = new Thread(c2); - Thread t3 = new Thread(c3); - Thread t4 = new Thread(c4); - - t1.start(); - t2.start(); - t3.start(); - // t4.start(); - - try - { - t1.join(); - t2.join(); - t3.join(); - t4.join(); - } - catch (InterruptedException e) - { - fail("Unable to join to Consumer theads"); - } - - _logger.info("consumer 1 count is " + c1.getCount()); - _logger.info("consumer 2 count is " + c2.getCount()); - _logger.info("consumer 3 count is " + c3.getCount()); - _logger.info("consumer 4 count is " + c4.getCount()); - - Integer totalConsumed = c1.getCount() + c2.getCount() + c3.getCount() + c4.getCount(); - - // Check all messages were correctly delivered - int index = 0; - StringBuilder list = new StringBuilder(); - list.append("Failed to receive:"); - int failed = 0; - if (!conn.isBroker010()) - { - for (long b : receieved) - { - if ((b == 0) && (index != 0)) // delivery tag of zero shouldn't exist (and we don't have msg 0) - { - _logger.error("Index: " + index + " was not received."); - list.append(" "); - list.append(index); - list.append(":"); - list.append(b); - failed++; - } - - index++; - } - - assertEquals(list.toString() + "-" + numTestMessages + "-" + totalConsumed, 0, failed); - } - assertEquals("number of consumed messages does not match initial data", numTestMessages, totalConsumed); - passed = true; - } - - class Consumer implements Runnable - { - private Integer count = 0; - private Integer id; - - public Consumer() - { - id = consumerIds.addAndGet(1); - } - - public void run() - { - try - { - _logger.info("consumer-" + id + ": starting"); - QpidClientConnection conn = new QpidClientConnection(BROKER); - - conn.connect(); - - _logger.info("consumer-" + id + ": connected, consuming..."); - Message result; - do - { - result = conn.getNextMessage(queue, consumeTimeout); - if (result != null) - { - - long dt = ((AbstractJMSMessage) result).getDeliveryTag(); - - if (testReception) - { - int msgindex = result.getIntProperty("index"); - if (receieved[msgindex] != 0) - { - _logger.error("Received Message(" + msgindex + ":" - + ((AbstractJMSMessage) result).getDeliveryTag() + ") more than once."); - } - - if (_logger.isInfoEnabled()) - { - _logger.info("Received Message(" + System.identityHashCode(msgindex) + ") " + "DT:" + dt - + "IN:" + msgindex); - } - - if (dt == 0) - { - _logger.error("DT is zero for msg:" + msgindex); - } - - receieved[msgindex] = dt; - } - - count++; - if ((count % 100) == 0) - { - _logger.info("consumer-" + id + ": got " + result + ", new count is " + count); - } - } - } - while (result != null); - - _logger.info("consumer-" + id + ": complete"); - conn.disconnect(); - - } - catch (Exception e) - { - _logger.error("Consumer run error",e); - } - } - - public Integer getCount() - { - return count; - } - - public Integer getId() - { - return id; - } - } - - public void testRequeue() throws JMSException, AMQException, URLSyntaxException - { - int run = 0; - // while (run < 10) - { - run++; - - if (_logger.isInfoEnabled()) - { - _logger.info("testRequeue run " + run); - } - - String virtualHost = "/test"; - String brokerlist = BROKER; - String brokerUrl = "amqp://guest:guest@" + virtualHost + "?brokerlist='" + brokerlist + "'"; - QpidClientConnection qpc = new QpidClientConnection(BROKER); - qpc.connect(); - Connection conn = qpc. getConnection(); - - Session session = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE); - Queue q = session.createQueue(queue); - - _logger.debug("Create Consumer"); - MessageConsumer consumer = session.createConsumer(q); - - conn.start(); - - _logger.debug("Receiving msg"); - Message msg = consumer.receive(2000); - - assertNotNull("Message should not be null", msg); - - // As we have not ack'd message will be requeued. - _logger.debug("Close Consumer"); - consumer.close(); - - _logger.debug("Close Connection"); - conn.close(); - } - } - -} diff --git a/qpid/java/systests/src/test/java/org/apache/qpid/test/utils/QpidClientConnection.java b/qpid/java/systests/src/test/java/org/apache/qpid/test/utils/QpidClientConnection.java deleted file mode 100644 index 0e0032da64..0000000000 --- a/qpid/java/systests/src/test/java/org/apache/qpid/test/utils/QpidClientConnection.java +++ /dev/null @@ -1,288 +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.test.utils; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.JMSAMQException; - -import javax.jms.Connection; -import javax.jms.ExceptionListener; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; -import javax.jms.Queue; -import javax.jms.Session; -import javax.jms.TextMessage; - -public class QpidClientConnection extends QpidBrokerTestCase implements ExceptionListener -{ - private static final Logger _logger = LoggerFactory.getLogger(QpidClientConnection.class); - - private boolean transacted = true; - private int ackMode = Session.CLIENT_ACKNOWLEDGE; - private Connection connection; - - private String virtualHost; - private String brokerlist; - private int prefetch; - protected Session session; - protected boolean connected; - - public QpidClientConnection(String broker) - { - super(); - setVirtualHost("/test"); - setBrokerList(broker); - setPrefetch(5000); - } - - - public Connection getConnection() - { - return connection; - } - - public void connect() throws JMSException - { - if (!connected) - { - /* - * amqp://[user:pass@][clientid]/virtualhost? - * brokerlist='[transport://]host[:port][?option='value'[&option='value']];' - * [&failover='method[?option='value'[&option='value']]'] - * [&option='value']" - */ - String brokerUrl = "amqp://guest:guest@" + virtualHost + "?brokerlist='" + brokerlist + "'"; - try - { - _logger.info("connecting to Qpid :" + brokerUrl); - connection = getConnection("guest", "guest") ; - // register exception listener - connection.setExceptionListener(this); - - session = ((AMQConnection) connection).createSession(transacted, ackMode, prefetch); - - _logger.info("starting connection"); - connection.start(); - - connected = true; - } - catch (Exception e) - { - throw new JMSAMQException("URL syntax error in [" + brokerUrl + "]: " + e.getMessage(), e); - } - } - } - - public void disconnect() throws Exception - { - if (connected) - { - session.commit(); - session.close(); - connection.close(); - connected = false; - _logger.info("disconnected"); - } - } - - public void disconnectWithoutCommit() throws JMSException - { - if (connected) - { - session.close(); - connection.close(); - connected = false; - _logger.info("disconnected without commit"); - } - } - - public String getBrokerList() - { - return brokerlist; - } - - public void setBrokerList(String brokerlist) - { - this.brokerlist = brokerlist; - } - - public String getVirtualHost() - { - return virtualHost; - } - - public void setVirtualHost(String virtualHost) - { - this.virtualHost = virtualHost; - } - - public void setPrefetch(int prefetch) - { - this.prefetch = prefetch; - } - - /** override as necessary */ - public void onException(JMSException exception) - { - _logger.info("ExceptionListener event: error " + exception.getErrorCode() + ", message: " + exception.getMessage()); - } - - public boolean isConnected() - { - return connected; - } - - public Session getSession() - { - return session; - } - - /** - * Put a String as a text messages, repeat n times. A null payload will result in a null message. - * - * @param queueName The queue name to put to - * @param payload the content of the payload - * @param copies the number of messages to put - * - * @throws javax.jms.JMSException any exception that occurs - */ - public void put(String queueName, String payload, int copies) throws JMSException - { - if (!connected) - { - connect(); - } - - _logger.info("putting to queue " + queueName); - Queue queue = session.createQueue(queueName); - - final MessageProducer sender = session.createProducer(queue); - - for (int i = 0; i < copies; i++) - { - Message m = session.createTextMessage(payload + i); - m.setIntProperty("index", i + 1); - sender.send(m); - } - - session.commit(); - sender.close(); - _logger.info("put " + copies + " copies"); - } - - /** - * GET the top message on a queue. Consumes the message. Accepts timeout value. - * - * @param queueName The quename to get from - * @param readTimeout The timeout to use - * - * @return the content of the text message if any - * - * @throws javax.jms.JMSException any exception that occured - */ - public Message getNextMessage(String queueName, long readTimeout) throws JMSException - { - if (!connected) - { - connect(); - } - - Queue queue = session.createQueue(queueName); - - final MessageConsumer consumer = session.createConsumer(queue); - - Message message = consumer.receive(readTimeout); - session.commit(); - consumer.close(); - - Message result; - - // all messages we consume should be TextMessages - if (message instanceof TextMessage) - { - result = ((TextMessage) message); - } - else if (null == message) - { - result = null; - } - else - { - _logger.info("warning: received non-text message"); - result = message; - } - - return result; - } - - /** - * GET the top message on a queue. Consumes the message. - * - * @param queueName The Queuename to get from - * - * @return The string content of the text message, if any received - * - * @throws javax.jms.JMSException any exception that occurs - */ - public Message getNextMessage(String queueName) throws JMSException - { - return getNextMessage(queueName, 0); - } - - /** - * Completely clears a queue. For readTimeout behaviour see Javadocs for javax.jms.MessageConsumer. - * - * @param queueName The Queue name to consume from - * @param readTimeout The timeout for each consume - * - * @throws javax.jms.JMSException Any exception that occurs during the consume - * @throws InterruptedException If the consume thread was interrupted during a consume. - */ - public void consume(String queueName, int readTimeout) throws JMSException, InterruptedException - { - if (!connected) - { - connect(); - } - - _logger.info("consuming queue " + queueName); - Queue queue = session.createQueue(queueName); - - final MessageConsumer consumer = session.createConsumer(queue); - int messagesReceived = 0; - - _logger.info("consuming..."); - while ((consumer.receive(readTimeout)) != null) - { - messagesReceived++; - } - - session.commit(); - consumer.close(); - _logger.info("consumed: " + messagesReceived); - } -} diff --git a/qpid/java/test-profiles/Java010Excludes b/qpid/java/test-profiles/Java010Excludes index 136bc7918f..7294275684 100755 --- a/qpid/java/test-profiles/Java010Excludes +++ b/qpid/java/test-profiles/Java010Excludes @@ -34,7 +34,6 @@ org.apache.qpid.test.unit.topic.DurableSubscriptionTest#testUnsubscribeWhenUsing org.apache.qpid.server.logging.ChannelLoggingTest#testChannelStartsFlowStopped org.apache.qpid.server.logging.ChannelLoggingTest#testChannelStartConsumerFlowStarted org.apache.qpid.server.logging.ConsumerLoggingTest#testSubscriptionSuspend -org.apache.qpid.server.logging.ChannelLoggingTest#testChannelClosedOnQueueArgumentsMismatch // 0-10 is not supported by the MethodRegistry org.apache.qpid.test.unit.close.JavaServerCloseRaceConditionTest#* |
