You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by or...@apache.org on 2019/07/26 23:01:41 UTC
[qpid-broker-j] branch master updated: QPID-8348: [Broker-J] Add
ability to reload keystore/truststore
This is an automated email from the ASF dual-hosted git repository.
orudyy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/qpid-broker-j.git
The following commit(s) were added to refs/heads/master by this push:
new ca6626e QPID-8348: [Broker-J] Add ability to reload keystore/truststore
ca6626e is described below
commit ca6626ee2a5f317ed0426b2219236364b859969f
Author: Alex Rudyy <or...@apache.org>
AuthorDate: Sat Jul 27 00:00:35 2019 +0100
QPID-8348: [Broker-J] Add ability to reload keystore/truststore
---
.../apache/qpid/server/security/FileKeyStore.java | 5 +
.../qpid/server/security/FileKeyStoreImpl.java | 8 +-
.../qpid/server/security/FileTrustStore.java | 4 +
.../qpid/server/security/FileTrustStoreImpl.java | 12 ++-
.../qpid/server/security/FileKeyStoreTest.java | 62 +++++++++++
.../qpid/server/security/FileTrustStoreTest.java | 55 ++++++++++
.../qpid/server/security/KeystoreTestHelper.java | 114 +++++++++++++++++++++
.../js/qpid/management/store/filekeystore/show.js | 58 ++++++++++-
.../qpid/management/store/filetruststore/show.js | 58 ++++++++++-
.../java/resources/store/filekeystore/show.html | 3 +
.../java/resources/store/filetruststore/show.html | 3 +
11 files changed, 373 insertions(+), 9 deletions(-)
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStore.java b/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStore.java
index 56eede1..cf1145b 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStore.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStore.java
@@ -29,6 +29,7 @@ import org.apache.qpid.server.model.KeyStore;
import org.apache.qpid.server.model.ManagedAttribute;
import org.apache.qpid.server.model.ManagedContextDefault;
import org.apache.qpid.server.model.ManagedObject;
+import org.apache.qpid.server.model.ManagedOperation;
@ManagedObject( category = false, type = "FileKeyStore" )
public interface FileKeyStore<X extends FileKeyStore<X>> extends KeyStore<X>
@@ -70,4 +71,8 @@ public interface FileKeyStore<X extends FileKeyStore<X>> extends KeyStore<X>
@ManagedAttribute( defaultValue = "true", description = "Use SNI server name from the SSL handshake to select the most appropriate certificate for the indicated hostname")
boolean isUseHostNameMatching();
+
+ @ManagedOperation( description = "Reloads keystore.", changesConfiguredObjectState = true)
+ void reload();
+
}
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreImpl.java b/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreImpl.java
index 7f7408f..b6c6c1a 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreImpl.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreImpl.java
@@ -139,7 +139,7 @@ public class FileKeyStoreImpl extends AbstractKeyStore<FileKeyStoreImpl> impleme
}
catch (GeneralSecurityException | IOException e)
{
- result = Collections.emptyList();
+ throw new IllegalConfigurationException(String.format("Cannot instantiate keystore '%s'", getName()), e);
}
_certificates = result;
}
@@ -275,6 +275,12 @@ public class FileKeyStoreImpl extends AbstractKeyStore<FileKeyStoreImpl> impleme
return _useHostNameMatching;
}
+ @Override
+ public void reload()
+ {
+ initialize();
+ }
+
public void setPassword(String password)
{
_password = password;
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStore.java b/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStore.java
index a8e1975..6842130 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStore.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStore.java
@@ -28,6 +28,7 @@ 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;
+import org.apache.qpid.server.model.ManagedOperation;
import org.apache.qpid.server.model.TrustStore;
@ManagedObject( category = false, type = "FileTrustStore" )
@@ -69,4 +70,7 @@ public interface FileTrustStore<X extends FileTrustStore<X>> extends TrustStore<
String getPassword();
void setPassword(String password);
+
+ @ManagedOperation( description = "Reloads trust store.", changesConfiguredObjectState = true)
+ void reload();
}
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java b/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java
index c503801..508e464 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java
@@ -236,6 +236,12 @@ public class FileTrustStoreImpl extends AbstractTrustStore<FileTrustStoreImpl> i
}
@Override
+ public void reload()
+ {
+ initialize();
+ }
+
+ @Override
protected TrustManager[] getTrustManagersInternal()
{
TrustManager[] trustManagers = _trustManagers;
@@ -287,8 +293,10 @@ public class FileTrustStoreImpl extends AbstractTrustStore<FileTrustStoreImpl> i
try
{
KeyStore ts = initializeKeyStore(this);
- _trustManagers = createTrustManagers(ts);
- _certificates = createCertificates(ts);
+ TrustManager[] trustManagers = createTrustManagers(ts);
+ Certificate[] certificates = createCertificates(ts);
+ _trustManagers = trustManagers;
+ _certificates = certificates;
}
catch (Exception e)
{
diff --git a/broker-core/src/test/java/org/apache/qpid/server/security/FileKeyStoreTest.java b/broker-core/src/test/java/org/apache/qpid/server/security/FileKeyStoreTest.java
index 3d75ac0..18b2d37 100644
--- a/broker-core/src/test/java/org/apache/qpid/server/security/FileKeyStoreTest.java
+++ b/broker-core/src/test/java/org/apache/qpid/server/security/FileKeyStoreTest.java
@@ -23,16 +23,23 @@ package org.apache.qpid.server.security;
import static org.apache.qpid.server.security.FileTrustStoreTest.SYMMETRIC_KEY_KEYSTORE_RESOURCE;
import static org.apache.qpid.server.security.FileTrustStoreTest.createDataUrlForFile;
import static org.apache.qpid.test.utils.TestSSLConstants.JAVA_KEYSTORE_TYPE;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import java.io.File;
import java.net.URL;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import javax.net.ssl.KeyManager;
@@ -49,7 +56,9 @@ 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.server.transport.network.security.ssl.SSLUtil;
import org.apache.qpid.server.util.DataUrlUtils;
+import org.apache.qpid.test.utils.TestFileUtils;
import org.apache.qpid.test.utils.TestSSLConstants;
import org.apache.qpid.test.utils.UnitTestBase;
@@ -401,4 +410,57 @@ public class FileKeyStoreTest extends UnitTestBase
}
+ @Test
+ public void testReloadKeystore() throws Exception
+ {
+ assumeThat(SSLUtil.canGenerateCerts(), is(equalTo(true)));
+
+ final SSLUtil.KeyCertPair selfSigned1 = KeystoreTestHelper.generateSelfSigned("CN=foo");
+ final SSLUtil.KeyCertPair selfSigned2 = KeystoreTestHelper.generateSelfSigned("CN=bar");
+
+ final File keyStoreFile = TestFileUtils.createTempFile(this, ".ks");
+ final String dummy = "changit";
+ final char[] pass = dummy.toCharArray();
+ final String certificateAlias = "test1";
+ final String keyAlias = "test2";
+ try
+ {
+ final java.security.KeyStore keyStore =
+ KeystoreTestHelper.saveKeyStore(selfSigned1, certificateAlias, keyAlias, pass, keyStoreFile);
+
+ final Map<String, Object> attributes = new HashMap<>();
+ attributes.put(FileKeyStore.NAME, getTestName());
+ attributes.put(FileKeyStore.STORE_URL, keyStoreFile.getAbsolutePath());
+ attributes.put(FileKeyStore.PASSWORD, dummy);
+ attributes.put(FileKeyStore.KEY_STORE_TYPE, keyStore.getType());
+
+ final FileKeyStore keyStoreObject = (FileKeyStore) _factory.create(KeyStore.class, attributes, _broker);
+
+ final CertificateDetails certificate = getCertificate(keyStoreObject);
+ assertEquals("CN=foo", certificate.getIssuerName());
+
+ assertTrue(keyStoreFile.delete());
+ assertTrue(keyStoreFile.createNewFile());keyStoreFile.deleteOnExit();
+ KeystoreTestHelper.saveKeyStore(selfSigned2, certificateAlias, keyAlias, pass, keyStoreFile);
+
+ keyStoreObject.reload();
+
+ final CertificateDetails certificate2 = getCertificate(keyStoreObject);
+ assertEquals("CN=bar", certificate2.getIssuerName());
+ }
+ finally
+ {
+ assertTrue(keyStoreFile.delete());
+ }
+ }
+
+ public CertificateDetails getCertificate(final FileKeyStore keyStore) throws java.security.GeneralSecurityException
+ {
+ final List<CertificateDetails> certificates = keyStore.getCertificateDetails();
+
+ assertNotNull(certificates);
+ assertEquals(1, certificates.size());
+
+ return certificates.get(0);
+ }
}
diff --git a/broker-core/src/test/java/org/apache/qpid/server/security/FileTrustStoreTest.java b/broker-core/src/test/java/org/apache/qpid/server/security/FileTrustStoreTest.java
index 4e99790..427e0b7 100644
--- a/broker-core/src/test/java/org/apache/qpid/server/security/FileTrustStoreTest.java
+++ b/broker-core/src/test/java/org/apache/qpid/server/security/FileTrustStoreTest.java
@@ -66,7 +66,9 @@ 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.server.transport.network.security.ssl.QpidPeersOnlyTrustManager;
+import org.apache.qpid.server.transport.network.security.ssl.SSLUtil;
import org.apache.qpid.server.util.DataUrlUtils;
+import org.apache.qpid.test.utils.TestFileUtils;
import org.apache.qpid.test.utils.TestSSLConstants;
import org.apache.qpid.test.utils.UnitTestBase;
@@ -444,6 +446,59 @@ public class FileTrustStoreTest extends UnitTestBase
(long) certificates.length);
}
+ @Test
+ public void testReloadKeystore() throws Exception
+ {
+ assumeThat(SSLUtil.canGenerateCerts(), is(equalTo(true)));
+
+ final SSLUtil.KeyCertPair selfSigned1 = KeystoreTestHelper.generateSelfSigned("CN=foo");
+ final SSLUtil.KeyCertPair selfSigned2 = KeystoreTestHelper.generateSelfSigned("CN=bar");
+
+ final File keyStoreFile = TestFileUtils.createTempFile(this, ".ks");
+ final String dummy = "changit";
+ final char[] pass = dummy.toCharArray();
+ final String alias = "test";
+ try
+ {
+ final java.security.KeyStore keyStore =
+ KeystoreTestHelper.saveKeyStore(alias, selfSigned1.getCertificate(), pass, keyStoreFile);
+
+ final Map<String, Object> attributes = new HashMap<>();
+ attributes.put(FileTrustStore.NAME, getTestName());
+ attributes.put(FileTrustStore.PASSWORD, dummy);
+ attributes.put(FileTrustStore.STORE_URL, keyStoreFile.getAbsolutePath());
+ attributes.put(FileTrustStore.TRUST_STORE_TYPE, keyStore.getType());
+
+ final FileTrustStore trustStore = (FileTrustStore) _factory.create(TrustStore.class, attributes, _broker);
+
+ final X509Certificate certificate = getCertificate(trustStore);
+ assertEquals("CN=foo", certificate.getIssuerX500Principal().getName());
+
+ KeystoreTestHelper.saveKeyStore(alias, selfSigned2.getCertificate(), pass, keyStoreFile);
+
+ trustStore.reload();
+
+ final X509Certificate certificate2 = getCertificate(trustStore);
+ assertEquals("CN=bar", certificate2.getIssuerX500Principal().getName());
+ }
+ finally
+ {
+ assertTrue(keyStoreFile.delete());
+ }
+ }
+
+ public X509Certificate getCertificate(final FileTrustStore trustStore) throws java.security.GeneralSecurityException
+ {
+ Certificate[] certificates = trustStore.getCertificates();
+
+ assertNotNull(certificates);
+ assertEquals(1, certificates.length);
+
+ Certificate certificate = certificates[0];
+ assertTrue(certificate instanceof X509Certificate);
+ return (X509Certificate)certificate;
+ }
+
private int getNumberOfCertificates(URL url, String type) throws Exception
{
KeyStore ks = KeyStore.getInstance(type);
diff --git a/broker-core/src/test/java/org/apache/qpid/server/security/KeystoreTestHelper.java b/broker-core/src/test/java/org/apache/qpid/server/security/KeystoreTestHelper.java
new file mode 100644
index 0000000..6278f33
--- /dev/null
+++ b/broker-core/src/test/java/org/apache/qpid/server/security/KeystoreTestHelper.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.qpid.server.security;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
+import java.util.Collections;
+
+import org.apache.qpid.server.transport.network.security.ssl.SSLUtil;
+
+public class KeystoreTestHelper
+{
+ public static KeyStore saveKeyStore(final String alias,
+ final X509Certificate certificate,
+ final char[] pass,
+ final File file)
+ throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException
+ {
+ final KeyStore ks = createEmptyKeyStore();
+ ks.setCertificateEntry(alias, certificate);
+ saveKeyStore(ks, pass, file);
+ return ks;
+ }
+
+ public static KeyStore saveKeyStore(final SSLUtil.KeyCertPair keyCertPair,
+ final String keyAlias,
+ final String certificateAlias,
+ final char[] pass,
+ final File file)
+ throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException
+ {
+ final KeyStore ks = createKeyStore(keyCertPair, keyAlias, certificateAlias, pass);
+ saveKeyStore(ks, pass, file);
+ return ks;
+ }
+
+
+ public static SSLUtil.KeyCertPair generateSelfSigned(final String cn)
+ throws IllegalAccessException, InvocationTargetException, InstantiationException
+ {
+ return SSLUtil.generateSelfSignedCertificate("RSA",
+ "SHA256WithRSA",
+ 2048,
+ Instant.now()
+ .minus(1, ChronoUnit.DAYS)
+ .toEpochMilli(),
+ Duration.of(365, ChronoUnit.DAYS)
+ .getSeconds(),
+ cn,
+ Collections.emptySet(),
+ Collections.emptySet());
+ }
+
+
+ private static File saveKeyStore(final KeyStore ks, final char[] pass, final File storeFile)
+ throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException
+ {
+ try (FileOutputStream fos = new FileOutputStream(storeFile))
+ {
+ ks.store(fos, pass);
+ }
+ return storeFile;
+ }
+
+ private static KeyStore createKeyStore(final SSLUtil.KeyCertPair keyCertPair,
+ final String keyAlias,
+ final String certificateAlias,
+ final char[] pass)
+ throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException
+ {
+ final KeyStore ks = createEmptyKeyStore();
+ ks.setCertificateEntry(certificateAlias, keyCertPair.getCertificate());
+ ks.setKeyEntry(keyAlias,
+ keyCertPair.getPrivateKey(),
+ pass,
+ new X509Certificate[]{keyCertPair.getCertificate()});
+ return ks;
+ }
+
+ private static KeyStore createEmptyKeyStore()
+ throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException
+ {
+ final KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+ ks.load(null);
+ return ks;
+ }
+}
diff --git a/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/filekeystore/show.js b/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/filekeystore/show.js
index 267f2ae..90253f8 100644
--- a/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/filekeystore/show.js
+++ b/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/filekeystore/show.js
@@ -17,7 +17,16 @@
* under the License.
*/
-define(["qpid/common/util", "dojo/domReady!"], function (util)
+define(["dojo/_base/lang",
+ "qpid/common/util",
+ "dojo/query",
+ "dojo/mouse",
+ "dojo/on",
+ "dijit/registry",
+ "dijit/Tooltip",
+ "dijit/form/Button",
+ "dojo/domReady!"],
+ function (lang, util, query, mouse, on, registry, Tooltip)
{
function FileKeyStoreProvider(data)
@@ -28,13 +37,56 @@ define(["qpid/common/util", "dojo/domReady!"], function (util)
{
this.fields.push(name);
}
- util.buildUI(data.containerNode, data.parent, "store/filekeystore/show.html", this.fields, this);
+
+ this.parent = data.parent;
+ this.management = data.parent.management;
+ this.modelObj = data.parent.modelObj;
+ this.containerNode = data.containerNode;
+
+ util.buildUI(data.containerNode,
+ data.parent,
+ "store/filekeystore/show.html",
+ this.fields,
+ this,
+ lang.hitch(this, function(){
+ this.reloadButton = registry.byNode(query(".reload", data.containerNode)[0]);
+ this.reloadButton.on("click", lang.hitch(this, this.reload));
+ }));
}
FileKeyStoreProvider.prototype.update = function (data)
{
util.updateUI(data, this.fields, this);
- }
+ };
+
+ FileKeyStoreProvider.prototype.reload = function (evt)
+ {
+ evt.preventDefault();
+ evt.stopPropagation();
+ this.reloadButton.set("disabled", true);
+ var parentModelObj = this.modelObj;
+ var modelObj = {
+ type: parentModelObj.type,
+ name: "reload",
+ parent: parentModelObj
+ };
+ var url = this.management.buildObjectURL(modelObj);
+ this.management.post({url: url}, {})
+ .then(lang.hitch(this, function () {
+ this.parent.update();
+ var domNode = this.reloadButton.domNode;
+ Tooltip.show("Keystore is reloaded successfully", domNode);
+ on.once(domNode, mouse.leave, function()
+ {
+ Tooltip.hide(domNode);
+ });
+ }),
+ this.management.xhrErrorHandler)
+ .always(lang.hitch(this, function ()
+ {
+ this.reloadButton.set("disabled", false);
+ }));
+ };
return FileKeyStoreProvider;
});
diff --git a/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/filetruststore/show.js b/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/filetruststore/show.js
index 83e0d37..7638bfc 100644
--- a/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/filetruststore/show.js
+++ b/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/filetruststore/show.js
@@ -17,7 +17,16 @@
* under the License.
*/
-define(["qpid/common/util", "dojo/domReady!"], function (util)
+define(["dojo/_base/lang",
+ "qpid/common/util",
+ "dojo/query",
+ "dojo/mouse",
+ "dojo/on",
+ "dijit/registry",
+ "dijit/Tooltip",
+ "dijit/form/Button",
+ "dojo/domReady!"],
+ function (lang, util, query, mouse, on, registry, Tooltip)
{
function FileTrustStoreProvider(data)
@@ -28,13 +37,56 @@ define(["qpid/common/util", "dojo/domReady!"], function (util)
{
this.fields.push(name);
}
- util.buildUI(data.containerNode, data.parent, "store/filetruststore/show.html", this.fields, this);
+
+ this.parent = data.parent;
+ this.management = data.parent.management;
+ this.modelObj = data.parent.modelObj;
+ this.containerNode = data.containerNode;
+
+ util.buildUI(data.containerNode,
+ data.parent,
+ "store/filetruststore/show.html",
+ this.fields,
+ this,
+ lang.hitch(this, function(){
+ this.reloadButton = registry.byNode(query(".reload", data.containerNode)[0]);
+ this.reloadButton.on("click", lang.hitch(this, this.reload));
+ }));
}
FileTrustStoreProvider.prototype.update = function (data)
{
util.updateUI(data, this.fields, this);
- }
+ };
+
+ FileTrustStoreProvider.prototype.reload = function (evt)
+ {
+ evt.preventDefault();
+ evt.stopPropagation();
+ this.reloadButton.set("disabled", true);
+ var parentModelObj = this.modelObj;
+ var modelObj = {
+ type: parentModelObj.type,
+ name: "reload",
+ parent: parentModelObj
+ };
+ var url = this.management.buildObjectURL(modelObj);
+ this.management.post({url: url}, {})
+ .then(lang.hitch(this, function () {
+ this.parent.update();
+ var domNode = this.reloadButton.domNode;
+ Tooltip.show("Truststore is reloaded successfully", domNode);
+ on.once(domNode, mouse.leave, function()
+ {
+ Tooltip.hide(domNode);
+ });
+ }),
+ this.management.xhrErrorHandler)
+ .always(lang.hitch(this, function ()
+ {
+ this.reloadButton.set("disabled", false);
+ }));
+ };
return FileTrustStoreProvider;
});
diff --git a/broker-plugins/management-http/src/main/java/resources/store/filekeystore/show.html b/broker-plugins/management-http/src/main/java/resources/store/filekeystore/show.html
index 74284e5..a7c5540 100644
--- a/broker-plugins/management-http/src/main/java/resources/store/filekeystore/show.html
+++ b/broker-plugins/management-http/src/main/java/resources/store/filekeystore/show.html
@@ -38,6 +38,9 @@
<div class="formLabel-labelCell">Use SNI host name matching:</div>
<div><span class="useHostNameMatching" ></span></div>
</div>
+ <div class="clear">
+ <button data-dojo-type="dijit/form/Button" class="reload">Reload</button>
+ </div>
<div class="clear"></div>
</div>
diff --git a/broker-plugins/management-http/src/main/java/resources/store/filetruststore/show.html b/broker-plugins/management-http/src/main/java/resources/store/filetruststore/show.html
index 99190d1..f936e56 100644
--- a/broker-plugins/management-http/src/main/java/resources/store/filetruststore/show.html
+++ b/broker-plugins/management-http/src/main/java/resources/store/filetruststore/show.html
@@ -34,6 +34,9 @@
<div class="formLabel-labelCell">Trust manager factory algorithm:</div>
<div><span class="trustManagerFactoryAlgorithm" ></span></div>
</div>
+ <div class="clear">
+ <button data-dojo-type="dijit/form/Button" class="reload">Reload</button>
+ </div>
<div class="clear"></div>
</div>
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org