diff options
author | Robert Godfrey <rgodfrey@apache.org> | 2013-04-22 11:00:18 +0000 |
---|---|---|
committer | Robert Godfrey <rgodfrey@apache.org> | 2013-04-22 11:00:18 +0000 |
commit | 8eaa6f007e3cf2d287067b993ccf8058d0c66690 (patch) | |
tree | 75188469b2a27a15e8a5138a06640fc82e4f1c61 | |
parent | 05c01aacd2b0987ff7438d0d172fff60c7450201 (diff) | |
download | qpid-python-8eaa6f007e3cf2d287067b993ccf8058d0c66690.tar.gz |
QPID-4657, QPID-4683 : merged to QPID-4659 branch
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/QPID-4659@1470450 13f79535-47bb-0310-9956-ffa450edef68
9 files changed, 272 insertions, 39 deletions
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 fddd52138b..2f49ab1448 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 @@ -22,20 +22,20 @@ <div data-dojo-type="dijit.Dialog" style="width:600px;" data-dojo-props="title:'Port'" id="addPort"> <form id="formAddPort" method="post" dojoType="dijit.form.Form"> <div id="formAddPort:fields"> - <input type="text" required="true" name="name" id="formAddPort.name" placeholder="Port Name" - data-dojo-props="label: 'Port Name*:'" dojoType="dijit.form.ValidationTextBox" + <input type="text" required="true" name="name" id="formAddPort.name" placeholder="Name" + data-dojo-props="label: 'Name*:'" dojoType="dijit.form.ValidationTextBox" missingMessage="A name must be supplied" /> - <input data-dojo-type="dijit.form.NumberSpinner" id="formAddPort.port" data-dojo-props="label: 'Port*:'" - name="port" value="5672" smallDelta="1" constraints="{min:1,max:65535,places:0, pattern: '#####'}" /> - <select id="formAddPort.transport" data-dojo-type="dijit.form.FilteringSelect" - data-dojo-props="name: 'transport',label: 'Transport:',searchAttr: 'name',required:false,placeHolder: 'Select Transports', value: '' " + <input data-dojo-type="dijit.form.NumberSpinner" id="formAddPort.port" required="true" data-dojo-props="label: 'Port Number*:'" + name="port" smallDelta="1" constraints="{min:1,max:65535,places:0, pattern: '#####'}" + missingMessage="A port number must be supplied" /> + <select id="formAddPort.transports" data-dojo-type="dijit.form.FilteringSelect" + data-dojo-props="name: 'transports',label: 'Transport:',searchAttr: 'name',required:false,placeHolder: 'TCP', value: '' " style="margin: 0;"> <option value="TCP">TCP</option> <option value="SSL">SSL</option> </select> <select id="formAddPort.authenticationProvider" data-dojo-type="dijit.form.FilteringSelect" style="margin: 0;" - data-dojo-props="name:'authenticationProvider',label:'Authentication Provider:', searchAttr: 'name', required: false, placeHolder: 'Select Authentication', value: '' " - missingMessage="Transport must be supplied"> + data-dojo-props="name:'authenticationProvider',label:'Authentication Provider:', searchAttr: 'name', required: false, placeHolder: 'Default', value: '' "> </select> <select id="formAddPort.type" data-dojo-type="dijit.form.FilteringSelect" data-dojo-props="name: 'type', value: '',placeHolder: 'Select Port Type', label: 'Port Type:'"> @@ -44,13 +44,19 @@ <option value="HTTP">HTTP</option> </select> </div> + <div id="formAddPort:fieldsClientAuth"> + <input id="formAddPort.needClientAuth" type="checkbox" name="needClientAuth" + dojoType="dijit.form.CheckBox" data-dojo-props="label: 'Need SSL Client Certificate:'"/> + <input id="formAddPort.wantClientAuth" type="checkbox" name="wantClientAuth" + dojoType="dijit.form.CheckBox" data-dojo-props="label: 'Want SSL Client Certificate:'"/> + </div> <div id="formAddPort:fieldsAMQP"> - <input id="formAddPort.bindingAddress" type="text" name="bindingAddress" + <input id="formAddPort.bindingAddress" type="text" name="bindingAddress" placeholder="*" dojoType="dijit.form.TextBox" data-dojo-props="label: 'Binding address:'"/> <input id="formAddPort.protocolsDefault" type="checkbox" name="protocolsDefault" checked="checked" - dojoType="dijit.form.CheckBox" data-dojo-props="label: 'Use broker default AMQP protocols:'"/> + dojoType="dijit.form.CheckBox" data-dojo-props="label: 'Support broker default AMQP versions:'"/> <select id="formAddPort.protocolsAMQP" name="protocols" data-dojo-type="dijit.form.MultiSelect" multiple="true" - data-dojo-props="name: 'protocols', value: '', placeHolder: 'Select Protocols', label: 'AMQP protocols:'" + data-dojo-props="name: 'protocols', value: '', placeHolder: 'Select AMQP versions', label: 'AMQP versions:'" missingMessage="AMQP protocol(s) must be supplied"> <option value="AMQP_0_8">AMQP 0.8</option> <option value="AMQP_0_9">AMQP 0.9</option> @@ -61,14 +67,14 @@ </div> <div id="formAddPort:fieldsJMX"> <select id="formAddPort.protocolsJMX" name="protocols" data-dojo-type="dijit.form.FilteringSelect" - data-dojo-props="name: 'protocols', value: '', label: 'JMX protocols*:'" missingMessage="JMX protocol must be supplied"> + data-dojo-props="name: 'protocols', value: '', label: 'JMX protocol*:'" missingMessage="JMX protocol must be supplied"> <option value="RMI">RMI</option> <option value="JMX_RMI">JMX RMI</option> </select> </div> <div id="formAddPort:fieldsHTTP"> <select id="formAddPort.protocolsHTTP" name="protocols" data-dojo-type="dijit.form.FilteringSelect" - data-dojo-props="name: 'protocols', value: '', label: 'HTTP protocols*:'" missingMessage="HTTP protocol must be supplied"> + data-dojo-props="name: 'protocols', value: '', label: 'HTTP protocol*:'" missingMessage="HTTP protocol must be supplied"> <option value="HTTP">HTTP</option> <option value="HTTPS">HTTPS</option> </select> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addPort.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addPort.js index dec04e604e..4d1e268d4d 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addPort.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addPort.js @@ -75,8 +75,7 @@ define(["dojo/_base/xhr", { continue; } - - if (propName === "protocols") + else if (propName === "protocols") { var val = formValues[propName]; if (!lang.isArray(val)) @@ -85,6 +84,21 @@ define(["dojo/_base/xhr", } newPort[ propName ] = val; } + else if (propName === "transports") + { + var val = formValues[propName]; + + if(val === "") + { + continue; + } + + if (!lang.isArray(val)) + { + val = [ val ]; + } + newPort[ propName ] = val; + } else if(formValues[ propName ] !== "") { newPort[ propName ] = formValues[propName]; @@ -92,6 +106,18 @@ define(["dojo/_base/xhr", } } + + var needClientAuth = dijit.byId("formAddPort.needClientAuth"); + var wantClientAuth = dijit.byId("formAddPort.wantClientAuth"); + if(!needClientAuth.disabled) + { + newPort.needClientAuth = needClientAuth.checked; + } + if(!wantClientAuth.disabled) + { + newPort.wantClientAuth = wantClientAuth.checked; + } + return newPort; }; @@ -115,26 +141,41 @@ define(["dojo/_base/xhr", registry.byId("formAddPort.protocols" + option.value).set("disabled", true); registry.byId("formAddPort:fields" + option.value).domNode.style.display = "none"; }); + + if ("AMQP" == newValue) + { + registry.byId("formAddPort:fieldsClientAuth").domNode.style.display = "block"; + registry.byId("formAddPort.needClientAuth").set("disabled", false); + registry.byId("formAddPort.wantClientAuth").set("disabled", false); + } + else + { + registry.byId("formAddPort:fieldsClientAuth").domNode.style.display = "none"; + registry.byId("formAddPort.needClientAuth").set("checked", false); + registry.byId("formAddPort.wantClientAuth").set("checked", false); + registry.byId("formAddPort.needClientAuth").set("disabled", true); + registry.byId("formAddPort.wantClientAuth").set("disabled", true); + } + registry.byId("formAddPort:fields" + newValue).domNode.style.display = "block"; var defaultsAMQPProtocols = registry.byId("formAddPort.protocolsDefault"); defaultsAMQPProtocols.set("disabled", "AMQP" != newValue) var protocolsWidget = registry.byId("formAddPort.protocols" + newValue); - var transportWidget = registry.byId("formAddPort.transport"); if (protocolsWidget) { if ("AMQP" == newValue && defaultsAMQPProtocols.checked) { protocolsWidget.set("disabled", true); - transportWidget.set("required", false); } else { - // the transport has to be set for a management port - // disabling the default option - transportWidget.set("required", true); protocolsWidget.set("disabled", false); } - transportWidget.startup(); + } + var transportsWidget = registry.byId("formAddPort.transports"); + if (transportsWidget) + { + transportsWidget.startup(); } }); theForm = registry.byId("formAddPort"); @@ -186,6 +227,14 @@ define(["dojo/_base/xhr", customClass: "formLabel" }, dom.byId("formAddPort:fields")); addPort.fields.startup(); + addPort.fieldsClientAuth = new dojox.layout.TableContainer( { + cols: 1, + labelWidth: labelWidthValue, + showLabels: true, + orientation: "horiz", + customClass: "formLabel" + }, dom.byId("formAddPort:fieldsClientAuth")); + addPort.fieldsClientAuth.startup(); addPort.fieldsAMQP = new dojox.layout.TableContainer( { cols: 1, labelWidth: labelWidthValue, @@ -240,7 +289,7 @@ define(["dojo/_base/xhr", nameField.set("disabled", true); dom.byId("formAddPort.id").value=port.id; providerWidget.set("value", port.authenticationProvider ? port.authenticationProvider : ""); - registry.byId("formAddPort.transport").set("value", port.transports ? port.transports[0] : ""); + registry.byId("formAddPort.transports").set("value", port.transports ? port.transports[0] : ""); registry.byId("formAddPort.port").set("value", port.port); var protocols = port.protocols; var typeWidget = registry.byId("formAddPort.type"); @@ -250,6 +299,12 @@ define(["dojo/_base/xhr", registry.byId("formAddPort:fields" + option.value).domNode.style.display = "none"; }); + registry.byId("formAddPort.needClientAuth").set("checked", false); + registry.byId("formAddPort.wantClientAuth").set("checked", false); + registry.byId("formAddPort.needClientAuth").set("disabled", true); + registry.byId("formAddPort.wantClientAuth").set("disabled", true); + registry.byId("formAddPort:fieldsClientAuth").domNode.style.display = "none"; + // identify the type of port using first protocol specified in protocol field if provided if ( !protocols || protocols.length == 0 || protocols[0].indexOf("AMQP") == 0) { @@ -270,6 +325,12 @@ define(["dojo/_base/xhr", defaultProtocolsWidget.set("checked", true); amqpProtocolsWidget.set("disabled", true) } + + registry.byId("formAddPort.needClientAuth").set("disabled", false); + registry.byId("formAddPort.wantClientAuth").set("disabled", false); + registry.byId("formAddPort.needClientAuth").set("checked", port.needClientAuth); + registry.byId("formAddPort.wantClientAuth").set("checked", port.wantClientAuth); + registry.byId("formAddPort:fieldsClientAuth").domNode.style.display = "block"; } else if (protocols[0].indexOf("RMI") != -1) { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java index 56f92ebb6a..8f64cab2ec 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java @@ -215,4 +215,6 @@ public interface Broker extends ConfiguredObject TrustStore getDefaultTrustStore(); TaskExecutor getTaskExecutor(); + + boolean isManagementMode(); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java index 97acac668b..9759718ddd 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java @@ -58,6 +58,7 @@ import org.apache.qpid.server.model.Statistics; import org.apache.qpid.server.model.TrustStore; import org.apache.qpid.server.model.UUIDGenerator; import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.configuration.store.ManagementModeStoreHandler; import org.apache.qpid.server.configuration.updater.TaskExecutor; import org.apache.qpid.server.security.access.Operation; import org.apache.qpid.server.security.group.FileGroupManager; @@ -195,6 +196,8 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat private final Collection<String> _supportedStoreTypes; private final ConfigurationEntryStore _brokerStore; + private boolean _managementMode; + public BrokerAdapter(UUID id, Map<String, Object> attributes, StatisticsGatherer statisticsGatherer, VirtualHostRegistry virtualHostRegistry, LogRecorder logRecorder, RootMessageLogger rootMessageLogger, AuthenticationProviderFactory authenticationProviderFactory, PortFactory portFactory, TaskExecutor taskExecutor, ConfigurationEntryStore brokerStore) @@ -214,6 +217,7 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat createBrokerChildrenFromAttributes(); _supportedStoreTypes = new MessageStoreCreator().getStoreTypes(); _brokerStore = brokerStore; + _managementMode = brokerStore instanceof ManagementModeStoreHandler; } /* @@ -542,11 +546,20 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat port.addChangeListener(this); } + /** + * Called when adding a new port via the management interface + */ private Port createPort(Map<String, Object> attributes) { Port port = _portFactory.createPort(UUID.randomUUID(), this, attributes); addPort(port); - port.setDesiredState(State.INITIALISING, State.ACTIVE); + + //AMQP ports are disable during ManagementMode, and the management + //plugins can currently only start ports at broker startup and + //not when they are newly created via the management interfaces. + boolean quiesce = isManagementMode() || !(port instanceof AmqpPortAdapter); + port.setDesiredState(State.INITIALISING, quiesce ? State.QUIESCED : State.ACTIVE); + return port; } @@ -1237,4 +1250,10 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat throw new AccessControlException("Setting of broker attributes is denied"); } } + + @Override + public boolean isManagementMode() + { + return _managementMode; + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java index a37c2dceb7..ba10816a35 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java @@ -312,6 +312,13 @@ public class PortAdapter extends AbstractAdapter implements Port throw new IllegalStateException("Cannot activate port in " + state + " state"); } } + else if (desiredState == State.QUIESCED) + { + if (state == State.INITIALISING && _state.compareAndSet(state, State.QUIESCED)) + { + return true; + } + } else if (desiredState == State.STOPPED) { if (_state.compareAndSet(state, State.STOPPED)) @@ -351,9 +358,9 @@ public class PortAdapter extends AbstractAdapter implements Port @Override protected void changeAttributes(Map<String, Object> attributes) { - if (getActualState() == State.ACTIVE) + if (getActualState() == State.ACTIVE && !_broker.isManagementMode()) { - throw new IllegalStateException("Cannot change attributes for an active port"); + throw new IllegalStateException("Cannot change attributes for an active port outside of Management Mode"); } super.changeAttributes(MapValueConverter.convert(attributes, ATTRIBUTE_TYPES)); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java index 1872f3e2ee..50bb2e2fcb 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java @@ -104,6 +104,18 @@ public class PortFactory defaults.put(Port.RECEIVE_BUFFER_SIZE, DEFAULT_AMQP_RECEIVE_BUFFER_SIZE); defaults.put(Port.SEND_BUFFER_SIZE, DEFAULT_AMQP_SEND_BUFFER_SIZE); port = new AmqpPortAdapter(id, broker, attributes, defaults, broker.getTaskExecutor()); + + boolean useClientAuth = (Boolean) port.getAttribute(Port.NEED_CLIENT_AUTH) || (Boolean) port.getAttribute(Port.WANT_CLIENT_AUTH); + if(useClientAuth && broker.getTrustStores().isEmpty()) + { + throw new IllegalConfigurationException("Cant create port which requests SSL client certificates as the broker has no trust/peer stores configured."); + } + + boolean doesntUseSSL = port.getTransports().isEmpty() || !port.getTransports().contains(Transport.SSL); + if(useClientAuth && doesntUseSSL) + { + throw new IllegalConfigurationException("Cant create port which requests SSL client certificates but doesnt use SSL transport."); + } } else { @@ -112,18 +124,35 @@ public class PortFactory throw new IllegalConfigurationException("Only one protocol can be used on non AMQP port"); } Protocol protocol = protocols.iterator().next(); - Collection<Port> existingPorts = broker.getPorts(); - for (Port existingPort : existingPorts) + + if(!broker.isManagementMode()) { - Collection<Protocol> portProtocols = existingPort.getProtocols(); - if (portProtocols != null && portProtocols.contains(protocol)) + //ManagementMode needs this relaxed to allow its overriding management ports to be inserted. + + //Enforce only a single port of each management protocol, as the plugins will only use one. + Collection<Port> existingPorts = broker.getPorts(); + for (Port existingPort : existingPorts) { - throw new IllegalConfigurationException("Port for protocol " + protocol + " already exist. Only one management port per protocol can be created"); + Collection<Protocol> portProtocols = existingPort.getProtocols(); + if (portProtocols != null && portProtocols.contains(protocol)) + { + throw new IllegalConfigurationException("Port for protocol " + protocol + " already exist. Only one management port per protocol can be created"); + } } } + defaults.put(Port.NAME, portValue + "-" + protocol.name()); port = new PortAdapter(id, broker, attributes, defaults, broker.getTaskExecutor()); } + + if(port.getTransports().contains(Transport.SSL) || port.getProtocols().contains(Protocol.HTTPS)) + { + if(broker.getKeyStores().isEmpty()) + { + throw new IllegalConfigurationException("Cant create port which requires SSL as the broker has no keystore configured."); + } + } + return port; } diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java index 0c496dfd9b..5d9cfea709 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java @@ -23,6 +23,7 @@ package org.apache.qpid.server.model.adapter; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -36,21 +37,30 @@ import java.util.UUID; import org.apache.qpid.server.configuration.BrokerProperties; import org.apache.qpid.server.configuration.IllegalConfigurationException; import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.KeyStore; import org.apache.qpid.server.model.Port; import org.apache.qpid.server.model.Protocol; import org.apache.qpid.server.model.Transport; +import org.apache.qpid.server.model.TrustStore; import org.apache.qpid.test.utils.QpidTestCase; public class PortFactoryTest extends QpidTestCase { private UUID _portId = UUID.randomUUID(); + private UUID _keyStoreId = UUID.randomUUID(); + private UUID _trustStoreId = UUID.randomUUID(); private int _portNumber = 123; - private Set<String> _tcpStringSet = Collections.singleton(Transport.SSL.name()); - private Set<Transport> _tcpTransportSet = Collections.singleton(Transport.SSL); + private Set<String> _tcpStringSet = Collections.singleton(Transport.TCP.name()); + private Set<Transport> _tcpTransportSet = Collections.singleton(Transport.TCP); + private Set<String> _sslStringSet = Collections.singleton(Transport.SSL.name()); + private Set<Transport> _sslTransportSet = Collections.singleton(Transport.SSL); private Map<String, Object> _attributes = new HashMap<String, Object>(); private Broker _broker = mock(Broker.class); + private KeyStore _keyStore = mock(KeyStore.class); + private TrustStore _trustStore = mock(TrustStore.class); + private PortFactory _portFactory; @Override @@ -66,8 +76,6 @@ public class PortFactoryTest extends QpidTestCase _attributes.put(Port.TCP_NO_DELAY, "true"); _attributes.put(Port.RECEIVE_BUFFER_SIZE, "1"); _attributes.put(Port.SEND_BUFFER_SIZE, "2"); - _attributes.put(Port.NEED_CLIENT_AUTH, "true"); - _attributes.put(Port.WANT_CLIENT_AUTH, "true"); _attributes.put(Port.BINDING_ADDRESS, "127.0.0.1"); } @@ -126,22 +134,116 @@ public class PortFactoryTest extends QpidTestCase public void testCreateAmqpPort() { + createAmqpPortTestImpl(false,false,false); + } + + public void testCreateAmqpPortUsingSslFailsWithoutKeyStore() + { + when(_broker.getKeyStores()).thenReturn(new ArrayList<KeyStore>()); + try + { + createAmqpPortTestImpl(true,false,false); + fail("expected exception due to lack of SSL keystore"); + } + catch(IllegalConfigurationException e) + { + //expected + } + } + + public void testCreateAmqpPortUsingSsslSucceedsWithKeyStore() + { + when(_broker.getKeyStores()).thenReturn(Collections.singleton(_keyStore)); + + createAmqpPortTestImpl(true,false,false); + } + + public void testCreateAmqpPortNeedingClientAuthFailsWithoutTrustStore() + { + when(_broker.getKeyStores()).thenReturn(Collections.singleton(_keyStore)); + when(_broker.getTrustStores()).thenReturn(new ArrayList<TrustStore>()); + try + { + createAmqpPortTestImpl(true,true,false); + fail("expected exception due to lack of SSL truststore"); + } + catch(IllegalConfigurationException e) + { + //expected + } + } + + public void testCreateAmqpPortNeedingClientAuthSucceedsWithTrustStore() + { + when(_broker.getKeyStores()).thenReturn(Collections.singleton(_keyStore)); + when(_broker.getTrustStores()).thenReturn(Collections.singleton(_trustStore)); + + createAmqpPortTestImpl(true,true,false); + } + + public void testCreateAmqpPortWantingClientAuthFailsWithoutTrustStore() + { + when(_broker.getKeyStores()).thenReturn(Collections.singleton(_keyStore)); + when(_broker.getTrustStores()).thenReturn(new ArrayList<TrustStore>()); + try + { + createAmqpPortTestImpl(true,false,true); + fail("expected exception due to lack of SSL truststore"); + } + catch(IllegalConfigurationException e) + { + //expected + } + } + + public void testCreateAmqpPortWantingClientAuthSucceedsWithTrustStore() + { + when(_broker.getKeyStores()).thenReturn(Collections.singleton(_keyStore)); + when(_broker.getTrustStores()).thenReturn(Collections.singleton(_trustStore)); + + createAmqpPortTestImpl(true,false,true); + } + + public void createAmqpPortTestImpl(boolean useSslTransport, boolean needClientAuth, boolean wantClientAuth) + { Set<Protocol> amqp010ProtocolSet = Collections.singleton(Protocol.AMQP_0_10); Set<String> amqp010StringSet = Collections.singleton(Protocol.AMQP_0_10.name()); _attributes.put(Port.PROTOCOLS, amqp010StringSet); + if(useSslTransport) + { + _attributes.put(Port.TRANSPORTS, _sslStringSet); + } + + if(needClientAuth) + { + _attributes.put(Port.NEED_CLIENT_AUTH, "true"); + } + + if(wantClientAuth) + { + _attributes.put(Port.WANT_CLIENT_AUTH, "true"); + } + Port port = _portFactory.createPort(_portId, _broker, _attributes); assertNotNull(port); assertTrue(port instanceof AmqpPortAdapter); assertEquals(_portId, port.getId()); assertEquals(_portNumber, port.getPort()); - assertEquals(_tcpTransportSet, port.getTransports()); + if(useSslTransport) + { + assertEquals(_sslTransportSet, port.getTransports()); + } + else + { + assertEquals(_tcpTransportSet, port.getTransports()); + } assertEquals(amqp010ProtocolSet, port.getProtocols()); assertEquals("Unexpected send buffer size", 2, port.getAttribute(Port.SEND_BUFFER_SIZE)); assertEquals("Unexpected receive buffer size", 1, port.getAttribute(Port.RECEIVE_BUFFER_SIZE)); - assertEquals("Unexpected need client auth", true, port.getAttribute(Port.NEED_CLIENT_AUTH)); - assertEquals("Unexpected want client auth", true, port.getAttribute(Port.WANT_CLIENT_AUTH)); + assertEquals("Unexpected need client auth", needClientAuth, port.getAttribute(Port.NEED_CLIENT_AUTH)); + assertEquals("Unexpected want client auth", wantClientAuth, port.getAttribute(Port.WANT_CLIENT_AUTH)); assertEquals("Unexpected tcp no delay", true, port.getAttribute(Port.TCP_NO_DELAY)); assertEquals("Unexpected binding", "127.0.0.1", port.getAttribute(Port.BINDING_ADDRESS)); } diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/Asserts.java b/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/Asserts.java index 144e64f0bf..e20db6a6ac 100644 --- a/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/Asserts.java +++ b/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/Asserts.java @@ -181,12 +181,16 @@ public class Asserts public static void assertPortAttributes(Map<String, Object> port) { + assertPortAttributes(port, State.ACTIVE); + } + public static void assertPortAttributes(Map<String, Object> port, State state) + { assertNotNull("Unexpected value of attribute " + Port.ID, port.get(Port.ID)); assertEquals("Unexpected value of attribute " + Port.DURABLE, Boolean.FALSE, port.get(Port.DURABLE)); assertEquals("Unexpected value of attribute " + Port.LIFETIME_POLICY, LifetimePolicy.PERMANENT.name(), port.get(Broker.LIFETIME_POLICY)); - assertEquals("Unexpected value of attribute " + Port.STATE, State.ACTIVE.name(), port.get(Port.STATE)); + assertEquals("Unexpected value of attribute " + Port.STATE, state.name(), port.get(Port.STATE)); assertEquals("Unexpected value of attribute " + Port.TIME_TO_LIVE, 0, port.get(Port.TIME_TO_LIVE)); @SuppressWarnings("unchecked") diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/PortRestTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/PortRestTest.java index 9302ac88de..f8a7a9855f 100644 --- a/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/PortRestTest.java +++ b/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/PortRestTest.java @@ -30,6 +30,7 @@ import java.util.Map; import org.apache.qpid.server.model.AuthenticationProvider; import org.apache.qpid.server.model.Port; import org.apache.qpid.server.model.Protocol; +import org.apache.qpid.server.model.State; import org.apache.qpid.server.plugin.AuthenticationManagerFactory; import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManagerFactory; import org.apache.qpid.test.utils.TestBrokerConfiguration; @@ -107,7 +108,7 @@ public class PortRestTest extends QpidRestTestCase assertNotNull("Port details cannot be null", portDetails); assertEquals("Unexpected number of ports with name " + portName, 1, portDetails.size()); Map<String, Object> port = portDetails.get(0); - Asserts.assertPortAttributes(port); + Asserts.assertPortAttributes(port, State.QUIESCED); // make sure that port is there after broker restart restartBroker(); @@ -115,6 +116,8 @@ public class PortRestTest extends QpidRestTestCase portDetails = getRestTestHelper().getJsonAsList("/rest/port/" + portName); assertNotNull("Port details cannot be null", portDetails); assertEquals("Unexpected number of ports with name " + portName, 1, portDetails.size()); + port = portDetails.get(0); + Asserts.assertPortAttributes(port, State.ACTIVE); // try to add a second RMI port attributes = new HashMap<String, Object>(); |