diff options
| author | Robert Godfrey <rgodfrey@apache.org> | 2014-10-17 12:35:35 +0000 |
|---|---|---|
| committer | Robert Godfrey <rgodfrey@apache.org> | 2014-10-17 12:35:35 +0000 |
| commit | ba126ca5218e76bd38be239aed9200cb33c66c99 (patch) | |
| tree | 3bd255f3a995f812b01f9430e593b42ea40196cf /qpid/java | |
| parent | 2e62b717d3ca83f08010d86f4b7fb60615ae58a2 (diff) | |
| download | qpid-python-ba126ca5218e76bd38be239aed9200cb33c66c99.tar.gz | |
QPID-6161 : [Java Broker] add virtual host aliases
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1632553 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java')
42 files changed, 1207 insertions, 274 deletions
diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/FrameHandler.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/FrameHandler.java index bc16ba14e0..3e9dca683e 100644 --- a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/FrameHandler.java +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/FrameHandler.java @@ -20,7 +20,9 @@ */ package org.apache.qpid.amqp_1_0.framing; -import org.apache.qpid.amqp_1_0.codec.BinaryWriter; +import java.nio.ByteBuffer; +import java.util.Formatter; + import org.apache.qpid.amqp_1_0.codec.ProtocolHandler; import org.apache.qpid.amqp_1_0.codec.ValueHandler; import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint; @@ -30,9 +32,6 @@ import org.apache.qpid.amqp_1_0.type.transport.ConnectionError; import org.apache.qpid.amqp_1_0.type.transport.Error; import org.apache.qpid.amqp_1_0.type.transport.Transfer; -import java.nio.ByteBuffer; -import java.util.Formatter; - public class FrameHandler implements ProtocolHandler { private ConnectionEndpoint _connection; @@ -122,7 +121,7 @@ public class FrameHandler implements ProtocolHandler if(size < 8) { - frameParsingError = createFramingError("specified frame size %d smaller than minimum frame header size %d", _size, 8); + frameParsingError = createFramingError("specified frame size %d smaller than minimum frame header size %d", size, 8); state = State.ERROR; break; } diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListener.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListener.java index 9d8df844c9..21715f7406 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListener.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListener.java @@ -20,6 +20,8 @@ */ package org.apache.qpid.server.configuration.store; +import java.util.Collection; + import org.apache.qpid.server.model.ConfigurationChangeListener; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.State; @@ -47,13 +49,24 @@ public class StoreConfigurationChangeListener implements ConfigurationChangeList } @Override - public void childAdded(ConfiguredObject object, ConfiguredObject child) + public void childAdded(ConfiguredObject<?> object, ConfiguredObject<?> child) { // exclude VirtualHostNode children from storing in broker store if (!(object instanceof VirtualHostNode)) { child.addChangeListener(this); _store.update(true,child.asObjectRecord()); + + Class<? extends ConfiguredObject> categoryClass = child.getCategoryClass(); + Collection<Class<? extends ConfiguredObject>> childTypes = child.getModel().getChildTypes(categoryClass); + + for(Class<? extends ConfiguredObject> childClass : childTypes) + { + for (ConfiguredObject<?> grandchild : child.getChildren(childClass)) + { + childAdded(child, grandchild); + } + } } } diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java index b146854c7c..4edfbe0331 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java @@ -1361,6 +1361,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im _desiredState = State.DELETED; } setDesiredState(State.DELETED); + } public final void start() { setDesiredState(State.ACTIVE); } 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 02c9ccf8e1..3dfc272053 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 @@ -44,7 +44,7 @@ public final class BrokerModel extends Model * 2.0 Introduce VirtualHostNode as a child of a Broker instead of VirtualHost */ public static final int MODEL_MAJOR_VERSION = 2; - public static final int MODEL_MINOR_VERSION = 0; + public static final int MODEL_MINOR_VERSION = 1; 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 = @@ -81,7 +81,6 @@ public final class BrokerModel extends Model addRelationship(VirtualHost.class, Exchange.class); addRelationship(VirtualHost.class, Queue.class); addRelationship(VirtualHost.class, Connection.class); - addRelationship(VirtualHost.class, VirtualHostAlias.class); addRelationship(Port.class, VirtualHostAlias.class); diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/DefaultVirtualHostAlias.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/DefaultVirtualHostAlias.java new file mode 100644 index 0000000000..5265cf462c --- /dev/null +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/DefaultVirtualHostAlias.java @@ -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. + * + */ +package org.apache.qpid.server.model; + +@ManagedObject( category = false, type = DefaultVirtualHostAlias.TYPE_NAME) +public interface DefaultVirtualHostAlias<X extends VirtualHostAlias<X>> extends VirtualHostAlias<X> +{ + + String TYPE_NAME = "defaultAlias"; + + @ManagedAttribute( defaultValue = "500" ) + int getPriority(); +} diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/FixedVirtualHostNodeAlias.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/FixedVirtualHostNodeAlias.java new file mode 100644 index 0000000000..6b41a84d0d --- /dev/null +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/FixedVirtualHostNodeAlias.java @@ -0,0 +1,29 @@ +/* + * + * 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; + +public interface FixedVirtualHostNodeAlias<X extends FixedVirtualHostNodeAlias<X>> extends VirtualHostAlias<X> +{ + String VIRTUAL_HOST_NODE = "virtualHostNode"; + + @ManagedAttribute + VirtualHostNode<?> getVirtualHostNode(); +} diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/HostNameAlias.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/HostNameAlias.java new file mode 100644 index 0000000000..1206c0e126 --- /dev/null +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/HostNameAlias.java @@ -0,0 +1,33 @@ +/* + * + * 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; + +@ManagedObject( category = false, type = HostNameAlias.TYPE_NAME) +public interface HostNameAlias<X extends HostNameAlias<X>> extends FixedVirtualHostNodeAlias<X> +{ + + String TYPE_NAME = "hostnameAlias"; + + @ManagedAttribute( defaultValue = "750" ) + int getPriority(); + + +} diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/PatternMatchingAlias.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/PatternMatchingAlias.java new file mode 100644 index 0000000000..d602858628 --- /dev/null +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/PatternMatchingAlias.java @@ -0,0 +1,36 @@ +/* + * + * 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; + +@ManagedObject( category = false, type = PatternMatchingAlias.TYPE_NAME) +public interface PatternMatchingAlias<X extends PatternMatchingAlias<X>> extends FixedVirtualHostNodeAlias<X> +{ + + String TYPE_NAME = "patternMatchingAlias"; + + String PATTERN = "pattern"; + + @ManagedAttribute( defaultValue = "200" ) + int getPriority(); + + @ManagedAttribute( mandatory = true) + public String getPattern(); +} 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 d8b81a25b5..24528b9a4e 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,12 +60,8 @@ public interface Port<X extends Port<X>> extends ConfiguredObject<X> @ManagedAttribute Collection<TrustStore> getTrustStores(); - //children - Collection<VirtualHostAlias> getVirtualHostBindings(); Collection<Connection> getConnections(); void start(); - boolean isLocalMachine(final String host); - } diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHostAlias.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHostAlias.java index 4af5fbfde5..0cd4773d4b 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHostAlias.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHostAlias.java @@ -20,18 +20,17 @@ */ package org.apache.qpid.server.model; -import java.util.Collection; - -@ManagedObject +@ManagedObject( creatable = false ) public interface VirtualHostAlias<X extends VirtualHostAlias<X>> extends ConfiguredObject<X> { + String PRIORITY = "priority"; + // parents Port getPort(); - VirtualHost getVirtualHost(); - - // children - Collection<AuthenticationMethod> getAuthenticationMethods(); + @ManagedAttribute( defaultValue = "100" ) + int getPriority(); + VirtualHostNode getVirtualHostNode(String name); } diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHostNameAlias.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHostNameAlias.java new file mode 100644 index 0000000000..2d114f21a2 --- /dev/null +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHostNameAlias.java @@ -0,0 +1,27 @@ +/* + * + * 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; + +@ManagedObject( category = false, type = VirtualHostNameAlias.TYPE_NAME) +public interface VirtualHostNameAlias<X extends VirtualHostNameAlias<X>> extends VirtualHostAlias<X> +{ + String TYPE_NAME = "nameAlias"; +} diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAliasAdapter.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAliasAdapter.java deleted file mode 100644 index 0ea9079ebb..0000000000 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAliasAdapter.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.model.adapter; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -import org.apache.qpid.server.model.AbstractConfiguredObject; -import org.apache.qpid.server.model.AuthenticationMethod; -import org.apache.qpid.server.model.ConfiguredObject; -import org.apache.qpid.server.model.Port; -import org.apache.qpid.server.model.State; -import org.apache.qpid.server.model.VirtualHost; -import org.apache.qpid.server.model.VirtualHostAlias; - -public class VirtualHostAliasAdapter extends AbstractConfiguredObject<VirtualHostAliasAdapter> implements VirtualHostAlias<VirtualHostAliasAdapter> -{ - private VirtualHost _vhost; - private Port _port; - - public VirtualHostAliasAdapter(VirtualHost virtualHost, Port port) - { - super(parentsMap(virtualHost,port), createAttributes(virtualHost, port)); - _vhost = virtualHost; - _port = port; - setState(State.ACTIVE); - } - - private static Map<String, Object> createAttributes(final VirtualHost virtualHost, final Port port) - { - final Map<String, Object> attributes = new HashMap<String, Object>(); - attributes.put(ID, UUID.randomUUID()); - attributes.put(NAME, virtualHost.getName()); - attributes.put(DURABLE, false); - return attributes; - } - - @Override - public Port getPort() - { - return _port; - } - - @Override - public VirtualHost getVirtualHost() - { - return _vhost; - } - - @Override - public Collection<AuthenticationMethod> getAuthenticationMethods() - { - return Collections.emptySet(); // TODO - Implement - } - - @Override - public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz) - { - return Collections.emptySet(); - } - - -} 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 e2e7eff322..6d8e65cd17 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 @@ -21,23 +21,12 @@ package org.apache.qpid.server.model.port; -import java.net.InetAddress; -import java.net.InterfaceAddress; -import java.net.NetworkInterface; -import java.net.SocketException; -import java.net.UnknownHostException; import java.security.AccessControlException; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.CopyOnWriteArraySet; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; import org.apache.log4j.Logger; @@ -54,69 +43,12 @@ import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.StateTransition; import org.apache.qpid.server.model.Transport; import org.apache.qpid.server.model.TrustStore; -import org.apache.qpid.server.model.VirtualHost; -import org.apache.qpid.server.model.VirtualHostAlias; -import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.server.security.access.Operation; abstract public class AbstractPort<X extends AbstractPort<X>> extends AbstractConfiguredObject<X> implements Port<X> { private static final Logger LOGGER = Logger.getLogger(AbstractPort.class); - private static final Set<InetAddress> LOCAL_ADDRESSES = new CopyOnWriteArraySet<>(); - private static final Set<String> LOCAL_ADDRESS_NAMES = new CopyOnWriteArraySet<>(); - private static final Lock ADDRESS_LOCK = new ReentrantLock(); - private static final AtomicBoolean ADDRESSES_COMPUTED = new AtomicBoolean(); - - static - { - Thread thread = new Thread(new Runnable() - { - public void run() - { - Lock lock = ADDRESS_LOCK; - - lock.lock(); - try - { - for (NetworkInterface networkInterface : Collections.list(NetworkInterface.getNetworkInterfaces())) - { - for (InterfaceAddress inetAddress : networkInterface.getInterfaceAddresses()) - { - InetAddress address = inetAddress.getAddress(); - LOCAL_ADDRESSES.add(address); - String hostAddress = address.getHostAddress(); - if (hostAddress != null) - { - LOCAL_ADDRESS_NAMES.add(hostAddress); - } - String hostName = address.getHostName(); - if (hostName != null) - { - LOCAL_ADDRESS_NAMES.add(hostName); - } - String canonicalHostName = address.getCanonicalHostName(); - if (canonicalHostName != null) - { - LOCAL_ADDRESS_NAMES.add(canonicalHostName); - } - } - } - } - catch (SocketException e) - { - // ignore - } - finally - { - ADDRESSES_COMPUTED.set(true); - lock.unlock(); - } - } - }, "Network Address Resolver"); - thread.start(); - } - private final Broker<?> _broker; @ManagedAttributeField @@ -271,27 +203,6 @@ abstract public class AbstractPort<X extends AbstractPort<X>> extends AbstractCo } @Override - public Collection<VirtualHostAlias> getVirtualHostBindings() - { - List<VirtualHostAlias> aliases = new ArrayList<VirtualHostAlias>(); - for(VirtualHostNode<?> vhn : _broker.getVirtualHostNodes()) - { - VirtualHost<?, ?, ?> vh = vhn.getVirtualHost(); - if (vh != null) - { - for(VirtualHostAlias<?> alias : vh.getAliases()) - { - if(alias.getPort().equals(this)) - { - aliases.add(alias); - } - } - } - } - return Collections.unmodifiableCollection(aliases); - } - - @Override public Collection<Connection> getConnections() { return null; @@ -306,7 +217,7 @@ abstract public class AbstractPort<X extends AbstractPort<X>> extends AbstractCo } else { - return Collections.emptySet(); + return super.getChildren(clazz); } } @@ -412,38 +323,4 @@ abstract public class AbstractPort<X extends AbstractPort<X>> extends AbstractCo } } - public boolean isLocalMachine(final String host) - { - while(!ADDRESSES_COMPUTED.get()) - { - Lock lock = ADDRESS_LOCK; - lock.lock(); - lock.unlock(); - } - - boolean isNetworkAddress = true; - if (!LOCAL_ADDRESS_NAMES.contains(host)) - { - try - { - InetAddress inetAddress = InetAddress.getByName(host); - if (!LOCAL_ADDRESSES.contains(inetAddress)) - { - isNetworkAddress = false; - } - else - { - LOCAL_ADDRESS_NAMES.add(host); - } - } - catch (UnknownHostException e) - { - // ignore - isNetworkAddress = false; - } - } - return isNetworkAddress; - - } - } diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPort.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPort.java index a75e74f304..ade9055b5a 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPort.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPort.java @@ -20,6 +20,7 @@ */ package org.apache.qpid.server.model.port; +import java.util.Map; import java.util.Set; import org.apache.qpid.server.model.AuthenticationProvider; @@ -28,6 +29,7 @@ import org.apache.qpid.server.model.ManagedContextDefault; import org.apache.qpid.server.model.ManagedObject; import org.apache.qpid.server.model.Protocol; import org.apache.qpid.server.model.Transport; +import org.apache.qpid.server.model.VirtualHostAlias; import org.apache.qpid.server.virtualhost.VirtualHostImpl; @ManagedObject( category = false, type = "AMQP") @@ -79,4 +81,5 @@ public interface AmqpPort<X extends AmqpPort<X>> extends ClientAuthCapablePort<X VirtualHostImpl getVirtualHost(String name); + VirtualHostAlias createVirtualHostAlias(Map<String, Object> attributes); } diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java index 02bd8d994d..fd8c402344 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java @@ -25,9 +25,12 @@ import java.security.GeneralSecurityException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.TreeSet; import javax.net.ssl.KeyManager; import javax.net.ssl.SSLContext; @@ -40,6 +43,8 @@ import org.apache.qpid.server.configuration.BrokerProperties; import org.apache.qpid.server.configuration.IllegalConfigurationException; import org.apache.qpid.server.logging.messages.BrokerMessages; import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.DefaultVirtualHostAlias; +import org.apache.qpid.server.model.HostNameAlias; import org.apache.qpid.server.model.KeyStore; import org.apache.qpid.server.model.ManagedAttributeField; import org.apache.qpid.server.model.ManagedObjectFactoryConstructor; @@ -47,6 +52,9 @@ import org.apache.qpid.server.model.Protocol; import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.Transport; import org.apache.qpid.server.model.TrustStore; +import org.apache.qpid.server.model.VirtualHostAlias; +import org.apache.qpid.server.model.VirtualHostNameAlias; +import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.server.plugin.ProtocolEngineCreator; import org.apache.qpid.server.plugin.QpidServiceLoader; import org.apache.qpid.server.plugin.TransportProviderFactory; @@ -62,6 +70,29 @@ public class AmqpPortImpl extends AbstractClientAuthCapablePortWithAuthProvider< public static final String DEFAULT_BINDING_ADDRESS = "*"; + + private static final Comparator<VirtualHostAlias> VIRTUAL_HOST_ALIAS_COMPARATOR = new Comparator<VirtualHostAlias>() + { + @Override + public int compare(final VirtualHostAlias left, final VirtualHostAlias right) + { + int comparison = left.getPriority() - right.getPriority(); + if (comparison == 0) + { + long createCompare = left.getCreatedTime() - right.getCreatedTime(); + if (createCompare == 0) + { + comparison = left.getName().compareTo(right.getName()); + } + else + { + comparison = createCompare < 0l ? -1 : 1; + } + } + return comparison; + } + }; + @ManagedAttributeField private boolean _tcpNoDelay; @@ -110,15 +141,47 @@ public class AmqpPortImpl extends AbstractClientAuthCapablePortWithAuthProvider< } @Override + protected void onCreate() + { + super.onCreate(); + + Map<String, Object> attributes = new HashMap<>(); + attributes.put(VirtualHostAlias.NAME, "nameAlias"); + attributes.put(VirtualHostAlias.TYPE, VirtualHostNameAlias.TYPE_NAME); + attributes.put(VirtualHostAlias.DURABLE, true); + createVirtualHostAlias(attributes); + + attributes = new HashMap<>(); + attributes.put(VirtualHostAlias.NAME, "defaultAlias"); + attributes.put(VirtualHostAlias.TYPE, DefaultVirtualHostAlias.TYPE_NAME); + attributes.put(VirtualHostAlias.DURABLE, true); + createVirtualHostAlias(attributes); + + + attributes = new HashMap<>(); + attributes.put(VirtualHostAlias.NAME, "hostnameAlias"); + attributes.put(VirtualHostAlias.TYPE, HostNameAlias.TYPE_NAME); + attributes.put(VirtualHostAlias.DURABLE, true); + createVirtualHostAlias(attributes); + + } + + @Override public VirtualHostImpl getVirtualHost(String name) { - // TODO - aliases - if(name == null || name.trim().length() == 0) + Collection<VirtualHostAlias> aliases = new TreeSet<>(VIRTUAL_HOST_ALIAS_COMPARATOR); + + aliases.addAll(getChildren(VirtualHostAlias.class)); + + for(VirtualHostAlias alias : aliases) { - name = _broker.getDefaultVirtualHost(); + VirtualHostNode vhn = alias.getVirtualHostNode(name); + if (vhn != null) + { + return (VirtualHostImpl) vhn.getVirtualHost(); + } } - - return (VirtualHostImpl) _broker.findVirtualHostByName(name); + return null; } @Override @@ -155,7 +218,6 @@ public class AmqpPortImpl extends AbstractClientAuthCapablePortWithAuthProvider< { sslContext = createSslContext(); } - Protocol defaultSupportedProtocolReply = getDefaultAmqpSupportedReply(); _transport = transportProvider.createTransport(transportSet, @@ -188,6 +250,20 @@ public class AmqpPortImpl extends AbstractClientAuthCapablePortWithAuthProvider< } @Override + public VirtualHostAlias createVirtualHostAlias(Map<String, Object> attributes) + { + VirtualHostAlias child = addVirtualHostAlias(attributes); + childAdded(child); + return child; + } + + private VirtualHostAlias addVirtualHostAlias(Map<String,Object> attributes) + { + return getObjectFactory().create(VirtualHostAlias.class, attributes, this); + } + + + @Override public void validateOnCreate() { super.validateOnCreate(); 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 be7db10773..157229b30b 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 @@ -19,6 +19,7 @@ * */ package org.apache.qpid.server.store; + import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -26,12 +27,15 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.UUID; import org.apache.qpid.server.configuration.IllegalConfigurationException; import org.apache.qpid.server.configuration.store.StoreConfigurationChangeListener; import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.Port; import org.apache.qpid.server.model.SystemConfig; +import org.apache.qpid.server.model.VirtualHostAlias; import org.apache.qpid.server.util.Action; public class BrokerStoreUpgraderAndRecoverer @@ -49,6 +53,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()); } private void register(StoreUpgraderPhase upgrader) @@ -207,6 +212,64 @@ public class BrokerStoreUpgraderAndRecoverer } } + private class Upgrader_2_0_to_2_1 extends StoreUpgraderPhase + { + public Upgrader_2_0_to_2_1() + { + super("modelVersion", "2.0", "2.1"); + } + + @Override + public void configuredObject(ConfiguredObjectRecord record) + { + if(record.getType().equals("Port") && isAmqpPort(record.getAttributes())) + { + createAliasRecord(record, "nameAlias", "nameAlias"); + createAliasRecord(record, "defaultAlias", "defaultAlias"); + createAliasRecord(record, "hostnameAlias", "hostnameAlias"); + + } + else if (record.getType().equals("Broker")) + { + record = upgradeRootRecord(record); + } + + getNextUpgrader().configuredObject(record); + } + + private boolean isAmqpPort(final Map<String, Object> attributes) + { + Object type = attributes.get(ConfiguredObject.TYPE); + Object protocols = attributes.get(Port.PROTOCOLS); + String protocolString = protocols == null ? null : protocols.toString(); + return "AMQP".equals(type) + || protocolString == null + || !protocolString.matches(".*\\w.*") + || protocolString.contains("AMQP"); + + } + + private void createAliasRecord(ConfiguredObjectRecord parent, String name, String type) + { + Map<String,Object> attributes = new HashMap<>(); + attributes.put(VirtualHostAlias.NAME, name); + attributes.put(VirtualHostAlias.TYPE, type); + + final ConfiguredObjectRecord record = new ConfiguredObjectRecordImpl(UUID.randomUUID(), + "VirtualHostAlias", + attributes, + Collections.singletonMap("Port", parent.getId())); + getUpdateMap().put(record.getId(), record); + getNextUpgrader().configuredObject(record); + } + + @Override + public void complete() + { + getNextUpgrader().complete(); + } + + } private static class VirtualHostEntryUpgrader { diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/ConfiguredObjectRecordConverter.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/ConfiguredObjectRecordConverter.java index 5f1c0b4b7f..8d8b62ffdd 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/ConfiguredObjectRecordConverter.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/ConfiguredObjectRecordConverter.java @@ -98,7 +98,8 @@ public class ConfiguredObjectRecordConverter for(Class<? extends ConfiguredObject> childClass : childClasses) { final String childType = childClass.getSimpleName(); - String attrName = childType.toLowerCase() + "s"; + String singularName = childType.toLowerCase(); + String attrName = singularName + (singularName.endsWith("s") ? "es" : "s"); Object children = data.remove(attrName); if(children != null) { diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/ConfiguredObjectRecordImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/ConfiguredObjectRecordImpl.java index 2d1b08aa50..8044afafdc 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/ConfiguredObjectRecordImpl.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/ConfiguredObjectRecordImpl.java @@ -79,7 +79,7 @@ public class ConfiguredObjectRecordImpl implements ConfiguredObjectRecord @Override public String toString() { - return "ConfiguredObjectRecord [id=" + _id + ", type=" + _type + ", attributes=" + _attributes + "]"; + return "ConfiguredObjectRecord [id=" + _id + ", type=" + _type + ", attributes=" + _attributes + ", parents=" + _parents + "]"; } @Override diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/JsonFileConfigStore.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/JsonFileConfigStore.java index 55de8f6852..b3e9d39a55 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/JsonFileConfigStore.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/JsonFileConfigStore.java @@ -445,7 +445,8 @@ public class JsonFileConfigStore implements DurableConfigurationStore // only add if this is the "first" parent if(_parent.getModel().getParentTypes(childClass).iterator().next() == type) { - String attrName = childClass.getSimpleName().toLowerCase() + "s"; + String singularName = childClass.getSimpleName().toLowerCase(); + String attrName = singularName + (singularName.endsWith("s") ? "es" : "s"); List<UUID> childIds = _idsByType.get(childClass.getSimpleName()); if(childIds != null) { 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 5565ea6175..f1372882a8 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 @@ -61,6 +61,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()); Map<String, UUID> defaultExchangeIds = new HashMap<String, UUID>(); for (String exchangeName : DEFAULT_EXCHANGES.keySet()) @@ -400,6 +401,32 @@ public class VirtualHostStoreUpgraderAndRecoverer } + private class Upgrader_2_0_to_2_1 extends StoreUpgraderPhase + { + public Upgrader_2_0_to_2_1() + { + super("modelVersion", "2.0", "2.1"); + } + + @Override + public void configuredObject(ConfiguredObjectRecord record) + { + + if("VirtualHost".equals(record.getType())) + { + record = upgradeRootRecord(record); + } + getNextUpgrader().configuredObject(record); + } + + @Override + public void complete() + { + getNextUpgrader().complete(); + } + + } + public void perform(DurableConfigurationStore durableConfigurationStore) { String virtualHostCategory = VirtualHost.class.getSimpleName(); 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 733382a375..b1f6b84b72 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 @@ -62,7 +62,7 @@ class TCPandSSLTransport implements AcceptingTransport @Override public void start() { - String bindingAddress = (String) _port.getAttribute(Port.BINDING_ADDRESS); + String bindingAddress = ((AmqpPort<?>)_port).getBindingAddress(); if (WILDCARD_ADDRESS.equals(bindingAddress)) { bindingAddress = null; diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java index 48077ba503..56e28bd870 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java @@ -60,7 +60,6 @@ import org.apache.qpid.server.message.MessageSource; import org.apache.qpid.server.message.ServerMessage; import org.apache.qpid.server.model.*; import org.apache.qpid.server.model.adapter.ConnectionAdapter; -import org.apache.qpid.server.model.adapter.VirtualHostAliasAdapter; import org.apache.qpid.server.plugin.QpidServiceLoader; import org.apache.qpid.server.plugin.SystemNodeCreator; import org.apache.qpid.server.protocol.AMQConnectionModel; @@ -284,18 +283,6 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte _messageStore.addEventListener(this, Event.PERSISTENT_MESSAGE_SIZE_OVERFULL); _messageStore.addEventListener(this, Event.PERSISTENT_MESSAGE_SIZE_UNDERFULL); - - synchronized(_aliases) - { - for(Port port :_broker.getPorts()) - { - if (Protocol.hasAmqpProtocol(port.getProtocols())) - { - _aliases.add(new VirtualHostAliasAdapter(this, port)); - } - } - } - addChangeListener(new StoreUpdatingChangeListener()); } diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostalias/AbstractFixedVirtualHostNodeAlias.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostalias/AbstractFixedVirtualHostNodeAlias.java new file mode 100644 index 0000000000..2ec2c4390e --- /dev/null +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostalias/AbstractFixedVirtualHostNodeAlias.java @@ -0,0 +1,56 @@ +/* + * + * 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.virtualhostalias; + +import java.util.Map; + +import org.apache.qpid.server.model.FixedVirtualHostNodeAlias; +import org.apache.qpid.server.model.ManagedAttributeField; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.VirtualHostNode; + +abstract class AbstractFixedVirtualHostNodeAlias<X extends AbstractFixedVirtualHostNodeAlias<X>> + extends AbstractVirtualHostAlias<X> implements FixedVirtualHostNodeAlias<X> +{ + @ManagedAttributeField + private VirtualHostNode _virtualHostNode; + + protected AbstractFixedVirtualHostNodeAlias(final Map<String, Object> attributes, + final Port port) + { + super(attributes, port); + } + + + @Override + public VirtualHostNode<?> getVirtualHostNode() + { + return _virtualHostNode; + } + + @Override + public VirtualHostNode<?> getVirtualHostNode(final String name) + { + return matches(name) ? getVirtualHostNode() : null; + } + + protected abstract boolean matches(final String name); +} diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostalias/AbstractVirtualHostAlias.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostalias/AbstractVirtualHostAlias.java new file mode 100644 index 0000000000..bf705e5f96 --- /dev/null +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostalias/AbstractVirtualHostAlias.java @@ -0,0 +1,62 @@ +/* + * + * 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.virtualhostalias; + +import java.util.Map; + +import org.apache.qpid.server.model.AbstractConfiguredObject; +import org.apache.qpid.server.model.ManagedAttributeField; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.VirtualHostAlias; + +abstract class AbstractVirtualHostAlias<X extends AbstractVirtualHostAlias<X>> + extends AbstractConfiguredObject<X> implements VirtualHostAlias<X> +{ + + @ManagedAttributeField + private int _priority; + + protected AbstractVirtualHostAlias(Map<String, Object> attributes, Port port) + { + super(parentsMap(port), attributes); + } + + @Override + public Port<?> getPort() + { + return getParent(Port.class); + } + + @Override + public int getPriority() + { + return _priority; + } + + @Override + public State getState() + { + return State.ACTIVE; + } + +} diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostalias/DefaultVirtualHostAliasImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostalias/DefaultVirtualHostAliasImpl.java new file mode 100644 index 0000000000..cab9794375 --- /dev/null +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostalias/DefaultVirtualHostAliasImpl.java @@ -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. + * + */ +package org.apache.qpid.server.virtualhostalias; + +import java.util.Map; + +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.DefaultVirtualHostAlias; +import org.apache.qpid.server.model.ManagedObjectFactoryConstructor; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.VirtualHostNode; + +public final class DefaultVirtualHostAliasImpl + extends AbstractVirtualHostAlias<DefaultVirtualHostAliasImpl> + implements DefaultVirtualHostAlias<DefaultVirtualHostAliasImpl> +{ + + @ManagedObjectFactoryConstructor + protected DefaultVirtualHostAliasImpl(final Map<String, Object> attributes, final Port port) + { + super(attributes, port); + } + + @Override + public VirtualHostNode getVirtualHostNode(final String name) + { + if(name == null || name.trim().equals("")) + { + Broker<?> broker = getPort().getParent(Broker.class); + String defaultHostName = broker.getDefaultVirtualHost(); + for(VirtualHostNode<?> vhn : broker.getVirtualHostNodes()) + { + if(vhn.getName().equals(defaultHostName)) + { + return vhn; + } + } + + } + return null; + } + +} diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostalias/HostNameAliasImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostalias/HostNameAliasImpl.java new file mode 100644 index 0000000000..9abeac5f31 --- /dev/null +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostalias/HostNameAliasImpl.java @@ -0,0 +1,193 @@ +/* + * + * 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.virtualhostalias; + +import java.net.InetAddress; +import java.net.InterfaceAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.HostNameAlias; +import org.apache.qpid.server.model.ManagedObjectFactoryConstructor; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.VirtualHostNode; +import org.apache.qpid.server.model.port.AmqpPort; + +public class HostNameAliasImpl + extends AbstractFixedVirtualHostNodeAlias<HostNameAliasImpl> + implements HostNameAlias<HostNameAliasImpl> +{ + + private final Set<InetAddress> _localAddresses = new CopyOnWriteArraySet<>(); + private final Set<String> _localAddressNames = new CopyOnWriteArraySet<>(); + private final Lock _addressLock = new ReentrantLock(); + private final AtomicBoolean _addressesComputed = new AtomicBoolean(); + + + @ManagedObjectFactoryConstructor + protected HostNameAliasImpl(final Map<String, Object> attributes, final Port port) + { + super(attributes, port); + } + + protected void onOpen() + { + super.onOpen(); + Thread thread = new Thread(new NetworkAddressResolver(), "Network Address Resolver"); + thread.start(); + } + + + @Override + public VirtualHostNode<?> getVirtualHostNode(final String name) + { + VirtualHostNode<?> node = null; + if(matches(name)) + { + node = getVirtualHostNode(); + if(node == null) + { + Broker<?> broker = getPort().getParent(Broker.class); + String defaultHostName = broker.getDefaultVirtualHost(); + for (VirtualHostNode<?> vhn : broker.getVirtualHostNodes()) + { + if (vhn.getName().equals(defaultHostName)) + { + return vhn; + } + } + } + + } + return node; + } + + @Override + protected boolean matches(final String host) + { + while(!_addressesComputed.get()) + { + Lock lock = _addressLock; + lock.lock(); + lock.unlock(); + } + + boolean isNetworkAddress = true; + if (!_localAddressNames.contains(host)) + { + try + { + InetAddress inetAddress = InetAddress.getByName(host); + if (!_localAddresses.contains(inetAddress)) + { + isNetworkAddress = false; + } + else + { + _localAddressNames.add(host); + } + } + catch (UnknownHostException e) + { + // ignore + isNetworkAddress = false; + } + } + return isNetworkAddress; + + } + + private class NetworkAddressResolver implements Runnable + { + public void run() + { + _addressesComputed.set(false); + Lock lock = _addressLock; + + lock.lock(); + String bindingAddress = ((AmqpPort<?>)getPort()).getBindingAddress(); + try + { + Collection<InetAddress> inetAddresses; + if(bindingAddress == null || bindingAddress.trim().equals("") || bindingAddress.trim().equals("*")) + { + inetAddresses = getAllInetAddresses(); + } + else + { + inetAddresses = Collections.singleton(InetAddress.getByName(bindingAddress)); + } + for (InetAddress address : inetAddresses) + { + _localAddresses.add(address); + String hostAddress = address.getHostAddress(); + if (hostAddress != null) + { + _localAddressNames.add(hostAddress); + } + String hostName = address.getHostName(); + if (hostName != null) + { + _localAddressNames.add(hostName); + } + String canonicalHostName = address.getCanonicalHostName(); + if (canonicalHostName != null) + { + _localAddressNames.add(canonicalHostName); + } + } + } + catch (SocketException | UnknownHostException e) + { + // ignore + } + finally + { + _addressesComputed.set(true); + lock.unlock(); + } + } + + private Collection<InetAddress> getAllInetAddresses() throws SocketException + { + Set<InetAddress> addresses = new HashSet<>(); + for (NetworkInterface networkInterface : Collections.list(NetworkInterface.getNetworkInterfaces())) + { + for (InterfaceAddress inetAddress : networkInterface.getInterfaceAddresses()) + { + addresses.add(inetAddress.getAddress()); + } + } + return addresses; + } + } +} diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostalias/PatternMatchingAliasImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostalias/PatternMatchingAliasImpl.java new file mode 100644 index 0000000000..df47b1a94e --- /dev/null +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostalias/PatternMatchingAliasImpl.java @@ -0,0 +1,54 @@ +/* + * + * 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.virtualhostalias; + +import java.util.Map; + +import org.apache.qpid.server.model.ManagedAttributeField; +import org.apache.qpid.server.model.ManagedObjectFactoryConstructor; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.PatternMatchingAlias; + +public final class PatternMatchingAliasImpl + extends AbstractFixedVirtualHostNodeAlias<PatternMatchingAliasImpl> + implements PatternMatchingAlias<PatternMatchingAliasImpl> +{ + @ManagedAttributeField + private String _pattern; + + @ManagedObjectFactoryConstructor + protected PatternMatchingAliasImpl(final Map<String, Object> attributes, final Port port) + { + super(attributes, port); + } + + @Override + protected boolean matches(final String name) + { + return name == null ? "".matches(_pattern) : name.matches(_pattern); + } + + @Override + public String getPattern() + { + return _pattern; + } +} diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostalias/VirtualHostNameAliasImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostalias/VirtualHostNameAliasImpl.java new file mode 100644 index 0000000000..f55367a89d --- /dev/null +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostalias/VirtualHostNameAliasImpl.java @@ -0,0 +1,54 @@ +/* + * + * 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.virtualhostalias; + +import java.util.Map; + +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ManagedObjectFactoryConstructor; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.VirtualHostNameAlias; +import org.apache.qpid.server.model.VirtualHostNode; + +public final class VirtualHostNameAliasImpl + extends AbstractVirtualHostAlias<VirtualHostNameAliasImpl> + implements VirtualHostNameAlias<VirtualHostNameAliasImpl> +{ + @ManagedObjectFactoryConstructor + protected VirtualHostNameAliasImpl(final Map<String, Object> attributes, final Port port) + { + super(attributes, port); + } + + @Override + public VirtualHostNode getVirtualHostNode(final String name) + { + Broker<?> broker = getPort().getParent(Broker.class); + for(VirtualHostNode<?> vhn : broker.getVirtualHostNodes()) + { + if(vhn.getName().equals(name)) + { + return vhn; + } + } + return null; + } +} diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java index aea07e3ed3..f4c0576d79 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java @@ -107,6 +107,11 @@ public abstract class AbstractVirtualHostNode<X extends AbstractVirtualHostNode< return LifetimePolicy.PERMANENT; } + @Override + protected void onCreate() + { + super.onCreate(); + } @StateTransition( currentState = {State.UNINITIALIZED, State.STOPPED, State.ERRORED }, desiredState = State.ACTIVE ) protected void doActivate() 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 5ee820d9ac..012cdc9017 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.0", + "modelVersion": "2.1", "defaultVirtualHost" : "default", "authenticationproviders" : [ { "name" : "passwordFile", @@ -35,7 +35,18 @@ "ports" : [ { "name" : "AMQP", "port" : "${qpid.amqp_port}", - "authenticationProvider" : "passwordFile" + "authenticationProvider" : "passwordFile", + "secureOnlyMechanisms" : [ ], + "virtualhostaliases" : [ { + "name" : "nameAlias", + "type" : "nameAlias" + }, { + "name" : "defaultAlias", + "type" : "defaultAlias" + }, { + "name" : "hostnameAlias", + "type" : "hostnameAlias" + } ] }, { "name" : "HTTP", "port" : "${qpid.http_port}", diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListenerTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListenerTest.java index 6cfcf430b2..14ff640c57 100644 --- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListenerTest.java +++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListenerTest.java @@ -27,10 +27,12 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; +import java.util.Collections; import java.util.UUID; import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.Model; import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.VirtualHost; import org.apache.qpid.server.model.VirtualHostNode; @@ -69,6 +71,9 @@ public class StoreConfigurationChangeListenerTest extends QpidTestCase when(broker.getCategoryClass()).thenReturn(Broker.class); VirtualHost child = mock(VirtualHost.class); when(child.getCategoryClass()).thenReturn(VirtualHost.class); + Model model = mock(Model.class); + when(model.getChildTypes(any(Class.class))).thenReturn(Collections.<Class<? extends ConfiguredObject>>emptyList()); + when(child.getModel()).thenReturn(model); _listener.childAdded(broker, child); verify(_store).update(eq(true), any(ConfiguredObjectRecord.class)); } diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java index 8573ae3a42..0bee92a2e9 100644 --- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java +++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java @@ -28,6 +28,8 @@ import static org.mockito.Mockito.when; import java.net.SocketAddress; import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -110,17 +112,28 @@ public class BrokerTestHelper } public static VirtualHostImpl<?,?,?> createVirtualHost(Map<String, Object> attributes) - throws Exception { Broker<?> broker = createBrokerMock(); + return createVirtualHost(attributes, broker); + } + + public static VirtualHostImpl<?, ?, ?> createVirtualHost(final Map<String, Object> attributes, + final Broker<?> broker) + { ConfiguredObjectFactory objectFactory = broker.getObjectFactory(); VirtualHostNode virtualHostNode = mock(VirtualHostNode.class); + when(virtualHostNode.getName()).thenReturn((String) attributes.get(VirtualHostNode.NAME)); when(virtualHostNode.getTaskExecutor()).thenReturn(TASK_EXECUTOR); when(virtualHostNode.getParent(eq(Broker.class))).thenReturn(broker); + Collection<VirtualHostNode<?>> nodes = broker.getVirtualHostNodes(); + nodes = new ArrayList<>(nodes != null ? nodes : Collections.<VirtualHostNode<?>>emptyList()); + nodes.add(virtualHostNode); + when(broker.getVirtualHostNodes()).thenReturn(nodes); + DurableConfigurationStore dcs = mock(DurableConfigurationStore.class); when(virtualHostNode.getConfigurationStore()).thenReturn(dcs); when(virtualHostNode.getParent(eq(VirtualHostNode.class))).thenReturn(virtualHostNode); @@ -128,19 +141,26 @@ public class BrokerTestHelper when(virtualHostNode.getObjectFactory()).thenReturn(objectFactory); when(virtualHostNode.getCategoryClass()).thenReturn(VirtualHostNode.class); when(virtualHostNode.getTaskExecutor()).thenReturn(TASK_EXECUTOR); - AbstractVirtualHost host = (AbstractVirtualHost) objectFactory.create(VirtualHost.class, attributes, virtualHostNode ); + AbstractVirtualHost + host = (AbstractVirtualHost) objectFactory.create(VirtualHost.class, attributes, virtualHostNode ); host.start(); - + when(virtualHostNode.getVirtualHost()).thenReturn(host); return host; } + public static VirtualHostImpl<?,?,?> createVirtualHost(String name) throws Exception { + return createVirtualHost(name, createBrokerMock()); + } + + public static VirtualHostImpl<?,?,?> createVirtualHost(String name, Broker<?> broker) throws Exception + { Map<String,Object> attributes = new HashMap<String, Object>(); attributes.put(org.apache.qpid.server.model.VirtualHost.TYPE, TestMemoryVirtualHost.VIRTUAL_HOST_TYPE); attributes.put(org.apache.qpid.server.model.VirtualHost.NAME, name); - return createVirtualHost(attributes); + return createVirtualHost(attributes, broker); } public static AMQSessionModel<?,?> createSession(int channelId, AMQConnectionModel<?,?> connection) diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostalias/VirtualHostAliasTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostalias/VirtualHostAliasTest.java new file mode 100644 index 0000000000..1a7e2cdc0d --- /dev/null +++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostalias/VirtualHostAliasTest.java @@ -0,0 +1,206 @@ +/* + * + * 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.virtualhostalias; + +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObjectFactory; +import org.apache.qpid.server.model.PatternMatchingAlias; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.VirtualHostAlias; +import org.apache.qpid.server.model.VirtualHostNode; +import org.apache.qpid.server.model.port.AmqpPort; +import org.apache.qpid.server.util.BrokerTestHelper; +import org.apache.qpid.server.virtualhost.VirtualHostImpl; +import org.apache.qpid.test.utils.QpidTestCase; + +public class VirtualHostAliasTest extends QpidTestCase +{ + private Broker<?> _broker; + private Map<String, VirtualHost<?,?,?>> _vhosts; + private AmqpPort _port; + + @Override + public void setUp() throws Exception + { + super.setUp(); + _broker = BrokerTestHelper.createBrokerMock(); + + AuthenticationProvider dummyAuthProvider = mock(AuthenticationProvider.class); + when(dummyAuthProvider.getName()).thenReturn("dummy"); + when(dummyAuthProvider.getId()).thenReturn(UUID.randomUUID()); + when(_broker.getChildren(eq(AuthenticationProvider.class))).thenReturn(Collections.singleton(dummyAuthProvider)); + _vhosts = new HashMap<>(); + for(String name : new String[] { "red", "blue", "purple", "black" }) + { + _vhosts.put(name, BrokerTestHelper.createVirtualHost(name, _broker)); + } + ConfiguredObjectFactory objectFactory = _broker.getObjectFactory(); + when(_broker.getDefaultVirtualHost()).thenReturn("black"); + + final Map<String, Object> attributes = new HashMap<>(); + attributes.put(Port.NAME, getTestName()); + attributes.put(Port.PORT, findFreePort()); + attributes.put(Port.AUTHENTICATION_PROVIDER, "dummy"); + attributes.put(Port.TYPE, "AMQP"); + _port = (AmqpPort) objectFactory.create(Port.class, attributes, _broker ); + + } + + public void testDefaultAliases() + { + VirtualHostImpl vhost = _port.getVirtualHost("red"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("red"), vhost); + + vhost = _port.getVirtualHost("blue"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("blue"), vhost); + + vhost = _port.getVirtualHost("orange!"); + + assertNull(vhost); + + // test the default vhost resolution + vhost = _port.getVirtualHost(""); + + assertNotNull(vhost); + assertEquals(_vhosts.get("black"), vhost); + + + // 127.0.0.1 should always resolve and thus return the default vhost + vhost = _port.getVirtualHost("127.0.0.1"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("black"), vhost); + + } + + public void testPatternMatching() + { + final Map<String, Object> attributes = new HashMap<>(); + attributes.put(VirtualHostAlias.NAME, "matcher"); + attributes.put(VirtualHostAlias.TYPE, PatternMatchingAlias.TYPE_NAME); + attributes.put(PatternMatchingAlias.PATTERN, "orange|pink.*"); + attributes.put(PatternMatchingAlias.VIRTUAL_HOST_NODE, _vhosts.get("purple").getParent(VirtualHostNode.class)); + _port.createVirtualHostAlias(attributes); + + VirtualHostImpl vhost = _port.getVirtualHost("orange"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("purple"), vhost); + + vhost = _port.getVirtualHost("pink"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("purple"), vhost); + + + vhost = _port.getVirtualHost("pinker"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("purple"), vhost); + + + + vhost = _port.getVirtualHost("o.*"); + + assertNull(vhost); + + } + + public void testPriority() + { + + VirtualHostImpl vhost = _port.getVirtualHost("blue"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("blue"), vhost); + + vhost = _port.getVirtualHost("black"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("black"), vhost); + + + + Map<String, Object> attributes = new HashMap<>(); + attributes.put(VirtualHostAlias.NAME, "matcher10"); + attributes.put(VirtualHostAlias.TYPE, PatternMatchingAlias.TYPE_NAME); + attributes.put(VirtualHostAlias.PRIORITY, 10); + attributes.put(PatternMatchingAlias.PATTERN, "bl.*"); + attributes.put(PatternMatchingAlias.VIRTUAL_HOST_NODE, _vhosts.get("purple").getParent(VirtualHostNode.class)); + _port.createVirtualHostAlias(attributes); + + vhost = _port.getVirtualHost("blue"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("purple"), vhost); + + vhost = _port.getVirtualHost("black"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("purple"), vhost); + + + attributes = new HashMap<>(); + attributes.put(VirtualHostAlias.NAME, "matcher5"); + attributes.put(VirtualHostAlias.TYPE, PatternMatchingAlias.TYPE_NAME); + attributes.put(VirtualHostAlias.PRIORITY, 5); + attributes.put(PatternMatchingAlias.PATTERN, ".*u.*"); + attributes.put(PatternMatchingAlias.VIRTUAL_HOST_NODE, _vhosts.get("red").getParent(VirtualHostNode.class)); + _port.createVirtualHostAlias(attributes); + + + + vhost = _port.getVirtualHost("blue"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("red"), vhost); + + vhost = _port.getVirtualHost("black"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("purple"), vhost); + + + + vhost = _port.getVirtualHost("purple"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("red"), vhost); + + + + } +} diff --git a/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Connection_1_0.java b/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Connection_1_0.java index f97a223f4d..377eaab4cf 100644 --- a/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Connection_1_0.java +++ b/qpid/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Connection_1_0.java @@ -130,21 +130,12 @@ public class Connection_1_0 implements ConnectionEventListener, AMQConnectionMod public void openReceived() { String host = _conn.getLocalHostname(); - if(host == null || host.trim().equals("")) - { - host = _broker.getDefaultVirtualHost(); - } - _vhost = ((AmqpPort)_port).getVirtualHost(host); - if(_vhost == null && _port.isLocalMachine(host)) - { - _vhost = ((AmqpPort)_port).getVirtualHost(_broker.getDefaultVirtualHost()); - } if(_vhost == null) { final Error err = new Error(); err.setCondition(AmqpError.NOT_FOUND); - err.setDescription("Unknown hostname " + _conn.getLocalHostname()); + err.setDescription("Unknown hostname in connection open: '" + host + "'"); _conn.close(err); _closedOnOpen = true; } diff --git a/qpid/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/store/derby/DerbyUtils.java b/qpid/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/store/derby/DerbyUtils.java index 9bdce9af1c..b3c449747b 100644 --- a/qpid/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/store/derby/DerbyUtils.java +++ b/qpid/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/store/derby/DerbyUtils.java @@ -32,7 +32,6 @@ import java.sql.ResultSet; import java.sql.SQLException; import org.apache.qpid.server.store.StoreException; -import org.apache.qpid.util.FileUtils; public class DerbyUtils { 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 7bde933bb9..7d86bd3c8c 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 @@ -268,7 +268,8 @@ public class ConfiguredObjectToMapConverter if (!childObjects.isEmpty()) { - object.put(childClass.getSimpleName().toLowerCase() + "s", childObjects); + String childTypeSingular = childClass.getSimpleName().toLowerCase(); + object.put(childTypeSingular + (childTypeSingular.endsWith("s") ? "es" : "s"), childObjects); } } } diff --git a/qpid/java/systests/etc/config-systests.json b/qpid/java/systests/etc/config-systests.json index 3ef4fa40f8..fa5e7f7724 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.0", + "modelVersion": "2.1", "authenticationproviders" : [ { "name" : "plain", "type" : "PlainPasswordFile", @@ -41,7 +41,17 @@ "name" : "amqp", "authenticationProvider" : "plain", "port" : "${test.port}", - "protocols" : "${test.amqp_port_protocols}" + "protocols" : "${test.amqp_port_protocols}", + "virtualhostaliases" : [ { + "name" : "nameAlias", + "type" : "nameAlias" + }, { + "name" : "defaultAlias", + "type" : "defaultAlias" + }, { + "name" : "hostnameAlias", + "type" : "hostnameAlias" + } ] }, { "name" : "http", "authenticationProvider" : "plain", diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java index 386cd80f38..369a76a6c6 100755 --- a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java +++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java @@ -50,6 +50,7 @@ import javax.naming.NamingException; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; import org.apache.qpid.client.AMQConnectionFactory; import org.apache.qpid.client.AMQConnectionURL; diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java index c7bcdd2edb..fb254f59ae 100644 --- a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java +++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java @@ -57,6 +57,8 @@ import org.apache.qpid.server.model.Plugin; import org.apache.qpid.server.model.PreferencesProvider; import org.apache.qpid.server.model.SystemConfig; import org.apache.qpid.server.model.UUIDGenerator; +import org.apache.qpid.server.model.VirtualHostAlias; +import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.server.model.adapter.FileBasedGroupProvider; import org.apache.qpid.server.model.adapter.FileBasedGroupProviderImpl; import org.apache.qpid.server.plugin.PluggableFactoryLoader; @@ -254,12 +256,47 @@ public class TestBrokerConfiguration } public UUID[] removeObjectConfiguration(final Class<? extends ConfiguredObject> category, - String name) + final String name) { final ConfiguredObjectRecord entry = findObject(category, name); + if (entry != null) { + + if(category == VirtualHostNode.class) + { + final List<ConfiguredObjectRecord> aliasRecords = new ArrayList<>(); + // remove vhost aliases associated with the vhost + final ConfiguredObjectRecordHandler visitor = new ConfiguredObjectRecordHandler() + { + @Override + public void begin() + { + + } + + @Override + public boolean handle(final ConfiguredObjectRecord record) + { + if (record.getType().equals(VirtualHostAlias.class.getSimpleName()) + && name.equals(record.getAttributes().get(ConfiguredObject.NAME))) + { + aliasRecords.add(record); + } + return true; + } + + @Override + public void end() + { + + } + }; + _store.visitConfiguredObjectRecords(visitor); + _store.remove(aliasRecords.toArray(new ConfiguredObjectRecord[aliasRecords.size()])); + } return _store.remove(entry); + } return null; } @@ -271,6 +308,18 @@ public class TestBrokerConfiguration return id; } + public UUID addObjectConfiguration(final Class<? extends ConfiguredObject> parentCategory, final String parentName, + Class<? extends ConfiguredObject> type, Map<String, Object> attributes) + { + UUID id = UUIDGenerator.generateRandomUUID(); + ConfiguredObjectRecord entry = + new ConfiguredObjectRecordImpl(id, type.getSimpleName(), attributes, + Collections.singletonMap(parentCategory.getSimpleName(), findObject(parentCategory,parentName).getId())); + + _store.update(true, entry); + return id; + } + public UUID addJmxManagementConfiguration() { Map<String, Object> attributes = new HashMap<String, Object>(); 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 3464051fc5..1dba5ced9d 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 @@ -42,8 +42,11 @@ import org.slf4j.LoggerFactory; import org.apache.qpid.client.AMQConnectionURL; import org.apache.qpid.client.AMQTestConnection_0_10; import org.apache.qpid.jms.ConnectionURL; +import org.apache.qpid.server.model.DefaultVirtualHostAlias; import org.apache.qpid.server.model.Port; import org.apache.qpid.server.model.Transport; +import org.apache.qpid.server.model.VirtualHostAlias; +import org.apache.qpid.server.model.VirtualHostNameAlias; import org.apache.qpid.test.utils.QpidBrokerTestCase; import org.apache.qpid.test.utils.TestBrokerConfiguration; @@ -216,7 +219,7 @@ public class SSLTest extends QpidBrokerTestCase AMQTestConnection_0_10 con = new AMQTestConnection_0_10(url); org.apache.qpid.transport.Connection transportCon = con.getConnection(); String userID = transportCon.getSecurityLayer().getUserID(); - assertEquals("The correct certificate was not choosen","app1@acme.org",userID); + assertEquals("The correct certificate was not chosen","app1@acme.org",userID); con.close(); url = "amqp://guest:guest@test/?brokerlist='tcp://localhost:" + @@ -226,7 +229,7 @@ public class SSLTest extends QpidBrokerTestCase con = new AMQTestConnection_0_10(url); transportCon = con.getConnection(); userID = transportCon.getSecurityLayer().getUserID(); - assertEquals("The correct certificate was not choosen","app2@acme.org",userID); + assertEquals("The correct certificate was not chosen","app2@acme.org",userID); con.close(); } } @@ -465,6 +468,17 @@ public class SSLTest extends QpidBrokerTestCase sslPortAttributes.put(Port.KEY_STORE, TestBrokerConfiguration.ENTRY_NAME_SSL_KEYSTORE); sslPortAttributes.put(Port.TRUST_STORES, Collections.singleton(TestBrokerConfiguration.ENTRY_NAME_SSL_TRUSTSTORE)); getBrokerConfiguration().addObjectConfiguration(Port.class,sslPortAttributes); + + Map<String, Object> aliasAttributes = new HashMap<>(); + aliasAttributes.put(VirtualHostAlias.NAME, "defaultAlias"); + aliasAttributes.put(VirtualHostAlias.TYPE, DefaultVirtualHostAlias.TYPE_NAME); + getBrokerConfiguration().addObjectConfiguration(Port.class, TestBrokerConfiguration.ENTRY_NAME_SSL_PORT, VirtualHostAlias.class, aliasAttributes); + + aliasAttributes = new HashMap<>(); + aliasAttributes.put(VirtualHostAlias.NAME, "nameAlias"); + aliasAttributes.put(VirtualHostAlias.TYPE, VirtualHostNameAlias.TYPE_NAME); + getBrokerConfiguration().addObjectConfiguration(Port.class, TestBrokerConfiguration.ENTRY_NAME_SSL_PORT, VirtualHostAlias.class, aliasAttributes); + } } 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 0d0c1257a2..5522187ee5 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 @@ -41,9 +41,12 @@ import javax.jms.JMSException; import org.apache.qpid.client.AMQConnectionURL; import org.apache.qpid.management.common.mbeans.ManagedConnection; import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.DefaultVirtualHostAlias; import org.apache.qpid.server.model.Port; import org.apache.qpid.server.model.Transport; import org.apache.qpid.server.model.TrustStore; +import org.apache.qpid.server.model.VirtualHostAlias; +import org.apache.qpid.server.model.VirtualHostNameAlias; import org.apache.qpid.server.security.FileTrustStore; import org.apache.qpid.test.utils.JMXTestUtils; import org.apache.qpid.test.utils.QpidBrokerTestCase; @@ -346,6 +349,17 @@ public class ExternalAuthenticationTest extends QpidBrokerTestCase sslPortAttributes.put(Port.TRUST_STORES, trustStoreNames); config.addObjectConfiguration(Port.class, sslPortAttributes); + Map<String, Object> aliasAttributes = new HashMap<>(); + aliasAttributes.put(VirtualHostAlias.NAME, "defaultAlias"); + aliasAttributes.put(VirtualHostAlias.TYPE, DefaultVirtualHostAlias.TYPE_NAME); + getBrokerConfiguration().addObjectConfiguration(Port.class, TestBrokerConfiguration.ENTRY_NAME_SSL_PORT, VirtualHostAlias.class, aliasAttributes); + + aliasAttributes = new HashMap<>(); + aliasAttributes.put(VirtualHostAlias.NAME, "nameAlias"); + aliasAttributes.put(VirtualHostAlias.TYPE, VirtualHostNameAlias.TYPE_NAME); + getBrokerConfiguration().addObjectConfiguration(Port.class, TestBrokerConfiguration.ENTRY_NAME_SSL_PORT, VirtualHostAlias.class, aliasAttributes); + + Map<String, Object> externalAuthProviderAttributes = new HashMap<String, Object>(); externalAuthProviderAttributes.put(AuthenticationProvider.NAME, TestBrokerConfiguration.ENTRY_NAME_EXTERNAL_PROVIDER); externalAuthProviderAttributes.put(AuthenticationProvider.TYPE, ExternalAuthenticationManager.PROVIDER_TYPE); diff --git a/qpid/java/systests/src/test/java/org/apache/qpid/server/security/auth/manager/MultipleAuthenticationManagersTest.java b/qpid/java/systests/src/test/java/org/apache/qpid/server/security/auth/manager/MultipleAuthenticationManagersTest.java index 1c32a3f671..f5e17a0953 100644 --- a/qpid/java/systests/src/test/java/org/apache/qpid/server/security/auth/manager/MultipleAuthenticationManagersTest.java +++ b/qpid/java/systests/src/test/java/org/apache/qpid/server/security/auth/manager/MultipleAuthenticationManagersTest.java @@ -35,8 +35,11 @@ import javax.jms.JMSException; import org.apache.qpid.AMQException; import org.apache.qpid.client.AMQConnection; import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.DefaultVirtualHostAlias; import org.apache.qpid.server.model.Port; import org.apache.qpid.server.model.Transport; +import org.apache.qpid.server.model.VirtualHostAlias; +import org.apache.qpid.server.model.VirtualHostNameAlias; import org.apache.qpid.test.utils.QpidBrokerTestCase; import org.apache.qpid.test.utils.TestBrokerConfiguration; @@ -61,6 +64,17 @@ public class MultipleAuthenticationManagersTest extends QpidBrokerTestCase sslPortAttributes.put(Port.AUTHENTICATION_PROVIDER, TestBrokerConfiguration.ENTRY_NAME_ANONYMOUS_PROVIDER); config.addObjectConfiguration(Port.class, sslPortAttributes); + Map<String, Object> aliasAttributes = new HashMap<>(); + aliasAttributes.put(VirtualHostAlias.NAME, "defaultAlias"); + aliasAttributes.put(VirtualHostAlias.TYPE, DefaultVirtualHostAlias.TYPE_NAME); + config.addObjectConfiguration(Port.class, TestBrokerConfiguration.ENTRY_NAME_SSL_PORT, VirtualHostAlias.class, aliasAttributes); + + aliasAttributes = new HashMap<>(); + aliasAttributes.put(VirtualHostAlias.NAME, "nameAlias"); + aliasAttributes.put(VirtualHostAlias.TYPE, VirtualHostNameAlias.TYPE_NAME); + getBrokerConfiguration().addObjectConfiguration(Port.class, TestBrokerConfiguration.ENTRY_NAME_SSL_PORT, VirtualHostAlias.class, aliasAttributes); + + // set the ssl system properties setSystemProperty("javax.net.ssl.keyStore", KEYSTORE); setSystemProperty("javax.net.ssl.keyStorePassword", KEYSTORE_PASSWORD); |
