summaryrefslogtreecommitdiff
path: root/java/broker/src
diff options
context:
space:
mode:
authorRobert Godfrey <rgodfrey@apache.org>2010-01-31 00:31:49 +0000
committerRobert Godfrey <rgodfrey@apache.org>2010-01-31 00:31:49 +0000
commit2b8bb96fca71909d1dc185e1f62ee5fdaad02abd (patch)
tree919f0119bd3d23d97b497c5fa486121d4b5e286d /java/broker/src
parentf038a9ea62f563979678c2f1251d1eda82f1f20f (diff)
downloadqpid-python-2b8bb96fca71909d1dc185e1f62ee5fdaad02abd.tar.gz
QPID-2379 : Initial work on adding QMF and federation to the Java Broker
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@904934 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/broker/src')
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/CompletionCode.java36
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java559
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerRequestCommand.java78
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerResponseCommand.java46
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFClass.java158
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFClassIndicationCommand.java50
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFClassQueryCommand.java90
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFCommand.java54
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandCompletionCommand.java56
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandDecoder.java98
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandHeader.java63
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFEventClass.java42
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFEventCommand.java49
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFEventSeverity.java33
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFGetQueryCommand.java182
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java205
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFMethod.java157
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodInvocation.java26
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodRequestCommand.java88
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodResponseCommand.java43
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFObject.java76
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFObjectClass.java44
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFOperation.java67
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFPackage.java67
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageIndicationCommand.java46
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageQueryCommand.java86
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFProperty.java123
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaRequestCommand.java88
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaResponseCommand.java83
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java1583
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFStatistic.java61
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFType.java53
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java269
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java117
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java290
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfig.java43
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfigType.java112
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfig.java50
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfigType.java169
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfig.java59
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigType.java143
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigObjectType.java30
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigProperty.java66
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java184
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ConfiguredObject.java36
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfig.java45
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfigType.java145
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfig.java57
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfigType.java113
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfig.java59
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfigType.java136
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfig.java72
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfigType.java121
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java9
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfig.java41
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfigType.java136
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfig.java47
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfigType.java136
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfig.java44
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigImpl.java136
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigType.java128
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfig.java36
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfigType.java96
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java330
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java139
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java10
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java4
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java237
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeMBean.java79
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java48
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java202
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeMBean.java68
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java197
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeMBean.java96
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/Index.java114
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java439
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeMBean.java74
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicBinding.java70
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicExchangeResult.java179
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicNormalizer.java96
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java807
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java497
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/filter/JMSSelectorFilter.java3
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java9
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java5
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/QueueBindHandler.java38
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java13
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java12
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/QueueUnbindHandler.java17
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/logging/subjects/BindingLogSubject.java9
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ExchangeLogSubject.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/logging/subjects/QueueLogSubject.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/message/AMQMessageHeader.java4
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java13
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java12
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferHeader.java24
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferMessage.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java140
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java37
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java14
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngineFactory_0_10.java46
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java102
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java14
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java50
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java126
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java12
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/BaseQueue.java42
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueue.java42
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueueList.java168
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java3
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/ExchangeBinding.java91
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/ExchangeBindings.java82
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java6
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java3
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java30
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java351
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java14
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java92
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java163
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java14
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java40
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalPermissions.java32
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousInitialiser.java39
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServer.java88
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java63
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/store/DerbyMessageStore.java57
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java5
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java119
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java246
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java29
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java132
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java55
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java9
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java11
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java15
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java30
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java24
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java185
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java13
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java6
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Copy.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/List.java4
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.java2
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java201
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java57
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java74
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java13
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersBindingTest.java10
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java9
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/messages/ExchangeMessagesTest.java8
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/subjects/AbstractTestLogSubject.java8
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/subjects/BindingLogSubjectTest.java2
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java4
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java127
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/queue/MockQueueEntry.java5
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java67
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/registry/ApplicationRegistryShutdownTest.java26
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java30
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/access/QueueDenier.java2
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java82
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java2
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/util/NullApplicationRegistry.java15
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java19
-rw-r--r--java/broker/src/xsl/qmf.xsl842
165 files changed, 13741 insertions, 2178 deletions
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/CompletionCode.java b/java/broker/src/main/java/org/apache/qpid/qmf/CompletionCode.java
new file mode 100644
index 0000000000..706ab3974a
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/CompletionCode.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.qmf;
+
+public enum CompletionCode
+{
+ OK,
+ UNKNOWN_OBJECT,
+ UNKNOWN_METHOD,
+ NOT_IMPLEMENTED,
+ INVALID_PARAMETER,
+ FEATURE_NOT_IMPLEMENTED,
+ FORBIDDEN,
+ EXCEPTION,
+ UNKNOWN_PACKAGE,
+ UNKNOWN_CLASS;
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java b/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java
new file mode 100644
index 0000000000..b639cb9fc1
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java
@@ -0,0 +1,559 @@
+/*
+ *
+ * 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.qmf;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.server.binding.Binding;
+import org.apache.qpid.server.configuration.ConfigStore;
+import org.apache.qpid.server.configuration.ConfiguredObject;
+import org.apache.qpid.server.configuration.ExchangeConfigType;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.exchange.ExchangeReferrer;
+import org.apache.qpid.server.exchange.ExchangeType;
+import org.apache.qpid.server.exchange.topic.TopicBinding;
+import org.apache.qpid.server.exchange.topic.TopicExchangeResult;
+import org.apache.qpid.server.exchange.topic.TopicMatcherResult;
+import org.apache.qpid.server.exchange.topic.TopicNormalizer;
+import org.apache.qpid.server.exchange.topic.TopicParser;
+import org.apache.qpid.server.message.AMQMessageHeader;
+import org.apache.qpid.server.message.InboundMessage;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.queue.BaseQueue;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.TimerTask;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class ManagementExchange implements Exchange, QMFService.Listener
+{
+ private static final AMQShortString QPID_MANAGEMENT = new AMQShortString("qpid.management");
+ private static final AMQShortString QPID_MANAGEMENT_TYPE = new AMQShortString("management");
+
+ private VirtualHost _virtualHost;
+
+ private final TopicParser _parser = new TopicParser();
+
+ private final Map<AMQShortString, TopicExchangeResult> _topicExchangeResults =
+ new ConcurrentHashMap<AMQShortString, TopicExchangeResult>();
+
+ private final Map<TopicBinding, FieldTable> _topicBindings = new HashMap<TopicBinding, FieldTable>();
+ private final Set<Binding> _bindingSet = new HashSet<Binding>();
+ private UUID _id;
+ private static final String AGENT_BANK = "0";
+
+ private int _bindingCountHigh;
+ private final AtomicLong _msgReceived = new AtomicLong();
+ private final AtomicLong _bytesReceived = new AtomicLong();
+
+ private final CopyOnWriteArrayList<BindingListener> _listeners = new CopyOnWriteArrayList<Exchange.BindingListener>();
+
+ // TODO
+ private long _createTime = System.currentTimeMillis();
+
+
+ private class ManagementQueue implements BaseQueue
+ {
+ private final String NAME_AS_STRING = "##__mgmt_pseudo_queue__##" + UUID.randomUUID().toString();
+ private final AMQShortString NAME_AS_SHORT_STRING = new AMQShortString(NAME_AS_STRING);
+
+ public void enqueue(ServerMessage message) throws AMQException
+ {
+ AMQMessageHeader h = message.getMessageHeader();
+ long size = message.getSize();
+
+ ByteBuffer buf = ByteBuffer.allocate((int) size);
+
+ int offset = 0;
+
+ while(offset < size)
+ {
+ offset += message.getContent(buf,offset);
+ }
+
+ buf.flip();
+ QMFCommandDecoder commandDecoder = new QMFCommandDecoder(getQMFService(),buf);
+ QMFCommand cmd;
+ while((cmd = commandDecoder.decode()) != null)
+ {
+ cmd.process(_virtualHost, message);
+ }
+
+ }
+
+ public void enqueue(ServerMessage message, PostEnqueueAction action) throws AMQException
+ {
+ enqueue(message);
+ }
+
+ public boolean isDurable()
+ {
+ return false;
+ }
+
+ public AMQShortString getNameShortString()
+ {
+ return NAME_AS_SHORT_STRING;
+ }
+
+ public String getResourceName()
+ {
+ return NAME_AS_STRING;
+ }
+ }
+
+
+ private final ManagementQueue _mgmtQueue = new ManagementQueue();
+
+ public ManagementExchange()
+ {
+ }
+
+ public static final ExchangeType<ManagementExchange> TYPE = new ExchangeType<ManagementExchange>()
+ {
+
+ public AMQShortString getName()
+ {
+ return QPID_MANAGEMENT_TYPE;
+ }
+
+ public Class<ManagementExchange> getExchangeClass()
+ {
+ return ManagementExchange.class;
+ }
+
+ public ManagementExchange newInstance(VirtualHost host,
+ AMQShortString name,
+ boolean durable,
+ int ticket,
+ boolean autoDelete) throws AMQException
+ {
+ ManagementExchange exch = new ManagementExchange();
+ exch.initialise(host, name, durable, ticket, autoDelete);
+ return exch;
+ }
+
+ public AMQShortString getDefaultExchangeName()
+ {
+ return QPID_MANAGEMENT;
+ }
+ };
+
+
+ public AMQShortString getNameShortString()
+ {
+ return QPID_MANAGEMENT;
+ }
+
+ public AMQShortString getTypeShortString()
+ {
+ return QPID_MANAGEMENT_TYPE;
+ }
+
+ public void initialise(VirtualHost host, AMQShortString name, boolean durable, int ticket, boolean autoDelete)
+ throws AMQException
+ {
+ if(!QPID_MANAGEMENT.equals(name))
+ {
+ throw new AMQException("Can't create more than one Management exchange");
+ }
+ _virtualHost = host;
+ _id = host.getConfigStore().createId();
+ _virtualHost.scheduleTask(_virtualHost.getBroker().getManagementPublishInterval(),_updateTask);
+ getConfigStore().addConfiguredObject(this);
+ getQMFService().addListener(this);
+ }
+
+ public UUID getId()
+ {
+ return _id;
+ }
+
+ public ExchangeConfigType getConfigType()
+ {
+ return ExchangeConfigType.getInstance();
+ }
+
+ public ConfiguredObject getParent()
+ {
+ return _virtualHost;
+ }
+
+ public boolean isDurable()
+ {
+ return true;
+ }
+
+ public VirtualHost getVirtualHost()
+ {
+ return _virtualHost;
+ }
+
+ public String getName()
+ {
+ return QPID_MANAGEMENT.toString();
+ }
+
+ public ExchangeType getType()
+ {
+ return TYPE;
+ }
+
+ public boolean isAutoDelete()
+ {
+ return false;
+ }
+
+ public int getTicket()
+ {
+ return 0;
+ }
+
+ public void close() throws AMQException
+ {
+ getConfigStore().removeConfiguredObject(this);
+ }
+
+ public ConfigStore getConfigStore()
+ {
+ return getVirtualHost().getConfigStore();
+ }
+
+ public synchronized void addBinding(final Binding b)
+ {
+
+ _bindingSet.add(b);
+
+ for(BindingListener listener : _listeners)
+ {
+ listener.bindingAdded(this, b);
+ }
+
+ if(_bindingSet.size() > _bindingCountHigh)
+ {
+ _bindingCountHigh = _bindingSet.size();
+ }
+
+ TopicBinding binding = new TopicBinding(new AMQShortString(b.getBindingKey()), b.getQueue(), null);
+
+ if(!_topicBindings.containsKey(binding))
+ {
+ AMQShortString routingKey = TopicNormalizer.normalize(new AMQShortString(b.getBindingKey()));
+
+ TopicExchangeResult result = _topicExchangeResults.get(routingKey);
+ if(result == null)
+ {
+ result = new TopicExchangeResult();
+ result.addUnfilteredQueue(b.getQueue());
+ _parser.addBinding(routingKey, result);
+ _topicExchangeResults.put(routingKey,result);
+ }
+ else
+ {
+ result.addUnfilteredQueue(b.getQueue());
+ }
+ _topicBindings.put(binding, null);
+
+
+ }
+ String bindingKey = b.getBindingKey();
+
+ if(bindingKey.startsWith("schema.") || bindingKey.startsWith("*.") || bindingKey.startsWith("#."))
+ {
+ publishAllSchema();
+ }
+ if(bindingKey.startsWith("console.") || bindingKey.startsWith("*.") || bindingKey.startsWith("#."))
+ {
+ publishAllConsole();
+ }
+
+ }
+
+ void publishAllConsole()
+ {
+ QMFService qmfService = getQMFService();
+
+ long sampleTime = System.currentTimeMillis();
+
+ for(QMFPackage pkg : qmfService.getSupportedSchemas())
+ {
+ for(QMFClass qmfClass : pkg.getClasses())
+ {
+ Collection<QMFObject> qmfObjects = qmfService.getObjects(qmfClass);
+
+ publishObjectsToConsole(sampleTime, qmfObjects);
+ }
+
+ }
+
+ }
+
+ private QMFService getQMFService()
+ {
+ return _virtualHost.getApplicationRegistry().getQMFService();
+ }
+
+ void publishObjectsToConsole(final long sampleTime,
+ final Collection<QMFObject> qmfObjects)
+ {
+ if(!qmfObjects.isEmpty() && hasBindings())
+ {
+ QMFClass qmfClass = qmfObjects.iterator().next().getQMFClass();
+ ArrayList<QMFCommand> commands = new ArrayList<QMFCommand>();
+
+
+ for(QMFObject obj : qmfObjects)
+ {
+ commands.add(obj.asConfigInfoCmd(sampleTime));
+ commands.add(obj.asInstrumentInfoCmd(sampleTime));
+ }
+
+ publishToConsole(qmfClass, commands);
+ }
+ }
+
+ private void publishToConsole(final QMFClass qmfClass, final ArrayList<QMFCommand> commands)
+ {
+ if(!commands.isEmpty() && hasBindings())
+ {
+ String routingKey = "console.obj.1." + AGENT_BANK + "." + qmfClass.getPackage().getName() + "." + qmfClass.getName();
+ QMFMessage message = new QMFMessage(routingKey,commands.toArray(new QMFCommand[commands.size()]));
+
+ Collection<TopicMatcherResult> results = _parser.parse(new AMQShortString(routingKey));
+ HashSet<AMQQueue> queues = new HashSet<AMQQueue>();
+ for(TopicMatcherResult result : results)
+ {
+ queues.addAll(((TopicExchangeResult)result).getUnfilteredQueues());
+ }
+ for(AMQQueue queue : queues)
+ {
+ try
+ {
+ queue.enqueue(message);
+ }
+ catch (AMQException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }
+
+ void publishAllSchema()
+ {
+
+ }
+
+ public synchronized void removeBinding(final Binding binding)
+ {
+ _bindingSet.remove(binding);
+
+ TopicBinding topicBinding = new TopicBinding(new AMQShortString(binding.getBindingKey()), binding.getQueue(), null);
+
+ if(_topicBindings.containsKey(topicBinding))
+ {
+ AMQShortString bindingKey = TopicNormalizer.normalize(topicBinding.getBindingKey());
+ TopicExchangeResult result = _topicExchangeResults.get(bindingKey);
+ result.removeUnfilteredQueue(binding.getQueue());
+ }
+
+ for(BindingListener listener : _listeners)
+ {
+ listener.bindingRemoved(this, binding);
+ }
+ }
+
+ public synchronized Collection<Binding> getBindings()
+ {
+ return new ArrayList<Binding>(_bindingSet);
+ }
+
+ public ArrayList<BaseQueue> route(InboundMessage message)
+ {
+ ArrayList<BaseQueue> queues = new ArrayList<BaseQueue>(1);
+ _msgReceived.incrementAndGet();
+ _bytesReceived.addAndGet(message.getSize());
+ queues.add(_mgmtQueue);
+ return queues;
+ }
+
+ public boolean isBound(AMQShortString routingKey, FieldTable arguments, AMQQueue queue)
+ {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public boolean isBound(AMQShortString routingKey, AMQQueue queue)
+ {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public boolean isBound(AMQShortString routingKey)
+ {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public boolean isBound(AMQQueue queue)
+ {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public boolean hasBindings()
+ {
+ return !_bindingSet.isEmpty();
+ }
+
+ public boolean isBound(String bindingKey, AMQQueue queue)
+ {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public boolean isBound(String bindingKey)
+ {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void addCloseTask(final Task task)
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void removeCloseTask(final Task task)
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+
+
+ public Exchange getAlternateExchange()
+ {
+ return null;
+ }
+
+ public Map<String, Object> getArguments()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void setAlternateExchange(Exchange exchange)
+ {
+
+ }
+
+ public void removeReference(ExchangeReferrer exchange)
+ {
+ }
+
+ public void addReference(ExchangeReferrer exchange)
+ {
+ }
+
+ public boolean hasReferrers()
+ {
+ return true;
+ }
+
+
+
+ private final TimerTask _updateTask = new UpdateTask();
+
+
+ private class UpdateTask extends TimerTask
+ {
+
+ public void run()
+ {
+ publishAllConsole();
+ publishAllSchema();
+
+ }
+
+ }
+
+ public void objectCreated(final QMFObject obj)
+ {
+ publishObjectsToConsole(System.currentTimeMillis(), Collections.singleton(obj));
+ }
+
+ public void objectDeleted(final QMFObject obj)
+ {
+ publishObjectsToConsole(System.currentTimeMillis(), Collections.singleton(obj));
+ }
+
+ public long getBindingCount()
+ {
+ return getBindings().size();
+ }
+
+ public long getBindingCountHigh()
+ {
+ return _bindingCountHigh;
+ }
+
+ public long getMsgReceives()
+ {
+ return _msgReceived.get();
+ }
+
+ public long getMsgRoutes()
+ {
+ return getMsgReceives();
+ }
+
+ public long getByteReceives()
+ {
+ return _bytesReceived.get();
+ }
+
+ public long getByteRoutes()
+ {
+ return getByteReceives();
+ }
+
+ public long getCreateTime()
+ {
+ return _createTime;
+ }
+
+ public void addBindingListener(final BindingListener listener)
+ {
+ _listeners.add(listener);
+ }
+
+ public void removeBindingListener(final BindingListener listener)
+ {
+ _listeners.remove(listener);
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerRequestCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerRequestCommand.java
new file mode 100644
index 0000000000..b98daf7cb1
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerRequestCommand.java
@@ -0,0 +1,78 @@
+/*
+ *
+ * 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.qmf;
+
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.codec.BBEncoder;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.server.message.MessageTransferMessage;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.queue.BaseQueue;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.management.common.mbeans.ManagedConnection;
+
+import java.util.ArrayList;
+
+public class QMFBrokerRequestCommand extends QMFCommand
+{
+
+ public QMFBrokerRequestCommand(QMFCommandHeader header, BBDecoder buf)
+ {
+ super(header);
+ }
+
+ public void process(VirtualHost virtualHost, ServerMessage message)
+ {
+ String exchangeName = message.getMessageHeader().getReplyToExchange();
+ String queueName = message.getMessageHeader().getReplyToRoutingKey();
+
+ QMFCommand[] commands = new QMFCommand[2];
+ commands[0] = new QMFBrokerResponseCommand(this, virtualHost);
+ commands[1] = new QMFCommandCompletionCommand(this);
+
+ Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName);
+
+ for(QMFCommand cmd : commands)
+ {
+ QMFMessage responseMessage = new QMFMessage(queueName, cmd);
+
+
+ ArrayList<? extends BaseQueue> queues = exchange.route(responseMessage);
+
+
+ for(BaseQueue q : queues)
+ {
+ try
+ {
+ q.enqueue(responseMessage);
+ }
+ catch (AMQException e)
+ {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ }
+ }
+ }
+ }
+
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerResponseCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerResponseCommand.java
new file mode 100644
index 0000000000..ac01c47fe8
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerResponseCommand.java
@@ -0,0 +1,46 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.qmf;
+
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.transport.codec.BBEncoder;
+
+public class QMFBrokerResponseCommand extends QMFCommand
+{
+ private QMFCommandHeader _header;
+ private VirtualHost _virtualHost;
+
+ public QMFBrokerResponseCommand(QMFBrokerRequestCommand qmfBrokerRequestCommand, VirtualHost virtualHost)
+ {
+ super( new QMFCommandHeader(qmfBrokerRequestCommand.getHeader().getVersion(),
+ qmfBrokerRequestCommand.getHeader().getSeq(),
+ QMFOperation.BROKER_RESPONSE));
+ _virtualHost = virtualHost;
+ }
+
+ public void encode(BBEncoder encoder)
+ {
+ super.encode(encoder);
+ encoder.writeUuid(_virtualHost.getBrokerId());
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFClass.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFClass.java
new file mode 100644
index 0000000000..3408ff09f4
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFClass.java
@@ -0,0 +1,158 @@
+/*
+ *
+ * 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.qmf;
+
+import org.apache.qpid.server.configuration.ConfiguredObject;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.List;
+import java.util.LinkedHashMap;
+
+abstract public class QMFClass
+{
+
+
+ public enum Type
+ {
+ OBJECT((byte)1),
+ EVENT((byte)2);
+
+ private final byte _value;
+
+ Type(byte value)
+ {
+ _value = value;
+ }
+
+ public byte getValue()
+ {
+ return _value;
+ }
+ }
+
+ private final Type _type;
+ private QMFPackage _package;
+ private final String _name;
+ private byte[] _schemaHash;
+
+ private Map<String, QMFProperty> _properties = new LinkedHashMap<String, QMFProperty>();
+ private Map<String, QMFStatistic> _statistics = new LinkedHashMap<String, QMFStatistic>();
+ private Map<String, QMFMethod> _methods = new LinkedHashMap<String, QMFMethod>();
+
+
+
+ public QMFClass(Type type, String name, byte[] schemaHash, List<QMFProperty> properties,
+ List<QMFStatistic> statistics, List<QMFMethod> methods)
+ {
+ this(type, name, schemaHash);
+ setProperties(properties);
+ setStatistics(statistics);
+ setMethods(methods);
+ }
+
+
+ public QMFClass(Type type, String name, byte[] schemaHash)
+
+ {
+ _type = type;
+ _name = name;
+ _schemaHash = schemaHash;
+
+ }
+
+ protected void setProperties(List<QMFProperty> properties)
+ {
+ for(QMFProperty prop : properties)
+ {
+ _properties.put(prop.getName(), prop);
+ }
+ }
+
+ protected void setStatistics(List<QMFStatistic> statistics)
+ {
+ for(QMFStatistic stat : statistics)
+ {
+ _statistics.put(stat.getName(), stat);
+ }
+ }
+
+
+ protected void setMethods(List<QMFMethod> methods)
+ {
+ for(QMFMethod method : methods)
+ {
+ _methods.put(method.getName(), method);
+ }
+ }
+
+ public void setPackage(QMFPackage aPackage)
+ {
+ _package = aPackage;
+ for(QMFProperty prop : _properties.values())
+ {
+ prop.setQMFClass(this);
+ }
+ // TODO Statisics, Methods
+ }
+
+ public Type getType()
+ {
+ return _type;
+ }
+
+ public QMFPackage getPackage()
+ {
+ return _package;
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public byte[] getSchemaHash()
+ {
+ return _schemaHash;
+ }
+
+ public Collection<QMFProperty> getProperties()
+ {
+ return _properties.values();
+ }
+
+ public Collection<QMFStatistic> getStatistics()
+ {
+ return _statistics.values();
+ }
+
+ public Collection<QMFMethod> getMethods()
+ {
+ return _methods.values();
+ }
+
+ public QMFMethod getMethod(String methodName)
+ {
+ return _methods.get(methodName);
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassIndicationCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassIndicationCommand.java
new file mode 100644
index 0000000000..a956a9bd70
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassIndicationCommand.java
@@ -0,0 +1,50 @@
+/*
+ *
+ * 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.qmf;
+
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.transport.codec.BBEncoder;
+
+public class QMFClassIndicationCommand extends QMFCommand
+{
+ private QMFClass _qmfClass;
+
+ public QMFClassIndicationCommand(QMFClassQueryCommand qmfClassQueryCommand, QMFClass qmfClass)
+ {
+ super(new QMFCommandHeader(qmfClassQueryCommand.getHeader().getVersion(),
+ qmfClassQueryCommand.getHeader().getSeq(),
+ QMFOperation.CLASS_INDICATION));
+ _qmfClass = qmfClass;
+ }
+
+
+ @Override
+ public void encode(BBEncoder encoder)
+ {
+ super.encode(encoder);
+ encoder.writeUint8(_qmfClass.getType().getValue());
+ encoder.writeStr8(_qmfClass.getPackage().getName());
+ encoder.writeStr8(_qmfClass.getName());
+ encoder.writeBin128(_qmfClass.getSchemaHash());
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassQueryCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassQueryCommand.java
new file mode 100644
index 0000000000..26a27cfa19
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassQueryCommand.java
@@ -0,0 +1,90 @@
+/*
+ *
+ * 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.qmf;
+
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.queue.BaseQueue;
+import org.apache.qpid.server.registry.IApplicationRegistry;
+import org.apache.qpid.AMQException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+public class QMFClassQueryCommand extends QMFCommand
+{
+ private final String _package;
+
+ public QMFClassQueryCommand(QMFCommandHeader header, BBDecoder decoder)
+ {
+ super(header);
+ _package = decoder.readStr8();
+ }
+
+ public void process(VirtualHost virtualHost, ServerMessage message)
+ {
+ String exchangeName = message.getMessageHeader().getReplyToExchange();
+ String routingKey = message.getMessageHeader().getReplyToRoutingKey();
+
+ IApplicationRegistry appRegistry = virtualHost.getApplicationRegistry();
+ QMFService service = appRegistry.getQMFService();
+
+ QMFPackage qmfPackage = service.getPackage(_package);
+ Collection<QMFClass> qmfClasses = qmfPackage.getClasses();
+
+ QMFCommand[] commands = new QMFCommand[ qmfClasses.size() + 1 ];
+
+ int i = 0;
+ for(QMFClass qmfClass : qmfClasses)
+ {
+ commands[i++] = new QMFClassIndicationCommand(this, qmfClass);
+ }
+ commands[ commands.length - 1 ] = new QMFCommandCompletionCommand(this);
+
+
+ for(QMFCommand cmd : commands)
+ {
+
+
+ QMFMessage responseMessage = new QMFMessage(routingKey, cmd);
+
+ Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName);
+
+ ArrayList<? extends BaseQueue> queues = exchange.route(responseMessage);
+
+ for(BaseQueue q : queues)
+ {
+ try
+ {
+ q.enqueue(responseMessage);
+ }
+ catch (AMQException e)
+ {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ }
+ }
+ }
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommand.java
new file mode 100644
index 0000000000..4f143701af
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommand.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.qmf;
+
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.transport.codec.BBEncoder;
+
+public abstract class QMFCommand
+{
+
+ private final QMFCommandHeader _header;
+
+ protected QMFCommand(QMFCommandHeader header)
+ {
+ _header = header;
+ }
+
+
+ public void process(final VirtualHost virtualHost, final ServerMessage message)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void encode(BBEncoder encoder)
+ {
+ _header.encode(encoder);
+
+ }
+
+ public QMFCommandHeader getHeader()
+ {
+ return _header;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandCompletionCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandCompletionCommand.java
new file mode 100644
index 0000000000..f163e434d1
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandCompletionCommand.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.qmf;
+
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.transport.codec.BBEncoder;
+
+public class QMFCommandCompletionCommand extends QMFCommand
+{
+
+ private final CompletionCode _status;
+ private final String _text;
+
+ public QMFCommandCompletionCommand(QMFCommand command)
+ {
+ this(command, CompletionCode.OK, "");
+ }
+ public QMFCommandCompletionCommand(QMFCommand command, CompletionCode status, String text)
+ {
+ super( new QMFCommandHeader(command.getHeader().getVersion(),
+ command.getHeader().getSeq(),
+ QMFOperation.COMMAND_COMPLETION));
+
+ _status = status;
+ _text = text;
+ }
+
+
+ @Override
+ public void encode(BBEncoder encoder)
+ {
+ super.encode(encoder);
+ encoder.writeInt32(_status.ordinal());
+ encoder.writeStr8(_text);
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandDecoder.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandDecoder.java
new file mode 100644
index 0000000000..ac036dfa19
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandDecoder.java
@@ -0,0 +1,98 @@
+/*
+ *
+ * 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.qmf;
+
+import org.apache.qpid.transport.codec.BBDecoder;
+
+import java.nio.ByteBuffer;
+
+public class QMFCommandDecoder
+{
+ private BBDecoder _decoder;
+
+
+ private static final QMFOperation[] OP_CODES = new QMFOperation[256];
+ private final QMFService _qmfService;
+
+ static
+ {
+ for(QMFOperation op : QMFOperation.values())
+ {
+ OP_CODES[op.getOpcode()] = op;
+ }
+ }
+
+ public QMFCommandDecoder(final QMFService qmfService, ByteBuffer buf)
+ {
+ _qmfService = qmfService;
+ _decoder = new BBDecoder();
+ _decoder.init(buf);
+ }
+
+ public QMFCommand decode()
+ {
+ if(_decoder.hasRemaining())
+ {
+ QMFCommandHeader header = readQMFHeader();
+
+ switch(header.getOperation())
+ {
+ case BROKER_REQUEST:
+ return new QMFBrokerRequestCommand(header, _decoder);
+ case PACKAGE_QUERY:
+ return new QMFPackageQueryCommand(header, _decoder);
+ case CLASS_QUERY:
+ return new QMFClassQueryCommand(header, _decoder);
+ case SCHEMA_REQUEST:
+ return new QMFSchemaRequestCommand(header, _decoder);
+ case METHOD_REQUEST:
+ return new QMFMethodRequestCommand(header, _decoder, _qmfService);
+ case GET_QUERY:
+ return new QMFGetQueryCommand(header, _decoder);
+ default:
+ System.out.println("Unknown command");
+
+ }
+
+ return null;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ private QMFCommandHeader readQMFHeader()
+ {
+ if(_decoder.readInt8() == (byte) 'A'
+ && _decoder.readInt8() == (byte) 'M')
+ {
+ byte version = _decoder.readInt8();
+ short opCode = _decoder.readUint8();
+ int seq = _decoder.readInt32();
+
+ return new QMFCommandHeader(version, seq, OP_CODES[opCode]);
+
+ }
+ return null;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandHeader.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandHeader.java
new file mode 100644
index 0000000000..c4d771317f
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandHeader.java
@@ -0,0 +1,63 @@
+/*
+ *
+ * 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.qmf;
+
+import org.apache.qpid.transport.codec.BBEncoder;
+
+public class QMFCommandHeader
+{
+ private final byte _version;
+ private final int _seq;
+
+ private final QMFOperation _operation;
+
+ public QMFCommandHeader(byte version, int seq, QMFOperation operation)
+ {
+ _version = version;
+ _seq = seq;
+ _operation = operation;
+ }
+
+ public byte getVersion()
+ {
+ return _version;
+ }
+
+ public int getSeq()
+ {
+ return _seq;
+ }
+
+ public QMFOperation getOperation()
+ {
+ return _operation;
+ }
+
+ public void encode(BBEncoder encoder)
+ {
+ encoder.writeUint8((short)'A');
+ encoder.writeUint8((short)'M');
+ encoder.writeInt8(_version);
+ encoder.writeUint8((short)_operation.getOpcode());
+ encoder.writeInt32(_seq);
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventClass.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventClass.java
new file mode 100644
index 0000000000..ec471f18e8
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventClass.java
@@ -0,0 +1,42 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.qmf;
+
+import java.util.List;
+
+public abstract class QMFEventClass extends QMFClass
+{
+ public QMFEventClass(String name,
+ byte[] schemaHash,
+ List<QMFProperty> properties,
+ List<QMFStatistic> statistics, List<QMFMethod> methods)
+ {
+ super(Type.EVENT, name, schemaHash, properties, statistics, methods);
+ }
+
+ public QMFEventClass(String name, byte[] schemaHash)
+ {
+ super(Type.EVENT, name, schemaHash);
+ }
+
+ abstract public QMFEventSeverity getSeverity();
+
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventCommand.java
new file mode 100644
index 0000000000..d70c12db19
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventCommand.java
@@ -0,0 +1,49 @@
+/*
+ *
+ * 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.qmf;
+
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.transport.codec.BBEncoder;
+
+public abstract class QMFEventCommand<T extends QMFEventClass> extends QMFCommand
+{
+ private final long _timestamp;
+
+ protected QMFEventCommand()
+ {
+ super(new QMFCommandHeader((byte)'2',0, QMFOperation.EVENT));
+ _timestamp = System.currentTimeMillis();
+ }
+
+ abstract public T getEventClass();
+
+ @Override
+ public void encode(final BBEncoder encoder)
+ {
+ super.encode(encoder);
+ encoder.writeStr8(getEventClass().getPackage().getName());
+ encoder.writeStr8(getEventClass().getName());
+ encoder.writeBin128(new byte[16]);
+ encoder.writeUint64(_timestamp * 1000000L);
+ encoder.writeUint8((short) getEventClass().getSeverity().ordinal());
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventSeverity.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventSeverity.java
new file mode 100644
index 0000000000..9f9c832732
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventSeverity.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.qmf;
+
+public enum QMFEventSeverity
+{
+ EMERGENCY,
+ ALERT,
+ CRITICAL,
+ ERROR,
+ WARN,
+ NOTICE,
+ INFORM,
+ DEBUG
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFGetQueryCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFGetQueryCommand.java
new file mode 100644
index 0000000000..8e8cb55a0d
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFGetQueryCommand.java
@@ -0,0 +1,182 @@
+/*
+ *
+ * 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.qmf;
+
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.queue.BaseQueue;
+import org.apache.qpid.server.registry.IApplicationRegistry;
+import org.apache.qpid.AMQException;
+
+import java.util.*;
+
+public class QMFGetQueryCommand extends QMFCommand
+{
+ private Map<String, Object> _map;
+
+
+ public QMFGetQueryCommand(QMFCommandHeader header, BBDecoder decoder)
+ {
+ super(header);
+
+ _map = decoder.readMap();
+ }
+
+ public void process(VirtualHost virtualHost, ServerMessage message)
+ {
+ String exchangeName = message.getMessageHeader().getReplyToExchange();
+ String routingKey = message.getMessageHeader().getReplyToRoutingKey();
+
+ IApplicationRegistry appRegistry = virtualHost.getApplicationRegistry();
+ QMFService service = appRegistry.getQMFService();
+
+ String className = (String) _map.get("_class");
+ String packageName = (String) _map.get("_package");
+ byte[] objectIdBytes = (byte[]) _map.get("_objectId");
+ UUID objectId;
+ if(objectIdBytes != null)
+ {
+ long msb = 0;
+ long lsb = 0;
+
+ for (int i = 0; i != 8; i++)
+ {
+ msb = (msb << 8) | (objectIdBytes[i] & 0xff);
+ }
+ for (int i = 8; i != 16; i++)
+ {
+ lsb = (lsb << 8) | (objectIdBytes[i] & 0xff);
+ }
+ objectId = new UUID(msb, lsb);
+ }
+ else
+ {
+ objectId = null;
+ }
+
+ List<QMFCommand> commands = new ArrayList<QMFCommand>();
+ final long sampleTime = System.currentTimeMillis() * 1000000l;
+
+ Collection<QMFPackage> packages;
+
+ if(packageName != null && packageName.length() != 0)
+ {
+ QMFPackage qmfPackage = service.getPackage(packageName);
+ if(qmfPackage == null)
+ {
+ packages = Collections.EMPTY_LIST;
+ }
+ else
+ {
+ packages = Collections.singleton(qmfPackage);
+ }
+ }
+ else
+ {
+ packages = service.getSupportedSchemas();
+ }
+
+ for(QMFPackage qmfPackage : packages)
+ {
+
+ Collection<QMFClass> qmfClasses;
+
+ if(className != null && className.length() != 0)
+ {
+ QMFClass qmfClass = qmfPackage.getQMFClass(className);
+ if(qmfClass == null)
+ {
+ qmfClasses = Collections.EMPTY_LIST;
+ }
+ else
+ {
+ qmfClasses = Collections.singleton(qmfClass);
+ }
+ }
+ else
+ {
+ qmfClasses = qmfPackage.getClasses();
+ }
+
+
+ for(QMFClass qmfClass : qmfClasses)
+ {
+ Collection<QMFObject> objects;
+
+ if(objectId != null)
+ {
+ QMFObject obj = service.getObjectById(qmfClass, objectId);
+ if(obj == null)
+ {
+ objects = Collections.EMPTY_LIST;
+ }
+ else
+ {
+ objects = Collections.singleton(obj);
+ }
+ }
+ else
+ {
+ objects = service.getObjects(qmfClass);
+ }
+
+ for(QMFObject object : objects)
+ {
+
+ commands.add(object.asGetQueryResponseCmd(this, sampleTime));
+ }
+ }
+
+
+ }
+
+
+ commands.add( new QMFCommandCompletionCommand(this));
+
+
+ for(QMFCommand cmd : commands)
+ {
+
+
+ QMFMessage responseMessage = new QMFMessage(routingKey, cmd);
+
+ Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName);
+
+ ArrayList<? extends BaseQueue> queues = exchange.route(responseMessage);
+
+ for(BaseQueue q : queues)
+ {
+ try
+ {
+ q.enqueue(responseMessage);
+ }
+ catch (AMQException e)
+ {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ }
+ }
+ }
+ }
+
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java
new file mode 100644
index 0000000000..c250b2c011
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java
@@ -0,0 +1,205 @@
+/*
+ *
+ * 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.qmf;
+
+import org.apache.qpid.server.message.*;
+import org.apache.qpid.transport.codec.BBEncoder;
+
+import java.nio.ByteBuffer;
+import java.util.Set;
+
+public class QMFMessage implements ServerMessage, InboundMessage, AMQMessageHeader
+{
+
+ private ByteBuffer _content;
+ private String _routingKey;
+
+ public QMFMessage(String routingKey, QMFCommand command)
+ {
+ this(routingKey, new QMFCommand[] { command });
+ }
+
+
+ public QMFMessage(String routingKey, QMFCommand[] commands)
+ {
+ _routingKey = routingKey;
+ BBEncoder encoder = new BBEncoder(256);
+
+ for(QMFCommand cmd : commands)
+ {
+ cmd.encode(encoder);
+ }
+
+
+ _content = encoder.buffer();
+ }
+
+ public String getRoutingKey()
+ {
+ return _routingKey;
+ }
+
+ public AMQMessageHeader getMessageHeader()
+ {
+ return this;
+ }
+
+ public boolean isPersistent()
+ {
+ return false;
+ }
+
+ public boolean isRedelivered()
+ {
+ return false;
+ }
+
+ public long getSize()
+ {
+ return _content.limit();
+ }
+
+ public boolean isImmediate()
+ {
+ return false;
+ }
+
+ public String getCorrelationId()
+ {
+ return null;
+ }
+
+ public long getExpiration()
+ {
+ return 0;
+ }
+
+ public String getMessageId()
+ {
+ return null;
+ }
+
+ public String getMimeType()
+ {
+ return null;
+ }
+
+ public String getEncoding()
+ {
+ return null;
+ }
+
+ public byte getPriority()
+ {
+ return 4;
+ }
+
+ public long getTimestamp()
+ {
+ return 0;
+ }
+
+ public String getType()
+ {
+ return null;
+ }
+
+ public String getReplyTo()
+ {
+ return null;
+ }
+
+ public String getReplyToExchange()
+ {
+ return null;
+ }
+
+ public String getReplyToRoutingKey()
+ {
+ return null;
+ }
+
+ public Object getHeader(String name)
+ {
+ return null;
+ }
+
+ public boolean containsHeaders(Set<String> names)
+ {
+ return false;
+ }
+
+ public boolean containsHeader(String name)
+ {
+ return false;
+ }
+
+ public MessageReference newReference()
+ {
+ return new QMFMessageReference(this);
+ }
+
+ public Long getMessageNumber()
+ {
+ return null;
+ }
+
+ public long getArrivalTime()
+ {
+ return 0;
+ }
+
+ public int getContent(ByteBuffer buf, int offset)
+ {
+ ByteBuffer src = _content.duplicate();
+ _content.position(offset);
+ _content = _content.slice();
+ int len = _content.remaining();
+ if(len > buf.remaining())
+ {
+ len = buf.remaining();
+ }
+
+ buf.put(src);
+
+ return len;
+ }
+
+ private class QMFMessageReference extends MessageReference<QMFMessage>
+ {
+ public QMFMessageReference(QMFMessage message)
+ {
+ super(message);
+ }
+
+ protected void onReference(QMFMessage message)
+ {
+
+ }
+
+ protected void onRelease(QMFMessage message)
+ {
+
+ }
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethod.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethod.java
new file mode 100644
index 0000000000..63e8fa6a1e
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethod.java
@@ -0,0 +1,157 @@
+/*
+ *
+ * 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.qmf;
+
+import org.apache.qpid.transport.codec.Encoder;
+import org.apache.qpid.transport.codec.BBDecoder;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.ArrayList;
+
+public abstract class QMFMethod<T extends QMFObject>
+{
+ private final LinkedHashMap<String,Object> _map = new LinkedHashMap<String,Object>();
+ private final List<Argument> _arguments = new ArrayList<Argument>();
+
+ private static final String NAME = "name";
+ private static final String TYPE = "type";
+ private static final String REF_PACKAGE = "refPackage";
+ private static final String REF_CLASS = "refClass";
+ private static final String UNIT = "unit";
+ private static final String MIN = "min";
+ private static final String MAX = "max";
+ private static final String MAX_LENGTH = "maxlen";
+ private static final String DESCRIPTION = "desc";
+ private static final String DEFAULT = "default";
+ private static final String DIRECTION = "dir";
+ private static final String ARG_COUNT = "argCount";
+
+
+
+ public enum Direction
+ {
+ I,
+ O,
+ IO;
+ }
+
+ public class Argument
+ {
+ private final LinkedHashMap<String,Object> _map = new LinkedHashMap<String,Object>();
+
+ public Argument(String name, QMFType type)
+ {
+ _map.put(NAME, name);
+ _map.put(TYPE, type.codeValue());
+ }
+
+ public void setRefPackage(String refPackage)
+ {
+ _map.put(REF_PACKAGE, refPackage);
+ }
+
+ public void setRefClass(String refClass)
+ {
+ _map.put(REF_CLASS, refClass);
+ }
+
+ public void setUnit(String unit)
+ {
+ _map.put(UNIT, unit);
+ }
+
+ public void setMax(Number max)
+ {
+ _map.put(MAX, max);
+ }
+
+ public void setMin(Number min)
+ {
+ _map.put(MIN, min);
+ }
+
+ public void setMaxLength(int len)
+ {
+ _map.put(MAX_LENGTH, len);
+ }
+
+ public void setDefault(Object dflt)
+ {
+ _map.put(DEFAULT, dflt);
+ }
+
+ public void setDescription(String desc)
+ {
+ _map.put(DESCRIPTION, desc);
+ }
+
+ public void setDirection(Direction direction)
+ {
+ _map.put(DIRECTION, direction.toString());
+ }
+
+ public void encode(Encoder encoder)
+ {
+ encoder.writeMap(_map);
+ }
+
+ public String getName()
+ {
+ return (String) _map.get(NAME);
+ }
+ }
+
+ public QMFMethod(String name, String description)
+ {
+ _map.put(NAME, name);
+ _map.put(ARG_COUNT, 0);
+ if(description != null)
+ {
+ _map.put(DESCRIPTION, description);
+ }
+
+ }
+
+ abstract public QMFMethodInvocation<T> parse(final BBDecoder decoder);
+
+ protected void addArgument(Argument arg)
+ {
+ _arguments.add(arg);
+ _map.put(ARG_COUNT, _arguments.size());
+ }
+
+
+ public void encode(Encoder encoder)
+ {
+ encoder.writeMap(_map);
+ for(Argument arg : _arguments)
+ {
+ arg.encode(encoder);
+ }
+ }
+
+ public String getName()
+ {
+ return (String) _map.get(NAME);
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodInvocation.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodInvocation.java
new file mode 100644
index 0000000000..5348c2783f
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodInvocation.java
@@ -0,0 +1,26 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.qmf;
+
+public interface QMFMethodInvocation<T extends QMFObject>
+{
+ QMFMethodResponseCommand execute(T obj, QMFMethodRequestCommand cmd);
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodRequestCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodRequestCommand.java
new file mode 100644
index 0000000000..cf27e4b970
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodRequestCommand.java
@@ -0,0 +1,88 @@
+/*
+ *
+ * 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.qmf;
+
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.queue.BaseQueue;
+import org.apache.qpid.AMQException;
+
+import java.util.UUID;
+import java.util.ArrayList;
+
+public class QMFMethodRequestCommand extends QMFCommand
+{
+ private QMFMethodInvocation _methodInstance;
+ private QMFObject _object;
+
+ public QMFMethodRequestCommand(final QMFCommandHeader header, final BBDecoder decoder, final QMFService qmfService)
+ {
+ super(header);
+ UUID objectId = decoder.readUuid();
+ String packageName = decoder.readStr8();
+ String className = decoder.readStr8();
+ byte[] hash = decoder.readBin128();
+ String methodName = decoder.readStr8();
+
+ QMFPackage qmfPackage = qmfService.getPackage(packageName);
+ QMFClass qmfClass = qmfPackage.getQMFClass(className);
+ _object = qmfService.getObjectById(qmfClass, objectId);
+ QMFMethod method = qmfClass.getMethod(methodName);
+ _methodInstance = method.parse(decoder);
+
+ }
+
+ public void process(final VirtualHost virtualHost, final ServerMessage message)
+ {
+ String exchangeName = message.getMessageHeader().getReplyToExchange();
+ String queueName = message.getMessageHeader().getReplyToRoutingKey();
+
+ QMFCommand[] commands = new QMFCommand[2];
+ commands[0] = _methodInstance.execute(_object, this);
+ commands[1] = new QMFCommandCompletionCommand(this);
+
+ Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName);
+
+ for(QMFCommand cmd : commands)
+ {
+ QMFMessage responseMessage = new QMFMessage(queueName, cmd);
+
+
+ ArrayList<? extends BaseQueue> queues = exchange.route(responseMessage);
+
+
+ for(BaseQueue q : queues)
+ {
+ try
+ {
+ q.enqueue(responseMessage);
+ }
+ catch (AMQException e)
+ {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ }
+ }
+ }
+
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodResponseCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodResponseCommand.java
new file mode 100644
index 0000000000..529b04ebdb
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodResponseCommand.java
@@ -0,0 +1,43 @@
+/*
+ *
+ * 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.qmf;
+
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.transport.codec.BBEncoder;
+
+public class QMFMethodResponseCommand extends QMFCommand
+{
+ public QMFMethodResponseCommand(final QMFMethodRequestCommand cmd)
+ {
+ super( new QMFCommandHeader(cmd.getHeader().getVersion(),
+ cmd.getHeader().getSeq(),
+ QMFOperation.METHOD_RESPONSE));
+ }
+
+ @Override
+ public void encode(final BBEncoder encoder)
+ {
+ super.encode(encoder);
+ encoder.writeUint32(0);
+ encoder.writeStr16("OK");
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFObject.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFObject.java
new file mode 100644
index 0000000000..d126717fc8
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFObject.java
@@ -0,0 +1,76 @@
+/*
+ *
+ * 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.qmf;
+
+import java.util.UUID;
+
+public abstract class QMFObject<C extends QMFClass, D extends QMFObject.Delegate>
+{
+ private long _deleteTime;
+
+ public interface Delegate
+ {
+ UUID getId();
+ long getCreateTime();
+ }
+
+
+ private D _delegate;
+
+ protected QMFObject(D delegate)
+ {
+ _delegate = delegate;
+ }
+
+ public D getDelegate()
+ {
+ return _delegate;
+ }
+
+ abstract public C getQMFClass();
+
+ public final UUID getId()
+ {
+ return _delegate.getId();
+ }
+
+ public final long getCreateTime()
+ {
+ return _delegate.getCreateTime();
+ }
+
+ public final void setDeleteTime()
+ {
+ _deleteTime = System.currentTimeMillis();
+ }
+
+ public final long getDeleteTime()
+ {
+ return _deleteTime;
+ }
+
+
+
+ abstract public QMFCommand asConfigInfoCmd(long sampleTime);
+ abstract public QMFCommand asInstrumentInfoCmd(long sampleTime);
+ abstract public QMFCommand asGetQueryResponseCmd(final QMFGetQueryCommand queryCommand, long sampleTime);
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFObjectClass.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFObjectClass.java
new file mode 100644
index 0000000000..fefdecb8d7
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFObjectClass.java
@@ -0,0 +1,44 @@
+/*
+ *
+ * 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.qmf;
+
+import java.util.List;
+
+public abstract class QMFObjectClass<T extends QMFObject, S extends QMFObject.Delegate> extends QMFClass
+{
+ public QMFObjectClass(String name,
+ byte[] schemaHash,
+ List<QMFProperty> properties,
+ List<QMFStatistic> statistics, List<QMFMethod> methods)
+ {
+ super(QMFClass.Type.OBJECT, name, schemaHash, properties, statistics, methods);
+ }
+
+ public QMFObjectClass(String name, byte[] schemaHash)
+ {
+ super(QMFClass.Type.OBJECT, name, schemaHash);
+ }
+
+
+ public abstract T newInstance(S delegate);
+
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFOperation.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFOperation.java
new file mode 100644
index 0000000000..6736b5d460
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFOperation.java
@@ -0,0 +1,67 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.qmf;
+
+public enum QMFOperation
+{
+
+
+ BROKER_REQUEST('B'),
+ BROKER_RESPONSE('b'), // This message contains a broker response, sent from the broker in response to a broker request message.
+ COMMAND_COMPLETION('z'), // This message is sent to indicate the completion of a request.
+ CLASS_QUERY('Q'), // Class query messages are used by a management console to request a list of schema classes that are known by the management broker.
+ CLASS_INDICATION('q'), // Sent by the management broker, a class indication notifies the peer of the existence of a schema class.
+ SCHEMA_REQUEST('S'), // Schema request messages are used to request the full schema details for a class.
+ SCHEMA_RESPONSE('s'), // Schema response message contain a full description of the schema for a class.
+ HEARTBEAT_INDEICATION('h'), // This message is published once per publish-interval. It can be used by a client to positively determine which objects did not change during the interval (since updates are not published for objects with no changes).
+ CONFIG_INDICATION('c'),
+ INSTRUMENTATION_INDICATION('i'),
+ GET_QUERY_RESPONSE('g'), // This message contains a content record. Content records contain the values of all properties or statistics in an object. Such records are broadcast on a periodic interval if 1) a change has been made in the value of one of the elements, or 2) if a new management client has bound a queue to the management exchange.
+ GET_QUERY('G'), // Sent by a management console, a get query requests that the management broker provide content indications for all objects that match the query criteria.
+ METHOD_REQUEST('M'), // This message contains a method request.
+ METHOD_RESPONSE('m'), // This message contains a method result.
+ PACKAGE_QUERY('P'), // This message contains a schema package query request, requesting that the broker dump the list of known packages
+ PACKAGE_INDICATION('p'), // This message contains a schema package indication, identifying a package known by the broker
+ AGENT_ATTACH_REUQEST('A'), // This message is sent by a remote agent when it wishes to attach to a management broker
+ AGENT_ATTACH_RESPONSE('a'), // The management broker sends this response if an attaching remote agent is permitted to join
+ CONSOLE_ADDED_INDICATION('x'), // This message is sent to all remote agents by the management broker when a new console binds to the management exchange
+ EVENT('e')
+ ;
+
+
+ private final char _opcode;
+
+ private static final QMFOperation[] OP_CODES = new QMFOperation[256];
+
+
+ QMFOperation(char opcode)
+ {
+ _opcode = opcode;
+ }
+
+
+ public char getOpcode()
+ {
+ return _opcode;
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackage.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackage.java
new file mode 100644
index 0000000000..681e64b799
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackage.java
@@ -0,0 +1,67 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.qmf;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.HashMap;
+
+public class QMFPackage
+{
+ private final String _name;
+ private final Map<String, QMFClass> _classes = new HashMap<String, QMFClass>();
+
+ public QMFPackage(String name)
+ {
+ _name = name;
+ }
+
+ public QMFPackage(String name, Collection<QMFClass> classes)
+ {
+ this(name);
+ setClasses(classes);
+ }
+
+ protected void setClasses(Collection<QMFClass> classes)
+ {
+ for(QMFClass qmfClass : classes)
+ {
+ qmfClass.setPackage(this);
+ _classes.put(qmfClass.getName(), qmfClass);
+ }
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public Collection<QMFClass> getClasses()
+ {
+ return _classes.values();
+ }
+
+ public QMFClass getQMFClass(String className)
+ {
+ return _classes.get(className);
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageIndicationCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageIndicationCommand.java
new file mode 100644
index 0000000000..7053b80655
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageIndicationCommand.java
@@ -0,0 +1,46 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.qmf;
+
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.transport.codec.BBEncoder;
+
+public class QMFPackageIndicationCommand extends QMFCommand
+{
+ private String _supportedSchema;
+
+ public QMFPackageIndicationCommand(QMFPackageQueryCommand qmfPackageQueryCommand, String supportedSchema)
+ {
+ super( new QMFCommandHeader(qmfPackageQueryCommand.getHeader().getVersion(),
+ qmfPackageQueryCommand.getHeader().getSeq(),
+ QMFOperation.PACKAGE_INDICATION));
+ _supportedSchema = supportedSchema;
+
+ }
+
+ public void encode(BBEncoder encoder)
+ {
+ super.encode(encoder);
+ encoder.writeStr8(_supportedSchema);
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageQueryCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageQueryCommand.java
new file mode 100644
index 0000000000..6defd088de
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageQueryCommand.java
@@ -0,0 +1,86 @@
+/*
+ *
+ * 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.qmf;
+
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.queue.BaseQueue;
+import org.apache.qpid.server.registry.IApplicationRegistry;
+import org.apache.qpid.AMQException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+public class QMFPackageQueryCommand extends QMFCommand
+{
+ public QMFPackageQueryCommand(QMFCommandHeader header, BBDecoder decoder)
+ {
+ super(header);
+ }
+
+ public void process(VirtualHost virtualHost, ServerMessage message)
+ {
+ String exchangeName = message.getMessageHeader().getReplyToExchange();
+ String routingKey = message.getMessageHeader().getReplyToRoutingKey();
+
+
+ IApplicationRegistry appRegistry = virtualHost.getApplicationRegistry();
+ QMFService service = appRegistry.getQMFService();
+
+ Collection<QMFPackage> supportedSchemas = service.getSupportedSchemas();
+
+ QMFCommand[] commands = new QMFCommand[ supportedSchemas.size() + 1 ];
+
+ int i = 0;
+ for(QMFPackage p : supportedSchemas)
+ {
+ commands[i++] = new QMFPackageIndicationCommand(this, p.getName());
+ }
+ commands[ commands.length - 1 ] = new QMFCommandCompletionCommand(this);
+
+
+ for(QMFCommand cmd : commands)
+ {
+
+ QMFMessage responseMessage = new QMFMessage(routingKey, cmd);
+
+ Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName);
+
+ ArrayList<? extends BaseQueue> queues = exchange.route(responseMessage);
+
+
+ for(BaseQueue q : queues)
+ {
+ try
+ {
+ q.enqueue(responseMessage);
+ }
+ catch (AMQException e)
+ {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ }
+ }
+ }
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFProperty.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFProperty.java
new file mode 100644
index 0000000000..5748722afe
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFProperty.java
@@ -0,0 +1,123 @@
+/*
+ *
+ * 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.qmf;
+
+import org.apache.qpid.transport.codec.Encoder;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+
+public class QMFProperty
+{
+ private final Map<String, Object> _map = new LinkedHashMap<String, Object>();
+ private static final String NAME = "name";
+ private static final String TYPE = "type";
+ private static final String ACCESS = "access";
+ private static final String INDEX = "index";
+ private static final String OPTIONAL = "optional";
+ private static final String REF_PACKAGE = "refPackage";
+ private static final String REF_CLASS = "refClass";
+ private static final String UNIT = "unit";
+ private static final String MIN = "min";
+ private static final String MAX = "max";
+ private static final String MAX_LENGTH = "maxlen";
+ private static final String DESCRIPTION = "desc";
+
+
+ public static enum AccessCode
+ {
+ RC,
+ RW,
+ RO;
+
+ public int codeValue()
+ {
+ return ordinal()+1;
+ }
+ }
+
+ public QMFProperty(String name, QMFType type, AccessCode accessCode, boolean index, boolean optional)
+ {
+ _map.put(NAME, name);
+ _map.put(TYPE, type.codeValue());
+ _map.put(ACCESS, accessCode.codeValue());
+ _map.put(INDEX, index ? 1 : 0);
+ _map.put(OPTIONAL, optional ? 1 :0);
+ }
+
+
+ public void setQMFClass(QMFClass qmfClass)
+ {
+ /* _map.put(REF_CLASS, qmfClass.getName());
+ _map.put(REF_PACKAGE, qmfClass.getPackage().getName());*/
+ }
+
+ public void setReferencedClass(String refClass)
+ {
+ _map.put(REF_CLASS, refClass);
+ }
+
+ public void setReferencedPackage(String refPackage)
+ {
+ _map.put(REF_CLASS, refPackage);
+ }
+
+
+ public String getName()
+ {
+ return (String) _map.get(NAME);
+ }
+
+
+ public void setUnit(String unit)
+ {
+ _map.put(UNIT, unit);
+ }
+
+ public void setMin(Number min)
+ {
+ _map.put(MIN, min);
+ }
+
+ public void setMax(Number max)
+ {
+ _map.put(MAX, max);
+ }
+
+ public void setMaxLength(int maxlen)
+ {
+ _map.put(MAX_LENGTH, maxlen);
+ }
+
+
+ public void setDescription(String description)
+ {
+ _map.put(DESCRIPTION, description);
+ }
+
+ public void encode(Encoder encoder)
+ {
+ encoder.writeMap(_map);
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaRequestCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaRequestCommand.java
new file mode 100644
index 0000000000..3141676f10
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaRequestCommand.java
@@ -0,0 +1,88 @@
+/*
+ *
+ * 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.qmf;
+
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.server.registry.IApplicationRegistry;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.queue.BaseQueue;
+import org.apache.qpid.AMQException;
+
+import java.util.Collection;
+import java.util.ArrayList;
+
+public class QMFSchemaRequestCommand extends QMFCommand
+{
+ private final String _packageName;
+ private final String _className;
+ private final byte[] _hash;
+
+ public QMFSchemaRequestCommand(QMFCommandHeader header, BBDecoder decoder)
+ {
+ super(header);
+ _packageName = decoder.readStr8();
+ _className = decoder.readStr8();
+ _hash = decoder.readBin128();
+ }
+
+ public void process(VirtualHost virtualHost, ServerMessage message)
+ {
+ String exchangeName = message.getMessageHeader().getReplyToExchange();
+ String routingKey = message.getMessageHeader().getReplyToRoutingKey();
+
+ IApplicationRegistry appRegistry = virtualHost.getApplicationRegistry();
+ QMFService service = appRegistry.getQMFService();
+
+ QMFPackage qmfPackage = service.getPackage(_packageName);
+ QMFClass qmfClass = qmfPackage.getQMFClass( _className );
+
+ QMFCommand[] commands = new QMFCommand[2];
+ commands[0] = new QMFSchemaResponseCommand(this, qmfClass);
+ commands[ 1 ] = new QMFCommandCompletionCommand(this);
+
+
+
+ Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName);
+
+ for(QMFCommand cmd : commands)
+ {
+ QMFMessage responseMessage = new QMFMessage(routingKey, cmd);
+
+
+ ArrayList<? extends BaseQueue> queues = exchange.route(responseMessage);
+
+ for(BaseQueue q : queues)
+ {
+ try
+ {
+ q.enqueue(responseMessage);
+ }
+ catch (AMQException e)
+ {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ }
+ }
+ }
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaResponseCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaResponseCommand.java
new file mode 100644
index 0000000000..fea2430130
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaResponseCommand.java
@@ -0,0 +1,83 @@
+/*
+ *
+ * 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.qmf;
+
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.transport.codec.BBEncoder;
+
+import java.util.Collection;
+
+public class QMFSchemaResponseCommand extends QMFCommand
+{
+ private final QMFClass _qmfClass;
+
+
+ public QMFSchemaResponseCommand(QMFSchemaRequestCommand qmfSchemaRequestCommand, QMFClass qmfClass)
+ {
+ super(new QMFCommandHeader(qmfSchemaRequestCommand.getHeader().getVersion(),
+ qmfSchemaRequestCommand.getHeader().getSeq(),
+ QMFOperation.SCHEMA_RESPONSE));
+ _qmfClass = qmfClass;
+ }
+
+ @Override
+ public void encode(BBEncoder encoder)
+ {
+ super.encode(encoder);
+ encoder.writeUint8(_qmfClass.getType().getValue());
+ encoder.writeStr8(_qmfClass.getPackage().getName());
+ encoder.writeStr8(_qmfClass.getName());
+ encoder.writeBin128(_qmfClass.getSchemaHash());
+
+ Collection<QMFProperty> props = _qmfClass.getProperties();
+ Collection<QMFStatistic> stats = _qmfClass.getStatistics();
+ Collection<QMFMethod> methods = _qmfClass.getMethods();
+
+ encoder.writeUint16(props.size());
+ if(_qmfClass.getType() == QMFClass.Type.OBJECT)
+ {
+ encoder.writeUint16(stats.size());
+ encoder.writeUint16(methods.size());
+ }
+
+ for(QMFProperty prop : props)
+ {
+ prop.encode(encoder);
+ }
+
+ if(_qmfClass.getType() == QMFClass.Type.OBJECT)
+ {
+
+ for(QMFStatistic stat : stats)
+ {
+ stat.encode(encoder);
+ }
+
+ for(QMFMethod method : methods)
+ {
+ method.encode(encoder);
+ }
+ }
+
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java
new file mode 100644
index 0000000000..6a1c24b5a7
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java
@@ -0,0 +1,1583 @@
+/*
+ *
+ * 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.qmf;
+
+import org.apache.qpid.qmf.schema.BrokerSchema;
+import org.apache.qpid.server.configuration.*;
+import org.apache.qpid.server.registry.IApplicationRegistry;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+public class QMFService implements ConfigStore.ConfigEventListener
+{
+
+
+ private IApplicationRegistry _applicationRegistry;
+ private ConfigStore _configStore;
+
+
+ private final Map<String, QMFPackage> _supportedSchemas = new HashMap<String, QMFPackage>();
+ private static final Map<String, ConfigObjectType> _qmfClassMapping = new HashMap<String, ConfigObjectType>();
+
+ static
+ {
+ _qmfClassMapping.put("system", SystemConfigType.getInstance());
+ _qmfClassMapping.put("broker", BrokerConfigType.getInstance());
+ _qmfClassMapping.put("vhost", VirtualHostConfigType.getInstance());
+ _qmfClassMapping.put("exchange", ExchangeConfigType.getInstance());
+ _qmfClassMapping.put("queue", QueueConfigType.getInstance());
+ _qmfClassMapping.put("binding", BindingConfigType.getInstance());
+ _qmfClassMapping.put("connection", ConnectionConfigType.getInstance());
+ _qmfClassMapping.put("session", SessionConfigType.getInstance());
+ _qmfClassMapping.put("subscription", SubscriptionConfigType.getInstance());
+ _qmfClassMapping.put("link", LinkConfigType.getInstance());
+ _qmfClassMapping.put("bridge", BridgeConfigType.getInstance());
+ }
+
+ private final Map<ConfigObjectType, ConfigObjectAdapter> _adapterMap =
+ new HashMap<ConfigObjectType, ConfigObjectAdapter>();
+ private final Map<ConfigObjectType,QMFClass> _classMap =
+ new HashMap<ConfigObjectType,QMFClass>();
+
+
+ private final ConcurrentHashMap<QMFClass,ConcurrentHashMap<ConfiguredObject, QMFObject>> _managedObjects =
+ new ConcurrentHashMap<QMFClass,ConcurrentHashMap<ConfiguredObject, QMFObject>>();
+
+ private final ConcurrentHashMap<QMFClass,ConcurrentHashMap<UUID, QMFObject>> _managedObjectsById =
+ new ConcurrentHashMap<QMFClass,ConcurrentHashMap<UUID, QMFObject>>();
+
+ private static final BrokerSchema PACKAGE = BrokerSchema.getPackage();
+
+ public static interface Listener
+ {
+ public void objectCreated(QMFObject obj);
+ public void objectDeleted(QMFObject obj);
+ }
+
+ private final CopyOnWriteArrayList<Listener> _listeners = new CopyOnWriteArrayList<Listener>();
+
+ abstract class ConfigObjectAdapter<Q extends QMFObject<S,D>, S extends QMFObjectClass<Q,D>, D extends QMFObject.Delegate, T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T,C>>
+ {
+ private final T _type;
+ private final S _qmfClass;
+
+
+ protected ConfigObjectAdapter(final T type, final S qmfClass)
+ {
+ _type = type;
+ _qmfClass = qmfClass;
+ _adapterMap.put(type,this);
+ _classMap.put(type,qmfClass);
+ }
+
+ public T getType()
+ {
+ return _type;
+ }
+
+ public S getQMFClass()
+ {
+ return _qmfClass;
+ }
+
+ protected final Q newInstance(D delegate)
+ {
+ return _qmfClass.newInstance(delegate);
+ }
+
+ public abstract Q createQMFObject(C configObject);
+ }
+
+ private ConfigObjectAdapter<BrokerSchema.SystemObject,
+ BrokerSchema.SystemClass,
+ BrokerSchema.SystemDelegate,
+ SystemConfigType,
+ SystemConfig> _systemObjectAdapter =
+ new ConfigObjectAdapter<BrokerSchema.SystemObject,
+ BrokerSchema.SystemClass,
+ BrokerSchema.SystemDelegate,
+ SystemConfigType,
+ SystemConfig>(SystemConfigType.getInstance(),
+ PACKAGE.getQMFClassInstance(BrokerSchema.SystemClass.class))
+ {
+
+
+ public BrokerSchema.SystemObject createQMFObject(
+ final SystemConfig configObject)
+ {
+ return newInstance(new SystemDelegate(configObject));
+ }
+ };
+
+ private ConfigObjectAdapter<BrokerSchema.BrokerObject,
+ BrokerSchema.BrokerClass,
+ BrokerSchema.BrokerDelegate,
+ BrokerConfigType,
+ BrokerConfig> _brokerObjectAdapter =
+ new ConfigObjectAdapter<BrokerSchema.BrokerObject,
+ BrokerSchema.BrokerClass,
+ BrokerSchema.BrokerDelegate,
+ BrokerConfigType,
+ BrokerConfig>(BrokerConfigType.getInstance(),
+ PACKAGE.getQMFClassInstance(BrokerSchema.BrokerClass.class))
+ {
+
+ public BrokerSchema.BrokerObject createQMFObject(
+ final BrokerConfig configObject)
+ {
+ return newInstance(new BrokerDelegate(configObject));
+ }
+ };
+
+ private ConfigObjectAdapter<BrokerSchema.VhostObject,
+ BrokerSchema.VhostClass,
+ BrokerSchema.VhostDelegate,
+ VirtualHostConfigType,
+ VirtualHostConfig> _vhostObjectAdapter =
+ new ConfigObjectAdapter<BrokerSchema.VhostObject,
+ BrokerSchema.VhostClass,
+ BrokerSchema.VhostDelegate,
+ VirtualHostConfigType,
+ VirtualHostConfig>(VirtualHostConfigType.getInstance(),
+ PACKAGE.getQMFClassInstance(BrokerSchema.VhostClass.class))
+ {
+
+ public BrokerSchema.VhostObject createQMFObject(
+ final VirtualHostConfig configObject)
+ {
+ return newInstance(new VhostDelegate(configObject));
+ }
+ };
+
+
+ private ConfigObjectAdapter<BrokerSchema.ExchangeObject,
+ BrokerSchema.ExchangeClass,
+ BrokerSchema.ExchangeDelegate,
+ ExchangeConfigType,
+ ExchangeConfig> _exchangeObjectAdapter =
+ new ConfigObjectAdapter<BrokerSchema.ExchangeObject,
+ BrokerSchema.ExchangeClass,
+ BrokerSchema.ExchangeDelegate,
+ ExchangeConfigType,
+ ExchangeConfig>(ExchangeConfigType.getInstance(),
+ PACKAGE.getQMFClassInstance(BrokerSchema.ExchangeClass.class))
+ {
+
+ public BrokerSchema.ExchangeObject createQMFObject(
+ final ExchangeConfig configObject)
+ {
+ return newInstance(new ExchangeDelegate(configObject));
+ }
+ };
+
+
+ private ConfigObjectAdapter<BrokerSchema.QueueObject,
+ BrokerSchema.QueueClass,
+ BrokerSchema.QueueDelegate,
+ QueueConfigType,
+ QueueConfig> _queueObjectAdapter =
+ new ConfigObjectAdapter<BrokerSchema.QueueObject,
+ BrokerSchema.QueueClass,
+ BrokerSchema.QueueDelegate,
+ QueueConfigType,
+ QueueConfig>(QueueConfigType.getInstance(),
+ PACKAGE.getQMFClassInstance(BrokerSchema.QueueClass.class))
+ {
+
+ public BrokerSchema.QueueObject createQMFObject(
+ final QueueConfig configObject)
+ {
+ return newInstance(new QueueDelegate(configObject));
+ }
+ };
+
+
+ private ConfigObjectAdapter<BrokerSchema.BindingObject,
+ BrokerSchema.BindingClass,
+ BrokerSchema.BindingDelegate,
+ BindingConfigType,
+ BindingConfig> _bindingObjectAdapter =
+ new ConfigObjectAdapter<BrokerSchema.BindingObject,
+ BrokerSchema.BindingClass,
+ BrokerSchema.BindingDelegate,
+ BindingConfigType,
+ BindingConfig>(BindingConfigType.getInstance(),
+ PACKAGE.getQMFClassInstance(BrokerSchema.BindingClass.class))
+ {
+
+ public BrokerSchema.BindingObject createQMFObject(
+ final BindingConfig configObject)
+ {
+ return newInstance(new BindingDelegate(configObject));
+ }
+ };
+
+
+ private ConfigObjectAdapter<BrokerSchema.ConnectionObject,
+ BrokerSchema.ConnectionClass,
+ BrokerSchema.ConnectionDelegate,
+ ConnectionConfigType,
+ ConnectionConfig> _connectionObjectAdapter =
+ new ConfigObjectAdapter<BrokerSchema.ConnectionObject,
+ BrokerSchema.ConnectionClass,
+ BrokerSchema.ConnectionDelegate,
+ ConnectionConfigType,
+ ConnectionConfig>(ConnectionConfigType.getInstance(),
+ PACKAGE.getQMFClassInstance(BrokerSchema.ConnectionClass.class))
+ {
+
+ public BrokerSchema.ConnectionObject createQMFObject(
+ final ConnectionConfig configObject)
+ {
+ return newInstance(new ConnectionDelegate(configObject));
+ }
+ };
+
+
+ private ConfigObjectAdapter<BrokerSchema.SessionObject,
+ BrokerSchema.SessionClass,
+ BrokerSchema.SessionDelegate,
+ SessionConfigType,
+ SessionConfig> _sessionObjectAdapter =
+ new ConfigObjectAdapter<BrokerSchema.SessionObject,
+ BrokerSchema.SessionClass,
+ BrokerSchema.SessionDelegate,
+ SessionConfigType,
+ SessionConfig>(SessionConfigType.getInstance(),
+ PACKAGE.getQMFClassInstance(BrokerSchema.SessionClass.class))
+ {
+
+ public BrokerSchema.SessionObject createQMFObject(
+ final SessionConfig configObject)
+ {
+ return newInstance(new SessionDelegate(configObject));
+ }
+ };
+
+ private ConfigObjectAdapter<BrokerSchema.SubscriptionObject,
+ BrokerSchema.SubscriptionClass,
+ BrokerSchema.SubscriptionDelegate,
+ SubscriptionConfigType,
+ SubscriptionConfig> _subscriptionObjectAdapter =
+ new ConfigObjectAdapter<BrokerSchema.SubscriptionObject,
+ BrokerSchema.SubscriptionClass,
+ BrokerSchema.SubscriptionDelegate,
+ SubscriptionConfigType,
+ SubscriptionConfig>(SubscriptionConfigType.getInstance(),
+ PACKAGE.getQMFClassInstance(BrokerSchema.SubscriptionClass.class))
+ {
+
+ public BrokerSchema.SubscriptionObject createQMFObject(
+ final SubscriptionConfig configObject)
+ {
+ return newInstance(new SubscriptionDelegate(configObject));
+ }
+ };
+
+
+ private ConfigObjectAdapter<BrokerSchema.LinkObject,
+ BrokerSchema.LinkClass,
+ BrokerSchema.LinkDelegate,
+ LinkConfigType,
+ LinkConfig> _linkObjectAdapter =
+ new ConfigObjectAdapter<BrokerSchema.LinkObject,
+ BrokerSchema.LinkClass,
+ BrokerSchema.LinkDelegate,
+ LinkConfigType,
+ LinkConfig>(LinkConfigType.getInstance(),
+ PACKAGE.getQMFClassInstance(BrokerSchema.LinkClass.class))
+ {
+
+ public BrokerSchema.LinkObject createQMFObject(
+ final LinkConfig configObject)
+ {
+ return newInstance(new LinkDelegate(configObject));
+ }
+ };
+
+
+ private ConfigObjectAdapter<BrokerSchema.BridgeObject,
+ BrokerSchema.BridgeClass,
+ BrokerSchema.BridgeDelegate,
+ BridgeConfigType,
+ BridgeConfig> _bridgeObjectAdapter =
+ new ConfigObjectAdapter<BrokerSchema.BridgeObject,
+ BrokerSchema.BridgeClass,
+ BrokerSchema.BridgeDelegate,
+ BridgeConfigType,
+ BridgeConfig>(BridgeConfigType.getInstance(),
+ PACKAGE.getQMFClassInstance(BrokerSchema.BridgeClass.class))
+ {
+
+ public BrokerSchema.BridgeObject createQMFObject(
+ final BridgeConfig configObject)
+ {
+ return newInstance(new BridgeDelegate(configObject));
+ }
+ };
+
+
+
+ public QMFService(ConfigStore configStore, IApplicationRegistry applicationRegistry)
+ {
+ _configStore = configStore;
+ _applicationRegistry = applicationRegistry;
+ registerSchema(PACKAGE);
+
+ for(ConfigObjectType v : _qmfClassMapping.values())
+ {
+ configStore.addConfigEventListener(v, this);
+ }
+ init();
+ }
+
+ public void close()
+ {
+ _managedObjects.clear();
+ _managedObjectsById.clear();
+ _classMap.clear();
+ _adapterMap.clear();
+ _supportedSchemas.clear();
+ }
+
+
+ public void registerSchema(QMFPackage qmfPackage)
+ {
+ _supportedSchemas.put(qmfPackage.getName(), qmfPackage);
+ }
+
+
+ public Collection<QMFPackage> getSupportedSchemas()
+ {
+ return _supportedSchemas.values();
+ }
+
+ public QMFPackage getPackage(String aPackage)
+ {
+ return _supportedSchemas.get(aPackage);
+ }
+
+ public void onEvent(final ConfiguredObject object, final ConfigStore.Event evt)
+ {
+
+ switch (evt)
+ {
+ case CREATED:
+ manageObject(object);
+ break;
+
+ case DELETED:
+ unmanageObject(object);
+ break;
+ }
+ }
+
+ public QMFObject getObjectById(QMFClass qmfclass, UUID id)
+ {
+ ConcurrentHashMap<UUID, QMFObject> map = _managedObjectsById.get(qmfclass);
+ if(map != null)
+ {
+ return map.get(id);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ private void unmanageObject(final ConfiguredObject object)
+ {
+ final QMFClass qmfClass = _classMap.get(object.getConfigType());
+
+ ConcurrentHashMap<ConfiguredObject, QMFObject> classObjects = _managedObjects.get(qmfClass);
+ if(classObjects != null)
+ {
+ QMFObject qmfObject = classObjects.remove(object);
+ if(qmfObject != null)
+ {
+ _managedObjectsById.get(qmfClass).remove(object.getId());
+ objectRemoved(qmfObject);
+ }
+ }
+ }
+
+ private void manageObject(final ConfiguredObject object)
+ {
+ ConfigObjectAdapter adapter = _adapterMap.get(object.getConfigType());
+ QMFObject qmfObject = adapter.createQMFObject(object);
+ final QMFClass qmfClass = qmfObject.getQMFClass();
+ ConcurrentHashMap<ConfiguredObject, QMFObject> classObjects = _managedObjects.get(qmfClass);
+
+ if(classObjects == null)
+ {
+ classObjects = new ConcurrentHashMap<ConfiguredObject, QMFObject>();
+ if(_managedObjects.putIfAbsent(qmfClass, classObjects) != null)
+ {
+ classObjects = _managedObjects.get(qmfClass);
+ }
+ }
+
+ ConcurrentHashMap<UUID, QMFObject> classObjectsById = _managedObjectsById.get(qmfClass);
+ if(classObjectsById == null)
+ {
+ classObjectsById = new ConcurrentHashMap<UUID, QMFObject>();
+ if(_managedObjectsById.putIfAbsent(qmfClass, classObjectsById) != null)
+ {
+ classObjectsById = _managedObjectsById.get(qmfClass);
+ }
+ }
+
+ classObjectsById.put(object.getId(),qmfObject);
+
+ if(classObjects.putIfAbsent(object, qmfObject) == null);
+ {
+ objectAdded(qmfObject);
+ }
+ }
+
+ private void objectRemoved(final QMFObject qmfObject)
+ {
+ qmfObject.setDeleteTime();
+ for(Listener l : _listeners)
+ {
+ l.objectDeleted(qmfObject);
+ }
+ }
+
+ private void objectAdded(final QMFObject qmfObject)
+ {
+ for(Listener l : _listeners)
+ {
+ l.objectCreated(qmfObject);
+ }
+ }
+
+ public void addListener(Listener l)
+ {
+ _listeners.add(l);
+ }
+
+ public void removeListener(Listener l)
+ {
+ _listeners.remove(l);
+ }
+
+
+ private void init()
+ {
+ for(QMFClass qmfClass : PACKAGE.getClasses())
+ {
+ ConfigObjectType configType = getConfigType(qmfClass);
+ if(configType != null)
+ {
+ Collection<ConfiguredObject> objects = _configStore.getConfiguredObjects(configType);
+ for(ConfiguredObject object : objects)
+ {
+ manageObject(object);
+ }
+ }
+ }
+ }
+
+ public Collection<QMFObject> getObjects(QMFClass qmfClass)
+ {
+ ConcurrentHashMap<ConfiguredObject, QMFObject> classObjects = _managedObjects.get(qmfClass);
+ if(classObjects != null)
+ {
+ return classObjects.values();
+ }
+ else
+ {
+ return Collections.EMPTY_SET;
+ }
+ }
+
+ private QMFObject adapt(final ConfiguredObject object)
+ {
+ if(object == null)
+ {
+ return null;
+ }
+
+ QMFClass qmfClass = _classMap.get(object.getConfigType());
+ ConcurrentHashMap<ConfiguredObject, QMFObject> classObjects = _managedObjects.get(qmfClass);
+ if(classObjects != null)
+ {
+ QMFObject qmfObject = classObjects.get(object);
+ if(qmfObject != null)
+ {
+ return qmfObject;
+ }
+ }
+
+ return _adapterMap.get(object.getConfigType()).createQMFObject(object);
+ }
+
+ private ConfigObjectType getConfigType(final QMFClass qmfClass)
+ {
+ return _qmfClassMapping.get(qmfClass.getName());
+ }
+
+ private static class SystemDelegate implements BrokerSchema.SystemDelegate
+ {
+ private final SystemConfig _obj;
+
+ public SystemDelegate(final SystemConfig obj)
+ {
+ _obj = obj;
+ }
+
+ public UUID getSystemId()
+ {
+ return _obj.getId();
+ }
+
+ public String getOsName()
+ {
+ return _obj.getOperatingSystemName();
+ }
+
+ public String getNodeName()
+ {
+ return _obj.getNodeName();
+ }
+
+ public String getRelease()
+ {
+ return _obj.getOSRelease();
+ }
+
+ public String getVersion()
+ {
+ return _obj.getOSVersion();
+ }
+
+ public String getMachine()
+ {
+ return _obj.getOSArchitecture();
+ }
+
+ public UUID getId()
+ {
+ return _obj.getId();
+ }
+
+ public long getCreateTime()
+ {
+ return _obj.getCreateTime();
+ }
+ }
+
+ private class BrokerDelegate implements BrokerSchema.BrokerDelegate
+ {
+ private final BrokerConfig _obj;
+
+ public BrokerDelegate(final BrokerConfig obj)
+ {
+ _obj = obj;
+ }
+
+ public BrokerSchema.SystemObject getSystemRef()
+ {
+ return (BrokerSchema.SystemObject) adapt(_obj.getSystem());
+ }
+
+ public Integer getPort()
+ {
+ return _obj.getPort();
+ }
+
+ public Integer getWorkerThreads()
+ {
+ return _obj.getWorkerThreads();
+ }
+
+ public Integer getMaxConns()
+ {
+ return _obj.getMaxConnections();
+ }
+
+ public Integer getConnBacklog()
+ {
+ return _obj.getConnectionBacklogLimit();
+ }
+
+ public Long getStagingThreshold()
+ {
+ return _obj.getStagingThreshold();
+ }
+
+ public Integer getMgmtPubInterval()
+ {
+ return _obj.getManagementPublishInterval();
+ }
+
+ public String getVersion()
+ {
+ return _obj.getVersion();
+ }
+
+ public String getDataDir()
+ {
+ return _obj.getDataDirectory();
+ }
+
+ public Long getUptime()
+ {
+ return (System.currentTimeMillis() - _obj.getCreateTime()) * 1000000L;
+ }
+
+ public BrokerSchema.BrokerClass.EchoMethodResponseCommand echo(final BrokerSchema.BrokerClass.EchoMethodResponseCommandFactory factory,
+ final Long sequence,
+ final String body)
+ {
+ return factory.createResponseCommand(sequence, body);
+ }
+
+ public BrokerSchema.BrokerClass.ConnectMethodResponseCommand connect(final BrokerSchema.BrokerClass.ConnectMethodResponseCommandFactory factory,
+ final String host,
+ final Long port,
+ final Boolean durable,
+ final String authMechanism,
+ final String username,
+ final String password,
+ final String transport)
+ {
+ _obj.createBrokerConnection(transport, host, port.intValue(), durable, authMechanism, username, password);
+
+ return factory.createResponseCommand();
+ }
+
+ public BrokerSchema.BrokerClass.QueueMoveMessagesMethodResponseCommand queueMoveMessages(final BrokerSchema.BrokerClass.QueueMoveMessagesMethodResponseCommandFactory factory,
+ final String srcQueue,
+ final String destQueue,
+ final Long qty)
+ {
+ // todo
+ throw new UnsupportedOperationException();
+ }
+
+ public UUID getId()
+ {
+ return _obj.getId();
+ }
+
+ public long getCreateTime()
+ {
+ return _obj.getCreateTime();
+ }
+ }
+
+ private class VhostDelegate implements BrokerSchema.VhostDelegate
+ {
+ private final VirtualHostConfig _obj;
+
+ public VhostDelegate(final VirtualHostConfig obj)
+ {
+ _obj = obj;
+ }
+
+ public BrokerSchema.BrokerObject getBrokerRef()
+ {
+ return (BrokerSchema.BrokerObject) adapt(_obj.getBroker());
+ }
+
+ public String getName()
+ {
+ return _obj.getName();
+ }
+
+ public String getFederationTag()
+ {
+ return _obj.getFederationTag();
+ }
+
+ public UUID getId()
+ {
+ return _obj.getId();
+ }
+
+ public long getCreateTime()
+ {
+ return _obj.getCreateTime();
+ }
+ }
+
+ private class ExchangeDelegate implements BrokerSchema.ExchangeDelegate
+ {
+ private final ExchangeConfig _obj;
+
+ public ExchangeDelegate(final ExchangeConfig obj)
+ {
+ _obj = obj;
+ }
+
+ public BrokerSchema.VhostObject getVhostRef()
+ {
+ return (BrokerSchema.VhostObject) adapt(_obj.getVirtualHost());
+ }
+
+ public String getName()
+ {
+ return _obj.getName();
+ }
+
+ public String getType()
+ {
+ return _obj.getType().getName().toString();
+ }
+
+ public Boolean getDurable()
+ {
+ return _obj.isDurable();
+ }
+
+ public Boolean getAutoDelete()
+ {
+ return _obj.isAutoDelete();
+ }
+
+ public BrokerSchema.ExchangeObject getAltExchange()
+ {
+ if(_obj.getAlternateExchange() != null)
+ {
+ return (BrokerSchema.ExchangeObject) adapt(_obj.getAlternateExchange());
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public Map getArguments()
+ {
+ return _obj.getArguments();
+ }
+
+ public Long getProducerCount()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getProducerCountHigh()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getProducerCountLow()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getBindingCount()
+ {
+ return _obj.getBindingCount();
+ }
+
+ public Long getBindingCountHigh()
+ {
+ return _obj.getBindingCountHigh();
+ }
+
+ public Long getBindingCountLow()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getMsgReceives()
+ {
+ return _obj.getMsgReceives();
+ }
+
+ public Long getMsgDrops()
+ {
+ return getMsgReceives() - getMsgRoutes();
+ }
+
+ public Long getMsgRoutes()
+ {
+ return _obj.getMsgRoutes();
+ }
+
+ public Long getByteReceives()
+ {
+ return _obj.getByteReceives();
+ }
+
+ public Long getByteDrops()
+ {
+ return getByteReceives() - getByteRoutes();
+ }
+
+ public Long getByteRoutes()
+ {
+ return _obj.getByteRoutes();
+ }
+
+ public UUID getId()
+ {
+ return _obj.getId();
+ }
+
+ public long getCreateTime()
+ {
+ return _obj.getCreateTime();
+ }
+ }
+
+ private class QueueDelegate implements BrokerSchema.QueueDelegate
+ {
+ private final QueueConfig _obj;
+
+ public QueueDelegate(final QueueConfig obj)
+ {
+ _obj = obj;
+ }
+
+ public BrokerSchema.VhostObject getVhostRef()
+ {
+ return (BrokerSchema.VhostObject) adapt(_obj.getVirtualHost());
+ }
+
+ public String getName()
+ {
+ return _obj.getName();
+ }
+
+ public Boolean getDurable()
+ {
+ return _obj.isDurable();
+ }
+
+ public Boolean getAutoDelete()
+ {
+ return _obj.isAutoDelete();
+ }
+
+ public Boolean getExclusive()
+ {
+ return _obj.isExclusive();
+ }
+
+ public BrokerSchema.ExchangeObject getAltExchange()
+ {
+ if(_obj.getAlternateExchange() != null)
+ {
+ return (BrokerSchema.ExchangeObject) adapt(_obj.getAlternateExchange());
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public Long getMsgTotalEnqueues()
+ {
+ return _obj.getReceivedMessageCount();
+ }
+
+ public Long getMsgTotalDequeues()
+ {
+ return _obj.getMessageDequeueCount();
+ }
+
+ public Long getMsgTxnEnqueues()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getMsgTxnDequeues()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getMsgPersistEnqueues()
+ {
+ return _obj.getPersistentMsgEnqueues();
+ }
+
+ public Long getMsgPersistDequeues()
+ {
+ return _obj.getPersistentMsgDequeues();
+ }
+
+ public Long getMsgDepth()
+ {
+ return (long) _obj.getMessageCount();
+ }
+
+ public Long getByteDepth()
+ {
+ return _obj.getQueueDepth();
+ }
+
+ public Long getByteTotalEnqueues()
+ {
+ return _obj.getTotalEnqueueSize();
+ }
+
+ public Long getByteTotalDequeues()
+ {
+ return _obj.getTotalDequeueSize();
+ }
+
+ public Long getByteTxnEnqueues()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getByteTxnDequeues()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getBytePersistEnqueues()
+ {
+ return _obj.getPersistentByteEnqueues();
+ }
+
+ public Long getBytePersistDequeues()
+ {
+ return _obj.getPersistentByteDequeues();
+ }
+
+ public Long getConsumerCount()
+ {
+ return (long) _obj.getConsumerCount();
+ }
+
+ public Long getConsumerCountHigh()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getConsumerCountLow()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getBindingCount()
+ {
+ return (long) _obj.getBindingCount();
+ }
+
+ public Long getBindingCountHigh()
+ {
+ return (long) _obj.getBindingCountHigh();
+ }
+
+ public Long getBindingCountLow()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getUnackedMessages()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getUnackedMessagesHigh()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getUnackedMessagesLow()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getMessageLatencySamples()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getMessageLatencyMin()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getMessageLatencyMax()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getMessageLatencyAverage()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public BrokerSchema.QueueClass.PurgeMethodResponseCommand purge(final BrokerSchema.QueueClass.PurgeMethodResponseCommandFactory factory,
+ final Long request)
+ {
+ _obj.purge(request);
+ return factory.createResponseCommand();
+ }
+
+ public Map getArguments()
+ {
+ return _obj.getArguments();
+ }
+
+ public UUID getId()
+ {
+ return _obj.getId();
+ }
+
+ public long getCreateTime()
+ {
+ return _obj.getCreateTime();
+ }
+ }
+
+ private class BindingDelegate implements BrokerSchema.BindingDelegate
+ {
+ private final BindingConfig _obj;
+
+ public BindingDelegate(final BindingConfig obj)
+ {
+ _obj = obj;
+ }
+
+ public BrokerSchema.ExchangeObject getExchangeRef()
+ {
+ return (BrokerSchema.ExchangeObject) adapt(_obj.getExchange());
+ }
+
+ public BrokerSchema.QueueObject getQueueRef()
+ {
+ return (BrokerSchema.QueueObject) adapt(_obj.getQueue());
+ }
+
+ public String getBindingKey()
+ {
+ return _obj.getBindingKey();
+ }
+
+ public Map getArguments()
+ {
+ return _obj.getArguments();
+ }
+
+ public String getOrigin()
+ {
+ return _obj.getOrigin();
+ }
+
+ public Long getMsgMatched()
+ {
+ // TODO
+ return _obj.getMatches();
+ }
+
+ public UUID getId()
+ {
+ return _obj.getId();
+ }
+
+ public long getCreateTime()
+ {
+ return _obj.getCreateTime();
+ }
+ }
+
+ private class ConnectionDelegate implements BrokerSchema.ConnectionDelegate
+ {
+ private final ConnectionConfig _obj;
+
+ public ConnectionDelegate(final ConnectionConfig obj)
+ {
+ _obj = obj;
+ }
+
+ public BrokerSchema.VhostObject getVhostRef()
+ {
+ return (BrokerSchema.VhostObject) adapt(_obj.getVirtualHost());
+ }
+
+ public String getAddress()
+ {
+ return _obj.getAddress();
+ }
+
+ public Boolean getIncoming()
+ {
+ return _obj.isIncoming();
+ }
+
+ public Boolean getSystemConnection()
+ {
+ return _obj.isSystemConnection();
+ }
+
+ public Boolean getFederationLink()
+ {
+ return _obj.isFederationLink();
+ }
+
+ public String getAuthIdentity()
+ {
+ return _obj.getAuthId();
+ }
+
+ public String getRemoteProcessName()
+ {
+ return _obj.getRemoteProcessName();
+ }
+
+ public Long getRemotePid()
+ {
+ Integer remotePID = _obj.getRemotePID();
+ return remotePID == null ? null : (long) remotePID;
+ }
+
+ public Long getRemoteParentPid()
+ {
+ Integer remotePPID = _obj.getRemoteParentPID();
+ return remotePPID == null ? null : (long) remotePPID;
+
+ }
+
+ public Boolean getClosing()
+ {
+ return false;
+ }
+
+ public Long getFramesFromClient()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getFramesToClient()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getBytesFromClient()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getBytesToClient()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public BrokerSchema.ConnectionClass.CloseMethodResponseCommand close(final BrokerSchema.ConnectionClass.CloseMethodResponseCommandFactory factory)
+ {
+ //todo
+ throw new UnsupportedOperationException();
+ }
+
+ public UUID getId()
+ {
+ return _obj.getId();
+ }
+
+ public long getCreateTime()
+ {
+ // TODO
+ return 0;
+ }
+ }
+
+ private class SessionDelegate implements BrokerSchema.SessionDelegate
+ {
+ private final SessionConfig _obj;
+
+ public SessionDelegate(final SessionConfig obj)
+ {
+ _obj = obj;
+ }
+
+ public BrokerSchema.VhostObject getVhostRef()
+ {
+ return (BrokerSchema.VhostObject) adapt(_obj.getVirtualHost());
+ }
+
+ public String getName()
+ {
+ return _obj.getSessionName();
+ }
+
+ public Integer getChannelId()
+ {
+ return _obj.getChannel();
+ }
+
+ public BrokerSchema.ConnectionObject getConnectionRef()
+ {
+ return (BrokerSchema.ConnectionObject) adapt(_obj.getConnectionConfig());
+ }
+
+ public Long getDetachedLifespan()
+ {
+ return _obj.getDetachedLifespan();
+ }
+
+ public Boolean getAttached()
+ {
+ return _obj.isAttached();
+ }
+
+ public Long getExpireTime()
+ {
+ return _obj.getExpiryTime();
+ }
+
+ public Long getMaxClientRate()
+ {
+ return _obj.getMaxClientRate();
+ }
+
+ public Long getFramesOutstanding()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getTxnStarts()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getTxnCommits()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getTxnRejects()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getTxnCount()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public Long getClientCredit()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public BrokerSchema.SessionClass.SolicitAckMethodResponseCommand solicitAck(final BrokerSchema.SessionClass.SolicitAckMethodResponseCommandFactory factory)
+ {
+ //todo
+ throw new UnsupportedOperationException();
+ }
+
+ public BrokerSchema.SessionClass.DetachMethodResponseCommand detach(final BrokerSchema.SessionClass.DetachMethodResponseCommandFactory factory)
+ {
+ //todo
+ throw new UnsupportedOperationException();
+ }
+
+ public BrokerSchema.SessionClass.ResetLifespanMethodResponseCommand resetLifespan(final BrokerSchema.SessionClass.ResetLifespanMethodResponseCommandFactory factory)
+ {
+ //todo
+ throw new UnsupportedOperationException();
+ }
+
+ public BrokerSchema.SessionClass.CloseMethodResponseCommand close(final BrokerSchema.SessionClass.CloseMethodResponseCommandFactory factory)
+ {
+ //todo
+ throw new UnsupportedOperationException();
+ }
+
+ public UUID getId()
+ {
+ return _obj.getId();
+ }
+
+ public long getCreateTime()
+ {
+ // TODO
+ return 0; //To change body of implemented methods use File | Settings | File Templates.
+ }
+ }
+
+ private class SubscriptionDelegate implements BrokerSchema.SubscriptionDelegate
+ {
+ private final SubscriptionConfig _obj;
+
+ private SubscriptionDelegate(final SubscriptionConfig obj)
+ {
+ _obj = obj;
+ }
+
+
+ public BrokerSchema.SessionObject getSessionRef()
+ {
+ return (BrokerSchema.SessionObject) adapt(_obj.getSessionConfig());
+ }
+
+ public BrokerSchema.QueueObject getQueueRef()
+ {
+ return (BrokerSchema.QueueObject) adapt(_obj.getQueue());
+ }
+
+ public String getName()
+ {
+ return _obj.getName();
+ }
+
+ public Boolean getBrowsing()
+ {
+ return _obj.isBrowsing();
+ }
+
+ public Boolean getAcknowledged()
+ {
+ return _obj.isExplicitAcknowledge();
+ }
+
+ public Boolean getExclusive()
+ {
+ return _obj.isExclusive();
+ }
+
+ public String getCreditMode()
+ {
+ return _obj.getCreditMode();
+ }
+
+ public Map getArguments()
+ {
+ return _obj.getArguments();
+ }
+
+ public Long getDelivered()
+ {
+ // TODO
+ return 0l;
+ }
+
+ public UUID getId()
+ {
+ return _obj.getId();
+ }
+
+ public long getCreateTime()
+ {
+ // TODO
+ return 0; //To change body of implemented methods use File | Settings | File Templates.
+ }
+ }
+
+ private class BridgeDelegate implements BrokerSchema.BridgeDelegate
+ {
+ private final BridgeConfig _obj;
+
+ private BridgeDelegate(final BridgeConfig obj)
+ {
+ _obj = obj;
+ }
+
+ public BrokerSchema.LinkObject getLinkRef()
+ {
+ return (BrokerSchema.LinkObject) adapt(_obj.getLink());
+ }
+
+ public Integer getChannelId()
+ {
+ return _obj.getChannelId();
+ }
+
+ public Boolean getDurable()
+ {
+ return _obj.isDurable();
+ }
+
+ public String getSrc()
+ {
+ return _obj.getSource();
+ }
+
+ public String getDest()
+ {
+ return _obj.getDestination();
+ }
+
+ public String getKey()
+ {
+ return _obj.getKey();
+ }
+
+ public Boolean getSrcIsQueue()
+ {
+ return _obj.isQueueBridge();
+ }
+
+ public Boolean getSrcIsLocal()
+ {
+ return _obj.isLocalSource();
+ }
+
+ public String getTag()
+ {
+ return _obj.getTag();
+ }
+
+ public String getExcludes()
+ {
+ return _obj.getExcludes();
+ }
+
+ public Boolean getDynamic()
+ {
+ return _obj.isDynamic();
+ }
+
+ public Integer getSync()
+ {
+ return _obj.getAckBatching();
+ }
+
+ public BrokerSchema.BridgeClass.CloseMethodResponseCommand close(final BrokerSchema.BridgeClass.CloseMethodResponseCommandFactory factory)
+ {
+ return null;
+ }
+
+ public UUID getId()
+ {
+ return _obj.getId();
+ }
+
+ public long getCreateTime()
+ {
+ return _obj.getCreateTime();
+ }
+ }
+
+ private class LinkDelegate implements BrokerSchema.LinkDelegate
+ {
+ private final LinkConfig _obj;
+
+ private LinkDelegate(final LinkConfig obj)
+ {
+ _obj = obj;
+ }
+
+ public BrokerSchema.VhostObject getVhostRef()
+ {
+ return (BrokerSchema.VhostObject) adapt(_obj.getVirtualHost());
+ }
+
+ public String getHost()
+ {
+ return _obj.getHost();
+ }
+
+ public Integer getPort()
+ {
+ return _obj.getPort();
+ }
+
+ public String getTransport()
+ {
+ return _obj.getTransport();
+ }
+
+ public Boolean getDurable()
+ {
+ return _obj.isDurable();
+ }
+
+ public String getState()
+ {
+ // TODO
+ return "";
+ }
+
+ public String getLastError()
+ {
+ // TODO
+ return "";
+ }
+
+ public BrokerSchema.LinkClass.CloseMethodResponseCommand close(final BrokerSchema.LinkClass.CloseMethodResponseCommandFactory factory)
+ {
+ _obj.close();
+ return factory.createResponseCommand();
+ }
+
+ public BrokerSchema.LinkClass.BridgeMethodResponseCommand bridge(final BrokerSchema.LinkClass.BridgeMethodResponseCommandFactory factory,
+ final Boolean durable,
+ final String src,
+ final String dest,
+ final String key,
+ final String tag,
+ final String excludes,
+ final Boolean srcIsQueue,
+ final Boolean srcIsLocal,
+ final Boolean dynamic,
+ final Integer sync)
+ {
+ _obj.createBridge(durable, dynamic, srcIsQueue, srcIsLocal, src, dest, key, tag, excludes);
+ return factory.createResponseCommand();
+ }
+
+ public UUID getId()
+ {
+ return _obj.getId();
+ }
+
+ public long getCreateTime()
+ {
+ return _obj.getCreateTime();
+ }
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFStatistic.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFStatistic.java
new file mode 100644
index 0000000000..89d650e03b
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFStatistic.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.qmf;
+
+import org.apache.qpid.transport.codec.Encoder;
+
+import java.util.LinkedHashMap;
+
+public class QMFStatistic
+{
+ private final LinkedHashMap<String,Object> _map = new LinkedHashMap<String,Object>();
+ private static final String NAME = "name";
+ private static final String TYPE = "type";
+ private static final String UNIT = "unit";
+ private static final String DESCRIPTION = "desc";
+
+
+ public QMFStatistic(String name, QMFType type, String unit, String description)
+ {
+ _map.put(NAME, name);
+ _map.put(TYPE, type.codeValue());
+ if(unit != null)
+ {
+ _map.put(UNIT, unit);
+ }
+ if(description != null)
+ {
+ _map.put(DESCRIPTION, description);
+ }
+
+ }
+
+ public void encode(Encoder encoder)
+ {
+ encoder.writeMap(_map);
+ }
+
+ public String getName()
+ {
+ return (String) _map.get(NAME);
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFType.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFType.java
new file mode 100644
index 0000000000..0e01c27db5
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFType.java
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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.qmf;
+
+public enum QMFType
+{
+
+ UINT8,
+ UINT16,
+ UINT32,
+ UINT64,
+ UNKNOWN,
+ STR8,
+ STR16,
+ ABSTIME,
+ DELTATIME,
+ OBJECTREFERENCE,
+ BOOLEAN,
+ FLOAT,
+ DOUBLE,
+ UUID,
+ MAP,
+ INT8,
+ INT16,
+ INT32,
+ INT64,
+ OBJECT,
+ LIST,
+ ARRAY;
+
+ public int codeValue()
+ {
+ return ordinal()+1;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java b/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
index 333c1b9cac..1b03ee2334 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
@@ -20,45 +20,72 @@
*/
package org.apache.qpid.server;
-import java.util.*;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ConcurrentHashMap;
-
import org.apache.log4j.Logger;
+
import org.apache.qpid.AMQException;
-import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.framing.*;
-import org.apache.qpid.framing.abstraction.MessagePublishInfo;
+import org.apache.qpid.framing.AMQMethodBody;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.BasicContentHeaderProperties;
+import org.apache.qpid.framing.ContentBody;
+import org.apache.qpid.framing.ContentHeaderBody;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.framing.MethodRegistry;
import org.apache.qpid.framing.abstraction.ContentChunk;
+import org.apache.qpid.framing.abstraction.MessagePublishInfo;
+import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.server.ack.UnacknowledgedMessageMap;
import org.apache.qpid.server.ack.UnacknowledgedMessageMapImpl;
+import org.apache.qpid.server.configuration.ConfigStore;
+import org.apache.qpid.server.configuration.ConfiguredObject;
+import org.apache.qpid.server.configuration.ConnectionConfig;
+import org.apache.qpid.server.configuration.SessionConfig;
+import org.apache.qpid.server.configuration.SessionConfigType;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.flow.FlowCreditManager;
import org.apache.qpid.server.flow.Pre0_10CreditManager;
-import org.apache.qpid.server.protocol.AMQProtocolSession;
-import org.apache.qpid.server.queue.*;
-import org.apache.qpid.server.subscription.Subscription;
-import org.apache.qpid.server.subscription.SubscriptionFactoryImpl;
-import org.apache.qpid.server.subscription.ClientDeliveryMethod;
-import org.apache.qpid.server.subscription.RecordDeliveryMethod;
-import org.apache.qpid.server.store.MessageStore;
-import org.apache.qpid.server.store.StoredMessage;
-import org.apache.qpid.server.txn.*;
-import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.server.message.AMQMessage;
-import org.apache.qpid.server.message.MessageMetaData;
-import org.apache.qpid.server.message.MessageReference;
-import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.logging.LogActor;
import org.apache.qpid.server.logging.LogSubject;
-import org.apache.qpid.server.logging.messages.ChannelMessages;
-import org.apache.qpid.server.logging.subjects.ChannelLogSubject;
import org.apache.qpid.server.logging.actors.AMQPChannelActor;
import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.messages.ChannelMessages;
+import org.apache.qpid.server.logging.subjects.ChannelLogSubject;
+import org.apache.qpid.server.message.AMQMessage;
+import org.apache.qpid.server.message.MessageMetaData;
+import org.apache.qpid.server.message.MessageReference;
+import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.output.ProtocolOutputConverter;
+import org.apache.qpid.server.protocol.AMQProtocolEngine;
+import org.apache.qpid.server.protocol.AMQProtocolSession;
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.queue.BaseQueue;
+import org.apache.qpid.server.queue.IncomingMessage;
+import org.apache.qpid.server.queue.QueueEntry;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.store.MessageStore;
+import org.apache.qpid.server.store.StoredMessage;
+import org.apache.qpid.server.subscription.ClientDeliveryMethod;
+import org.apache.qpid.server.subscription.RecordDeliveryMethod;
+import org.apache.qpid.server.subscription.Subscription;
+import org.apache.qpid.server.subscription.SubscriptionFactoryImpl;
+import org.apache.qpid.server.txn.AutoCommitTransaction;
+import org.apache.qpid.server.txn.LocalTransaction;
+import org.apache.qpid.server.txn.ServerTransaction;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicBoolean;
-public class AMQChannel
+public class AMQChannel implements SessionConfig
{
public static final int DEFAULT_PREFETCH = 5000;
@@ -123,6 +150,7 @@ public class AMQChannel
private List<QueueEntry> _resendList = new ArrayList<QueueEntry>();
private static final
AMQShortString IMMEDIATE_DELIVERY_REPLY_TEXT = new AMQShortString("Immediate delivery is not possible.");
+ private final UUID _id;
public AMQChannel(AMQProtocolSession session, int channelId, MessageStore messageStore)
throws AMQException
@@ -132,15 +160,22 @@ public class AMQChannel
_actor = new AMQPChannelActor(this, session.getLogActor().getRootMessageLogger());
_logSubject = new ChannelLogSubject(this);
-
+ _id = getConfigStore().createId();
_actor.message(ChannelMessages.CHN_CREATE());
+ getConfigStore().addConfiguredObject(this);
+
_messageStore = messageStore;
// by default the session is non-transactional
_transaction = new AutoCommitTransaction(_messageStore);
}
+ public ConfigStore getConfigStore()
+ {
+ return getVirtualHost().getConfigStore();
+ }
+
/** Sets this channel to be part of a local transaction */
public void setLocalTransactional()
{
@@ -220,7 +255,7 @@ public class AMQChannel
try
{
- final ArrayList<AMQQueue> destinationQueues = _currentMessage.getDestinationQueues();
+ final ArrayList<? extends BaseQueue> destinationQueues = _currentMessage.getDestinationQueues();
if(!checkMessageUserId(_currentMessage.getContentHeader()))
{
@@ -411,6 +446,8 @@ public class AMQChannel
_logger.error("Caught AMQException whilst attempting to reque:" + e);
}
+ getConfigStore().removeConfiguredObject(this);
+
}
private void setClosing(boolean closing)
@@ -970,10 +1007,10 @@ public class AMQChannel
private class MessageDeliveryAction implements ServerTransaction.Action
{
private IncomingMessage _incommingMessage;
- private ArrayList<AMQQueue> _destinationQueues;
+ private ArrayList<? extends BaseQueue> _destinationQueues;
public MessageDeliveryAction(IncomingMessage currentMessage,
- ArrayList<AMQQueue> destinationQueues)
+ ArrayList<? extends BaseQueue> destinationQueues)
{
_incommingMessage = currentMessage;
_destinationQueues = destinationQueues;
@@ -988,53 +1025,24 @@ public class AMQChannel
final AMQMessage amqMessage = createAMQMessage(_incommingMessage);
MessageReference ref = amqMessage.newReference();
- for(AMQQueue queue : _destinationQueues)
+ for(final BaseQueue queue : _destinationQueues)
{
+ BaseQueue.PostEnqueueAction action;
- QueueEntry entry = queue.enqueue(amqMessage);
- queue.checkCapacity(AMQChannel.this);
-
-
- if(immediate && !entry.getDeliveredToConsumer() && entry.acquire())
+ if(immediate)
{
+ action = new ImmediateAction(queue);
+ }
+ else
+ {
+ action = null;
+ }
+ queue.enqueue(amqMessage, action);
- ServerTransaction txn = new LocalTransaction(_messageStore);
- Collection<QueueEntry> entries = new ArrayList<QueueEntry>(1);
- entries.add(entry);
- final AMQMessage message = (AMQMessage) entry.getMessage();
- txn.dequeue(queue, entry.getMessage(),
- new MessageAcknowledgeAction(entries)
- {
- @Override
- public void postCommit()
- {
- try
- {
- final
- ProtocolOutputConverter outputConverter =
- _session.getProtocolOutputConverter();
-
- outputConverter.writeReturn(message.getMessagePublishInfo(),
- message.getContentHeaderBody(),
- message,
- _channelId,
- AMQConstant.NO_CONSUMERS.getCode(),
- IMMEDIATE_DELIVERY_REPLY_TEXT);
- }
- catch (AMQException e)
- {
- throw new RuntimeException(e);
- }
- super.postCommit();
- }
- }
- );
- txn.commit();
-
-
-
-
+ if(queue instanceof AMQQueue)
+ {
+ ((AMQQueue)queue).checkCapacity(AMQChannel.this);
}
}
@@ -1057,6 +1065,60 @@ public class AMQChannel
// Maybe keep track of entries that were created and then delete them here in case of failure
// to in memory enqueue
}
+
+ private class ImmediateAction implements BaseQueue.PostEnqueueAction
+ {
+ private final BaseQueue _queue;
+
+ public ImmediateAction(BaseQueue queue)
+ {
+ _queue = queue;
+ }
+
+ public void onEnqueue(QueueEntry entry)
+ {
+ if (!entry.getDeliveredToConsumer() && entry.acquire())
+ {
+
+
+ ServerTransaction txn = new LocalTransaction(_messageStore);
+ Collection<QueueEntry> entries = new ArrayList<QueueEntry>(1);
+ entries.add(entry);
+ final AMQMessage message = (AMQMessage) entry.getMessage();
+ txn.dequeue(_queue, entry.getMessage(),
+ new MessageAcknowledgeAction(entries)
+ {
+ @Override
+ public void postCommit()
+ {
+ try
+ {
+ final
+ ProtocolOutputConverter outputConverter =
+ _session.getProtocolOutputConverter();
+
+ outputConverter.writeReturn(message.getMessagePublishInfo(),
+ message.getContentHeaderBody(),
+ message,
+ _channelId,
+ AMQConstant.NO_CONSUMERS.getCode(),
+ IMMEDIATE_DELIVERY_REPLY_TEXT);
+ }
+ catch (AMQException e)
+ {
+ throw new RuntimeException(e);
+ }
+ super.postCommit();
+ }
+ }
+ );
+ txn.commit();
+
+
+ }
+
+ }
+ }
}
private class MessageAcknowledgeAction implements ServerTransaction.Action
@@ -1163,7 +1225,7 @@ public class AMQChannel
if(_blocking.compareAndSet(false,true))
{
- _actor.message(_logSubject, ChannelMessages.CHN_FLOW_ENFORCED(queue.getName().toString()));
+ _actor.message(_logSubject, ChannelMessages.CHN_FLOW_ENFORCED(queue.getNameShortString().toString()));
flow(false);
}
}
@@ -1188,9 +1250,70 @@ public class AMQChannel
AMQMethodBody responseBody = methodRegistry.createChannelFlowBody(flow);
_session.writeFrame(responseBody.generateFrame(_channelId));
}
-
+
public boolean getBlocking()
{
return _blocking.get();
}
+
+ public VirtualHost getVirtualHost()
+ {
+ return getProtocolSession().getVirtualHost();
+ }
+
+
+ public ConfiguredObject getParent()
+ {
+ return getVirtualHost();
+ }
+
+ public SessionConfigType getConfigType()
+ {
+ return SessionConfigType.getInstance();
+ }
+
+ public int getChannel()
+ {
+ return getChannelId();
+ }
+
+ public boolean isAttached()
+ {
+ return true;
+ }
+
+ public long getDetachedLifespan()
+ {
+ return 0;
+ }
+
+ public ConnectionConfig getConnectionConfig()
+ {
+ return (AMQProtocolEngine)getProtocolSession();
+ }
+
+ public Long getExpiryTime()
+ {
+ return null;
+ }
+
+ public Long getMaxClientRate()
+ {
+ return null;
+ }
+
+ public boolean isDurable()
+ {
+ return false;
+ }
+
+ public UUID getId()
+ {
+ return _id;
+ }
+
+ public String getSessionName()
+ {
+ return getConnectionConfig().getAddress() + "/" + getChannelId();
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java b/java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java
new file mode 100644
index 0000000000..0b689c16a7
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java
@@ -0,0 +1,117 @@
+/*
+ *
+ * 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.binding;
+
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.queue.AMQQueue;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class Binding
+{
+ private final String _bindingKey;
+ private final AMQQueue _queue;
+ private final Exchange _exchange;
+ private final Map<String, Object> _arguments;
+ private final UUID _id;
+ private final AtomicLong _matches = new AtomicLong();
+
+ Binding(UUID id, final String bindingKey, final AMQQueue queue, final Exchange exchange, final Map<String, Object> arguments)
+ {
+ _id = id;
+ _bindingKey = bindingKey;
+ _queue = queue;
+ _exchange = exchange;
+ _arguments = arguments == null ? Collections.EMPTY_MAP : Collections.unmodifiableMap(arguments);
+ }
+
+ public UUID getId()
+ {
+ return _id;
+ }
+
+ public String getBindingKey()
+ {
+ return _bindingKey;
+ }
+
+ public AMQQueue getQueue()
+ {
+ return _queue;
+ }
+
+ public Exchange getExchange()
+ {
+ return _exchange;
+ }
+
+ public Map<String, Object> getArguments()
+ {
+ return _arguments;
+ }
+
+ public void incrementMatches()
+ {
+ _matches.incrementAndGet();
+ }
+
+ public long getMatches()
+ {
+ return _matches.get();
+ }
+
+ boolean isDurable()
+ {
+ return _queue.isDurable() && _exchange.isDurable();
+ }
+
+ @Override
+ public boolean equals(final Object o)
+ {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ final Binding binding = (Binding) o;
+
+ if (!_bindingKey.equals(binding._bindingKey)) return false;
+ if (!_exchange.equals(binding._exchange)) return false;
+ if (!_queue.equals(binding._queue)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int result = _bindingKey.hashCode();
+ result = 31 * result + _queue.hashCode();
+ result = 31 * result + _exchange.hashCode();
+ return result;
+ }
+
+
+
+
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java b/java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java
new file mode 100644
index 0000000000..e11af5d553
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java
@@ -0,0 +1,290 @@
+/*
+ *
+ * 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.binding;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.server.configuration.BindingConfig;
+import org.apache.qpid.server.configuration.BindingConfigType;
+import org.apache.qpid.server.configuration.ConfigStore;
+import org.apache.qpid.server.configuration.ConfiguredObject;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.messages.BindingMessages;
+import org.apache.qpid.server.logging.subjects.BindingLogSubject;
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.store.DurableConfigurationStore;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class BindingFactory
+{
+
+ private final VirtualHost _virtualHost;
+ private final DurableConfigurationStore.Source _configSource;
+ private final Exchange _defaultExchange;
+
+ private final ConcurrentHashMap<BindingImpl, BindingImpl> _bindings = new ConcurrentHashMap<BindingImpl, BindingImpl>();
+
+
+ public BindingFactory(final VirtualHost vhost)
+ {
+ this(vhost,vhost.getExchangeRegistry().getDefaultExchange());
+ }
+
+ public BindingFactory(final DurableConfigurationStore.Source configSource, final Exchange defaultExchange)
+ {
+ _configSource = configSource;
+ _defaultExchange = defaultExchange;
+ if(configSource instanceof VirtualHost)
+ {
+ _virtualHost = (VirtualHost) configSource;
+ }
+ else
+ {
+ _virtualHost = null;
+ }
+ }
+
+ public VirtualHost getVirtualHost()
+ {
+ return _virtualHost;
+ }
+
+
+
+ private final class BindingImpl extends Binding implements AMQQueue.Task, Exchange.Task, BindingConfig
+ {
+ private final BindingLogSubject _logSubject;
+ //TODO
+ private long _createTime = System.currentTimeMillis();
+
+ private BindingImpl(String bindingKey, final AMQQueue queue, final Exchange exchange, final Map<String, Object> arguments)
+ {
+ super(queue.getVirtualHost().getConfigStore().createId(),bindingKey, queue, exchange, arguments);
+ _logSubject = new BindingLogSubject(bindingKey,exchange,queue);
+
+ }
+
+
+ public void doTask(final AMQQueue queue) throws AMQException
+ {
+ removeBinding(this);
+ }
+
+ public void onClose(final Exchange exchange)
+ {
+ removeBinding(this);
+ }
+
+ void logCreation()
+ {
+ CurrentActor.get().message(_logSubject, BindingMessages.BND_CREATED(String.valueOf(getArguments()), getArguments() != null && !getArguments().isEmpty()));
+ }
+
+ void logDestruction()
+ {
+ CurrentActor.get().message(_logSubject, BindingMessages.BND_DELETED());
+ }
+
+ public String getOrigin()
+ {
+ return (String) getArguments().get("qpid.fed.origin");
+ }
+
+ public long getCreateTime()
+ {
+ return _createTime;
+ }
+
+ public BindingConfigType getConfigType()
+ {
+ return BindingConfigType.getInstance();
+ }
+
+ public ConfiguredObject getParent()
+ {
+ return _virtualHost;
+ }
+
+ public boolean isDurable()
+ {
+ return getQueue().isDurable() && getExchange().isDurable();
+ }
+
+ }
+
+
+
+ public boolean addBinding(String bindingKey, AMQQueue queue, Exchange exchange, Map<String, Object> arguments)
+ {
+ return makeBinding(bindingKey, queue, exchange, arguments, false, false);
+ }
+
+
+ public boolean replaceBinding(final String bindingKey,
+ final AMQQueue queue,
+ final Exchange exchange,
+ final Map<String, Object> arguments)
+ {
+ return makeBinding(bindingKey, queue, exchange, arguments, false, true);
+ }
+
+ private boolean makeBinding(String bindingKey, AMQQueue queue, Exchange exchange, Map<String, Object> arguments, boolean restore, boolean force)
+ {
+ assert queue != null;
+ if(bindingKey == null)
+ {
+ bindingKey = "";
+ }
+ if(exchange == null)
+ {
+ exchange = _defaultExchange;
+ }
+ if(arguments == null)
+ {
+ arguments = Collections.EMPTY_MAP;
+ }
+
+ BindingImpl b = new BindingImpl(bindingKey,queue,exchange,arguments);
+ BindingImpl existingMapping = _bindings.putIfAbsent(b,b);
+ if(existingMapping == null || force)
+ {
+ if(existingMapping != null)
+ {
+ removeBinding(existingMapping);
+ }
+
+ if(b.isDurable() && !restore)
+ {
+ try
+ {
+ _configSource.getDurableConfigurationStore().bindQueue(exchange,new AMQShortString(bindingKey),queue,FieldTable.convertToFieldTable(arguments));
+ }
+ catch (AMQException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ queue.addQueueDeleteTask(b);
+ exchange.addCloseTask(b);
+ queue.addBinding(b);
+ exchange.addBinding(b);
+ getConfigStore().addConfiguredObject(b);
+ b.logCreation();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+
+
+ }
+
+ private ConfigStore getConfigStore()
+ {
+ return getVirtualHost().getConfigStore();
+ }
+
+ public void restoreBinding(final String bindingKey, final AMQQueue queue, final Exchange exchange, final Map<String, Object> argumentMap)
+ {
+ makeBinding(bindingKey,queue,exchange,argumentMap,true, false);
+ }
+
+ public void removeBinding(final Binding b)
+ {
+ removeBinding(b.getBindingKey(), b.getQueue(), b.getExchange(), b.getArguments());
+ }
+
+
+ public Binding removeBinding(String bindingKey, AMQQueue queue, Exchange exchange, Map<String, Object> arguments)
+ {
+ assert queue != null;
+ if(bindingKey == null)
+ {
+ bindingKey = "";
+ }
+ if(exchange == null)
+ {
+ exchange = _defaultExchange;
+ }
+ if(arguments == null)
+ {
+ arguments = Collections.EMPTY_MAP;
+ }
+
+ BindingImpl b = _bindings.remove(new BindingImpl(bindingKey,queue,exchange,arguments));
+
+ if(b != null)
+ {
+ exchange.removeBinding(b);
+ queue.removeBinding(b);
+ exchange.removeCloseTask(b);
+ queue.removeQueueDeleteTask(b);
+
+ if(b.isDurable())
+ {
+ try
+ {
+ _configSource.getDurableConfigurationStore().unbindQueue(exchange,
+ new AMQShortString(bindingKey),
+ queue,
+ FieldTable.convertToFieldTable(arguments));
+ }
+ catch (AMQException e)
+ {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ }
+ }
+ b.logDestruction();
+ getConfigStore().removeConfiguredObject(b);
+
+ }
+
+ return b;
+ }
+
+ public Binding getBinding(String bindingKey, AMQQueue queue, Exchange exchange, Map<String, Object> arguments)
+ {
+ assert queue != null;
+ if(bindingKey == null)
+ {
+ bindingKey = "";
+ }
+ if(exchange == null)
+ {
+ exchange = _defaultExchange;
+ }
+ if(arguments == null)
+ {
+ arguments = Collections.EMPTY_MAP;
+ }
+
+ BindingImpl b = new BindingImpl(bindingKey,queue,exchange,arguments);
+ return _bindings.get(b);
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfig.java
new file mode 100644
index 0000000000..9414edcec4
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfig.java
@@ -0,0 +1,43 @@
+/*
+ *
+ * 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.configuration;
+
+import java.util.Map;
+
+
+public interface BindingConfig extends ConfiguredObject<BindingConfigType, BindingConfig>
+{
+
+ ExchangeConfig getExchange();
+
+ QueueConfig getQueue();
+
+ String getBindingKey();
+
+ Map<String, Object> getArguments();
+
+ String getOrigin();
+
+ long getCreateTime();
+
+ long getMatches();
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfigType.java
new file mode 100644
index 0000000000..5cd064ff42
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfigType.java
@@ -0,0 +1,112 @@
+/*
+ *
+ * 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.configuration;
+
+import org.apache.qpid.server.exchange.ExchangeType;
+
+import java.util.*;
+
+public final class BindingConfigType extends ConfigObjectType<BindingConfigType, BindingConfig>
+{
+ private static final List<BindingProperty<?>> BINDING_PROPERTIES = new ArrayList<BindingProperty<?>>();
+
+ public static interface BindingProperty<S> extends ConfigProperty<BindingConfigType, BindingConfig, S>
+ {
+ }
+
+ private abstract static class BindingReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<BindingConfigType, BindingConfig, S> implements BindingProperty<S>
+ {
+ public BindingReadWriteProperty(String name)
+ {
+ super(name);
+ BINDING_PROPERTIES.add(this);
+ }
+ }
+
+ private abstract static class BindingReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<BindingConfigType, BindingConfig, S> implements BindingProperty<S>
+ {
+ public BindingReadOnlyProperty(String name)
+ {
+ super(name);
+ BINDING_PROPERTIES.add(this);
+ }
+ }
+
+ public static final BindingReadOnlyProperty<ExchangeConfig> EXCHANGE_PROPERTY = new BindingReadOnlyProperty<ExchangeConfig>("exchange")
+ {
+ public ExchangeConfig getValue(BindingConfig object)
+ {
+ return object.getExchange();
+ }
+ };
+
+ public static final BindingReadOnlyProperty<QueueConfig> QUEUE_PROPERTY = new BindingReadOnlyProperty<QueueConfig>("queue")
+ {
+ public QueueConfig getValue(BindingConfig object)
+ {
+ return object.getQueue();
+ }
+ };
+
+ public static final BindingReadOnlyProperty<String> BINDING_KEY_PROPERTY = new BindingReadOnlyProperty<String>("bindingKey")
+ {
+ public String getValue(BindingConfig object)
+ {
+ return object.getBindingKey();
+ }
+ };
+
+ public static final BindingReadOnlyProperty<Map<String,Object>> ARGUMENTS = new BindingReadOnlyProperty<Map<String,Object>>("arguments")
+ {
+ public Map<String,Object> getValue(BindingConfig object)
+ {
+ return object.getArguments();
+ }
+ };
+
+ public static final BindingReadOnlyProperty<String> ORIGIN_PROPERTY = new BindingReadOnlyProperty<String>("origin")
+ {
+ public String getValue(BindingConfig object)
+ {
+ return object.getOrigin();
+ }
+ };
+
+ private static final BindingConfigType INSTANCE = new BindingConfigType();
+
+ private BindingConfigType()
+ {
+ }
+
+ public Collection<BindingProperty<?>> getProperties()
+ {
+ return Collections.unmodifiableList(BINDING_PROPERTIES);
+ }
+
+ public static BindingConfigType getInstance()
+ {
+ return INSTANCE;
+ }
+
+
+
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfig.java
new file mode 100644
index 0000000000..f999bf4578
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfig.java
@@ -0,0 +1,50 @@
+/*
+ *
+ * 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.configuration;
+
+public interface BridgeConfig extends ConfiguredObject<BridgeConfigType, BridgeConfig>
+{
+
+ boolean isDynamic();
+
+ boolean isQueueBridge();
+
+ boolean isLocalSource();
+
+ String getSource();
+
+ String getDestination();
+
+ String getKey();
+
+ String getTag();
+
+ String getExcludes();
+
+ LinkConfig getLink();
+
+ Integer getChannelId();
+
+ int getAckBatching();
+
+ long getCreateTime();
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfigType.java
new file mode 100644
index 0000000000..a8d3cd9ec3
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfigType.java
@@ -0,0 +1,169 @@
+/*
+ *
+ * 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.configuration;
+
+import org.apache.qpid.server.exchange.ExchangeType;
+
+import java.util.*;
+
+public final class BridgeConfigType extends ConfigObjectType<BridgeConfigType, BridgeConfig>
+{
+ private static final List<BridgeProperty<?>> BRIDGE_PROPERTIES = new ArrayList<BridgeProperty<?>>();
+
+ public static interface BridgeProperty<S> extends ConfigProperty<BridgeConfigType, BridgeConfig, S>
+ {
+ }
+
+ private abstract static class BridgeReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<BridgeConfigType, BridgeConfig, S> implements BridgeProperty<S>
+ {
+ public BridgeReadWriteProperty(String name)
+ {
+ super(name);
+ BRIDGE_PROPERTIES.add(this);
+ }
+ }
+
+ private abstract static class BridgeReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<BridgeConfigType, BridgeConfig, S> implements BridgeProperty<S>
+ {
+ public BridgeReadOnlyProperty(String name)
+ {
+ super(name);
+ BRIDGE_PROPERTIES.add(this);
+ }
+ }
+
+ public static final BridgeReadOnlyProperty<LinkConfig> LINK_PROPERTY = new BridgeReadOnlyProperty<LinkConfig>("link")
+ {
+ public LinkConfig getValue(BridgeConfig object)
+ {
+ return object.getLink();
+ }
+ };
+
+ public static final BridgeReadOnlyProperty<Integer> CHANNEL_ID_PROPERTY = new BridgeReadOnlyProperty<Integer>("channelId")
+ {
+ public Integer getValue(BridgeConfig object)
+ {
+ return object.getChannelId();
+ }
+ };
+
+ public static final BridgeReadOnlyProperty<Boolean> DURABLE_PROPERTY = new BridgeReadOnlyProperty<Boolean>("durable")
+ {
+ public Boolean getValue(BridgeConfig object)
+ {
+ return object.isDurable();
+ }
+ };
+
+ public static final BridgeReadOnlyProperty<String> SOURCE_PROPERTY = new BridgeReadOnlyProperty<String>("source")
+ {
+ public String getValue(BridgeConfig object)
+ {
+ return object.getSource();
+ }
+ };
+
+ public static final BridgeReadOnlyProperty<String> DESTINATION_PROPERTY = new BridgeReadOnlyProperty<String>("destination")
+ {
+ public String getValue(BridgeConfig object)
+ {
+ return object.getDestination();
+ }
+ };
+
+ public static final BridgeReadOnlyProperty<String> KEY_PROPERTY = new BridgeReadOnlyProperty<String>("key")
+ {
+ public String getValue(BridgeConfig object)
+ {
+ return object.getKey();
+ }
+ };
+
+ public static final BridgeReadOnlyProperty<Boolean> QUEUE_BRIDGE_PROPERTY = new BridgeReadOnlyProperty<Boolean>("queueBridge")
+ {
+ public Boolean getValue(BridgeConfig object)
+ {
+ return object.isQueueBridge();
+ }
+ };
+
+ public static final BridgeReadOnlyProperty<Boolean> LOCAL_SOURCE_PROPERTY = new BridgeReadOnlyProperty<Boolean>("localSource")
+ {
+ public Boolean getValue(BridgeConfig object)
+ {
+ return object.isLocalSource();
+ }
+ };
+
+ public static final BridgeReadOnlyProperty<String> TAG_PROPERTY = new BridgeReadOnlyProperty<String>("tag")
+ {
+ public String getValue(BridgeConfig object)
+ {
+ return object.getTag();
+ }
+ };
+
+ public static final BridgeReadOnlyProperty<String> EXCLUDES_PROPERTY = new BridgeReadOnlyProperty<String>("excludes")
+ {
+ public String getValue(BridgeConfig object)
+ {
+ return object.getExcludes();
+ }
+ };
+
+ public static final BridgeReadOnlyProperty<Boolean> DYNAMIC_PROPERTY = new BridgeReadOnlyProperty<Boolean>("dynamic")
+ {
+ public Boolean getValue(BridgeConfig object)
+ {
+ return object.isDynamic();
+ }
+ };
+
+ public static final BridgeReadOnlyProperty<Integer> ACK_BATCHING_PROPERTY = new BridgeReadOnlyProperty<Integer>("ackBatching")
+ {
+ public Integer getValue(BridgeConfig object)
+ {
+ return object.getAckBatching();
+ }
+ };
+
+
+ private static final BridgeConfigType INSTANCE = new BridgeConfigType();
+
+ private BridgeConfigType()
+ {
+ }
+
+ public Collection<BridgeProperty<?>> getProperties()
+ {
+ return Collections.unmodifiableList(BRIDGE_PROPERTIES);
+ }
+
+ public static BridgeConfigType getInstance()
+ {
+ return INSTANCE;
+ }
+
+
+
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfig.java
new file mode 100644
index 0000000000..4f74a72344
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfig.java
@@ -0,0 +1,59 @@
+/*
+ *
+ * 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.configuration;
+
+
+public interface BrokerConfig extends ConfiguredObject<BrokerConfigType,BrokerConfig>
+{
+ void setSystem(SystemConfig system);
+
+ SystemConfig getSystem();
+
+ Integer getPort();
+
+ Integer getWorkerThreads();
+
+ Integer getMaxConnections();
+
+ Integer getConnectionBacklogLimit();
+
+ Long getStagingThreshold();
+
+ Integer getManagementPublishInterval();
+
+ String getVersion();
+
+ String getDataDirectory();
+
+ void addVirtualHost(VirtualHostConfig virtualHost);
+
+ long getCreateTime();
+
+ void createBrokerConnection(String transport,
+ String host,
+ int port,
+ boolean durable,
+ String authMechanism,
+ String username, String password);
+
+ String getFederationTag();
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigType.java
new file mode 100644
index 0000000000..82b2fc82d2
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigType.java
@@ -0,0 +1,143 @@
+/*
+ *
+ * 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.configuration;
+
+import java.util.*;
+import java.io.File;
+
+public final class BrokerConfigType extends ConfigObjectType<BrokerConfigType, BrokerConfig>
+{
+ private static final List<BrokerProperty<?>> BROKER_PROPERTIES = new ArrayList<BrokerProperty<?>>();
+
+ public static interface BrokerProperty<S> extends ConfigProperty<BrokerConfigType, BrokerConfig, S>
+ {
+ }
+
+ private abstract static class BrokerReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<BrokerConfigType, BrokerConfig, S> implements BrokerProperty<S>
+ {
+ public BrokerReadWriteProperty(String name)
+ {
+ super(name);
+ BROKER_PROPERTIES.add(this);
+ }
+ }
+
+ private abstract static class BrokerReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<BrokerConfigType, BrokerConfig, S> implements BrokerProperty<S>
+ {
+ public BrokerReadOnlyProperty(String name)
+ {
+ super(name);
+ BROKER_PROPERTIES.add(this);
+ }
+ }
+
+ public static final BrokerReadOnlyProperty<SystemConfig> SYSTEM_PROPERTY = new BrokerReadOnlyProperty<SystemConfig>("system")
+ {
+ public SystemConfig getValue(BrokerConfig object)
+ {
+ return object.getSystem();
+ }
+ };
+
+ public static final BrokerReadOnlyProperty<Integer> PORT_PROPERTY = new BrokerReadOnlyProperty<Integer>("port")
+ {
+ public Integer getValue(BrokerConfig object)
+ {
+ return object.getPort();
+ }
+ };
+
+ public static final BrokerReadOnlyProperty<Integer> WORKER_THREADS_PROPERTY = new BrokerReadOnlyProperty<Integer>("workerThreads")
+ {
+ public Integer getValue(BrokerConfig object)
+ {
+ return object.getWorkerThreads();
+ }
+ };
+
+ public static final BrokerReadOnlyProperty<Integer> MAX_CONNECTIONS_PROPERTY = new BrokerReadOnlyProperty<Integer>("maxConnections")
+ {
+ public Integer getValue(BrokerConfig object)
+ {
+ return object.getMaxConnections();
+ }
+ };
+
+ public static final BrokerReadOnlyProperty<Integer> CONNECTION_BACKLOG_LIMIT_PROPERTY = new BrokerReadOnlyProperty<Integer>("connectionBacklog")
+ {
+ public Integer getValue(BrokerConfig object)
+ {
+ return object.getConnectionBacklogLimit();
+ }
+ };
+
+ public static final BrokerReadOnlyProperty<Long> STAGING_THRESHOLD_PROPERTY = new BrokerReadOnlyProperty<Long>("stagingThreshold")
+ {
+ public Long getValue(BrokerConfig object)
+ {
+ return object.getStagingThreshold();
+ }
+ };
+
+ public static final BrokerReadOnlyProperty<Integer> MANAGEMENT_PUBLISH_INTERVAL_PROPERTY = new BrokerReadOnlyProperty<Integer>("mgmtPublishInterval")
+ {
+ public Integer getValue(BrokerConfig object)
+ {
+ return object.getManagementPublishInterval();
+ }
+ };
+
+ public static final BrokerReadOnlyProperty<String> VERSION_PROPERTY = new BrokerReadOnlyProperty<String>("version")
+ {
+ public String getValue(BrokerConfig object)
+ {
+ return object.getVersion();
+ }
+ };
+
+ public static final BrokerReadOnlyProperty<String> DATA_DIR_PROPERTY = new BrokerReadOnlyProperty<String>("dataDirectory")
+ {
+ public String getValue(BrokerConfig object)
+ {
+ return object.getDataDirectory();
+ }
+ };
+
+ private static final BrokerConfigType INSTANCE = new BrokerConfigType();
+
+ private BrokerConfigType()
+ {
+ }
+
+ public Collection<BrokerProperty<?>> getProperties()
+ {
+ return Collections.unmodifiableList(BROKER_PROPERTIES);
+ }
+
+ public static BrokerConfigType getInstance()
+ {
+ return INSTANCE;
+ }
+
+
+
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigObjectType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigObjectType.java
new file mode 100644
index 0000000000..c45aaaf1ee
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigObjectType.java
@@ -0,0 +1,30 @@
+/*
+ *
+ * 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.configuration;
+
+import java.util.Collection;
+
+public abstract class ConfigObjectType<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T,C>>
+{
+ public abstract Collection<? extends ConfigProperty<T, C, ?>> getProperties();
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigProperty.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigProperty.java
new file mode 100644
index 0000000000..2d88ba00a0
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigProperty.java
@@ -0,0 +1,66 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.server.configuration;
+
+public interface ConfigProperty<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T,C>, S>
+{
+ public String getName();
+
+ public S getValue(C object);
+
+ public void setValue(C object, S value);
+
+ public void clearValue(C object);
+
+ public abstract static class ReadWriteConfigProperty<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T,C>,S> implements ConfigProperty<T, C, S>
+ {
+ private final String _name;
+
+ protected ReadWriteConfigProperty(String name)
+ {
+ _name = name;
+ }
+
+ public final String getName()
+ {
+ return _name;
+ }
+ }
+
+ public abstract static class ReadOnlyConfigProperty<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T,C>, S> extends ReadWriteConfigProperty<T, C, S>
+ {
+ protected ReadOnlyConfigProperty(String name)
+ {
+ super(name);
+ }
+
+ public final void setValue(C object, S value)
+ {
+ throw new UnsupportedOperationException("Cannot set value '"+getName()+"' as this property is read-only");
+ }
+
+ public final void clearValue(C object)
+ {
+ throw new UnsupportedOperationException("Cannot set value '"+getName()+"' as this property is read-only");
+ }
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java
new file mode 100644
index 0000000000..572d886c18
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java
@@ -0,0 +1,184 @@
+/*
+ *
+ * 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.configuration;
+
+import java.util.UUID;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class ConfigStore
+{
+ private ConcurrentHashMap<ConfigObjectType, ConcurrentHashMap<UUID, ConfiguredObject>> _typeMap =
+ new ConcurrentHashMap<ConfigObjectType, ConcurrentHashMap<UUID, ConfiguredObject>>();
+
+ private ConcurrentHashMap<ConfigObjectType, CopyOnWriteArrayList<ConfigEventListener>> _listenerMap =
+ new ConcurrentHashMap<ConfigObjectType, CopyOnWriteArrayList<ConfigEventListener>>();
+
+ private SystemConfig _root;
+
+ private final AtomicLong _objectIdSource = new AtomicLong(0l);
+
+
+ public enum Event
+ {
+ CREATED, DELETED;
+ }
+
+ public interface ConfigEventListener<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T, C>>
+ {
+ void onEvent(C object, Event evt);
+ }
+
+ private ConfigStore()
+ {
+ }
+
+ public <T extends ConfigObjectType<T, C>, C extends ConfiguredObject<T, C>> ConfiguredObject<T, C> getConfiguredObject(ConfigObjectType<T,C> type, UUID id)
+ {
+ ConcurrentHashMap<UUID, ConfiguredObject> typeMap = _typeMap.get(type);
+ if(typeMap != null)
+ {
+ return typeMap.get(id);
+ }
+ else
+ {
+ return null;
+ }
+
+ }
+
+ public <T extends ConfigObjectType<T, C>, C extends ConfiguredObject<T, C>> Collection<? extends C> getConfiguredObjects(ConfigObjectType<T,C> type)
+ {
+ ConcurrentHashMap typeMap = _typeMap.get(type);
+ if(typeMap != null)
+ {
+ return typeMap.values();
+ }
+ else
+ {
+ return Collections.EMPTY_LIST;
+ }
+
+ }
+
+ public <T extends ConfigObjectType<T, C>, C extends ConfiguredObject<T, C>> void addConfiguredObject(ConfiguredObject<T, C> object)
+ {
+ ConcurrentHashMap typeMap = _typeMap.get(object.getConfigType());
+ if(typeMap == null)
+ {
+ typeMap = new ConcurrentHashMap();
+ ConcurrentHashMap oldMap = _typeMap.putIfAbsent(object.getConfigType(), typeMap);
+ if(oldMap != null)
+ {
+ typeMap = oldMap;
+ }
+
+ }
+
+ typeMap.put(object.getId(), object);
+ sendEvent(Event.CREATED, object);
+ }
+
+
+ public <T extends ConfigObjectType<T, C>, C extends ConfiguredObject<T, C>> void removeConfiguredObject(ConfiguredObject<T, C> object)
+ {
+ ConcurrentHashMap typeMap = _typeMap.get(object.getConfigType());
+ if(typeMap != null)
+ {
+ typeMap.remove(object.getId());
+ sendEvent(Event.DELETED, object);
+ }
+ }
+
+ public <T extends ConfigObjectType<T, C>, C extends ConfiguredObject<T, C>> void addConfigEventListener(T type, ConfigEventListener<T,C> listener)
+ {
+ CopyOnWriteArrayList listeners = _listenerMap.get(type);
+ if(listeners == null)
+ {
+ listeners = new CopyOnWriteArrayList();
+ CopyOnWriteArrayList oldListeners = _listenerMap.putIfAbsent(type, listeners);
+ if(oldListeners != null)
+ {
+ listeners = oldListeners;
+ }
+
+ }
+
+ listeners.add(listener);
+
+ }
+
+ public <T extends ConfigObjectType<T, C>, C extends ConfiguredObject<T, C>> void removeConfigEventListener(T type, ConfigEventListener<T,C> listener)
+ {
+ CopyOnWriteArrayList listeners = _listenerMap.get(type);
+ if(listeners != null)
+ {
+ listeners.remove(listener);
+ }
+ }
+
+ private void sendEvent(Event e, ConfiguredObject o)
+ {
+ CopyOnWriteArrayList<ConfigEventListener> listeners = _listenerMap.get(o.getConfigType());
+ if(listeners != null)
+ {
+ for(ConfigEventListener listener : listeners)
+ {
+ listener.onEvent(o, e);
+ }
+ }
+ }
+
+ public synchronized boolean setRoot(SystemConfig object)
+ {
+ if(_root == null)
+ {
+ _root = object;
+ addConfiguredObject(object);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ public UUID createId()
+ {
+ return new UUID(0l, _objectIdSource.getAndIncrement());
+ }
+
+
+ public SystemConfig getRoot()
+ {
+ return _root;
+ }
+
+ public static ConfigStore newInstance()
+ {
+ return new ConfigStore();
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfiguredObject.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfiguredObject.java
new file mode 100644
index 0000000000..dd116ea29a
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfiguredObject.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.configuration;
+
+import java.util.UUID;
+
+public interface ConfiguredObject<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T, C>>
+{
+ public UUID getId();
+
+ public T getConfigType();
+
+ public ConfiguredObject getParent();
+
+ public boolean isDurable();
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfig.java
new file mode 100644
index 0000000000..95fb7d39a1
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfig.java
@@ -0,0 +1,45 @@
+/*
+ *
+ * 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.configuration;
+
+public interface ConnectionConfig extends ConfiguredObject<ConnectionConfigType, ConnectionConfig>
+{
+ VirtualHostConfig getVirtualHost();
+
+ String getAddress();
+
+ Boolean isIncoming();
+
+ Boolean isSystemConnection();
+
+ Boolean isFederationLink();
+
+ String getAuthId();
+
+ String getRemoteProcessName();
+
+ Integer getRemotePID();
+
+ Integer getRemoteParentPID();
+
+ ConfigStore getConfigStore();
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfigType.java
new file mode 100644
index 0000000000..9750b12dea
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfigType.java
@@ -0,0 +1,145 @@
+/*
+ *
+ * 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.configuration;
+
+import org.apache.qpid.server.exchange.ExchangeType;
+
+import java.util.*;
+
+public final class ConnectionConfigType extends ConfigObjectType<ConnectionConfigType, ConnectionConfig>
+{
+ private static final List<ConnectionProperty<?>> CONNECTION_PROPERTIES = new ArrayList<ConnectionProperty<?>>();
+
+ public static interface ConnectionProperty<S> extends ConfigProperty<ConnectionConfigType, ConnectionConfig, S>
+ {
+ }
+
+ private abstract static class ConnectionReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<ConnectionConfigType, ConnectionConfig, S> implements ConnectionProperty<S>
+ {
+ public ConnectionReadWriteProperty(String name)
+ {
+ super(name);
+ CONNECTION_PROPERTIES.add(this);
+ }
+ }
+
+ private abstract static class ConnectionReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<ConnectionConfigType, ConnectionConfig, S> implements ConnectionProperty<S>
+ {
+ public ConnectionReadOnlyProperty(String name)
+ {
+ super(name);
+ CONNECTION_PROPERTIES.add(this);
+ }
+ }
+
+ public static final ConnectionReadOnlyProperty<VirtualHostConfig> VIRTUAL_HOST_PROPERTY = new ConnectionReadOnlyProperty<VirtualHostConfig>("virtualHost")
+ {
+ public VirtualHostConfig getValue(ConnectionConfig object)
+ {
+ return object.getVirtualHost();
+ }
+ };
+
+ public static final ConnectionReadOnlyProperty<String> ADDRESS_PROPERTY = new ConnectionReadOnlyProperty<String>("address")
+ {
+ public String getValue(ConnectionConfig object)
+ {
+ return object.getAddress();
+ }
+ };
+
+ public static final ConnectionReadOnlyProperty<Boolean> INCOMING_PROPERTY = new ConnectionReadOnlyProperty<Boolean>("incoming")
+ {
+ public Boolean getValue(ConnectionConfig object)
+ {
+ return object.isIncoming();
+ }
+ };
+
+ public static final ConnectionReadOnlyProperty<Boolean> SYSTEM_CONNECTION_PROPERTY = new ConnectionReadOnlyProperty<Boolean>("systemConnection")
+ {
+ public Boolean getValue(ConnectionConfig object)
+ {
+ return object.isSystemConnection();
+ }
+ };
+
+ public static final ConnectionReadOnlyProperty<Boolean> FEDERATION_LINK_PROPERTY = new ConnectionReadOnlyProperty<Boolean>("federationLink")
+ {
+ public Boolean getValue(ConnectionConfig object)
+ {
+ return object.isFederationLink();
+ }
+ };
+
+ public static final ConnectionReadOnlyProperty<String> AUTH_ID_PROPERTY = new ConnectionReadOnlyProperty<String>("authId")
+ {
+ public String getValue(ConnectionConfig object)
+ {
+ return object.getAuthId();
+ }
+ };
+
+ public static final ConnectionReadOnlyProperty<String> REMOTE_PROCESS_NAME_PROPERTY = new ConnectionReadOnlyProperty<String>("remoteProcessName")
+ {
+ public String getValue(ConnectionConfig object)
+ {
+ return object.getRemoteProcessName();
+ }
+ };
+
+
+ public static final ConnectionReadOnlyProperty<Integer> REMOTE_PID_PROPERTY = new ConnectionReadOnlyProperty<Integer>("remotePid")
+ {
+ public Integer getValue(ConnectionConfig object)
+ {
+ return object.getRemotePID();
+ }
+ };
+
+ public static final ConnectionReadOnlyProperty<Integer> REMOTE_PARENT_PID_PROPERTY = new ConnectionReadOnlyProperty<Integer>("remoteParentPid")
+ {
+ public Integer getValue(ConnectionConfig object)
+ {
+ return object.getRemoteParentPID();
+ }
+ };
+
+ private static final ConnectionConfigType INSTANCE = new ConnectionConfigType();
+
+ private ConnectionConfigType()
+ {
+ }
+
+ public Collection<ConnectionProperty<?>> getProperties()
+ {
+ return Collections.unmodifiableList(CONNECTION_PROPERTIES);
+ }
+
+ public static ConnectionConfigType getInstance()
+ {
+ return INSTANCE;
+ }
+
+
+
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfig.java
new file mode 100644
index 0000000000..40dc88c28c
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfig.java
@@ -0,0 +1,57 @@
+/*
+ *
+ * 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.configuration;
+
+import org.apache.qpid.server.exchange.ExchangeType;
+
+import java.util.Map;
+
+
+public interface ExchangeConfig extends ConfiguredObject<ExchangeConfigType, ExchangeConfig>
+{
+ VirtualHostConfig getVirtualHost();
+
+ String getName();
+
+ ExchangeType getType();
+
+ boolean isAutoDelete();
+
+ ExchangeConfig getAlternateExchange();
+
+ Map<String, Object> getArguments();
+
+
+ long getBindingCount();
+
+ long getBindingCountHigh();
+
+ long getMsgReceives();
+
+ long getMsgRoutes();
+
+ long getByteReceives();
+
+ long getByteRoutes();
+
+ long getCreateTime();
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfigType.java
new file mode 100644
index 0000000000..2095301ad6
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfigType.java
@@ -0,0 +1,113 @@
+/*
+ *
+ * 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.configuration;
+
+import org.apache.qpid.server.exchange.ExchangeType;
+
+import java.util.*;
+
+public final class ExchangeConfigType extends ConfigObjectType<ExchangeConfigType, ExchangeConfig>
+{
+ private static final List<ExchangeProperty<?>> EXCHANGE_PROPERTIES = new ArrayList<ExchangeProperty<?>>();
+
+ public static interface ExchangeProperty<S> extends ConfigProperty<ExchangeConfigType, ExchangeConfig, S>
+ {
+ }
+
+ private abstract static class ExchangeReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<ExchangeConfigType, ExchangeConfig, S> implements ExchangeProperty<S>
+ {
+ public ExchangeReadWriteProperty(String name)
+ {
+ super(name);
+ EXCHANGE_PROPERTIES.add(this);
+ }
+ }
+
+ private abstract static class ExchangeReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<ExchangeConfigType, ExchangeConfig, S> implements ExchangeProperty<S>
+ {
+ public ExchangeReadOnlyProperty(String name)
+ {
+ super(name);
+ EXCHANGE_PROPERTIES.add(this);
+ }
+ }
+
+ public static final ExchangeReadOnlyProperty<VirtualHostConfig> VIRTUAL_HOST_PROPERTY = new ExchangeReadOnlyProperty<VirtualHostConfig>("virtualHost")
+ {
+ public VirtualHostConfig getValue(ExchangeConfig object)
+ {
+ return object.getVirtualHost();
+ }
+ };
+
+ public static final ExchangeReadOnlyProperty<String> NAME_PROPERTY = new ExchangeReadOnlyProperty<String>("name")
+ {
+ public String getValue(ExchangeConfig object)
+ {
+ return object.getName();
+ }
+ };
+
+ public static final ExchangeReadOnlyProperty<Boolean> AUTODELETE_PROPERTY = new ExchangeReadOnlyProperty<Boolean>("autodelete")
+ {
+ public Boolean getValue(ExchangeConfig object)
+ {
+ return object.isAutoDelete();
+ }
+ };
+
+
+ public static final ExchangeReadOnlyProperty<ExchangeConfig> ALTERNATE_EXCHANGE_PROPERTY = new ExchangeReadOnlyProperty<ExchangeConfig>("alternateExchange")
+ {
+ public ExchangeConfig getValue(ExchangeConfig object)
+ {
+ return object.getAlternateExchange();
+ }
+ };
+
+ public static final ExchangeReadOnlyProperty<Map<String,Object>> ARGUMENTS = new ExchangeReadOnlyProperty<Map<String,Object>>("arguments")
+ {
+ public Map<String,Object> getValue(ExchangeConfig object)
+ {
+ return object.getArguments();
+ }
+ };
+
+ private static final ExchangeConfigType INSTANCE = new ExchangeConfigType();
+
+ private ExchangeConfigType()
+ {
+ }
+
+ public Collection<ExchangeProperty<?>> getProperties()
+ {
+ return Collections.unmodifiableList(EXCHANGE_PROPERTIES);
+ }
+
+ public static ExchangeConfigType getInstance()
+ {
+ return INSTANCE;
+ }
+
+
+
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfig.java
new file mode 100644
index 0000000000..82e0647917
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfig.java
@@ -0,0 +1,59 @@
+/*
+ *
+ * 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.configuration;
+
+import org.apache.qpid.server.exchange.ExchangeType;
+
+import java.util.Map;
+
+
+public interface LinkConfig extends ConfiguredObject<LinkConfigType, LinkConfig>
+{
+ VirtualHostConfig getVirtualHost();
+
+
+ String getTransport();
+
+ String getHost();
+
+ int getPort();
+
+ String getRemoteVhost();
+
+ String getAuthMechanism();
+
+ String getUsername();
+
+ String getPassword();
+
+ void close();
+
+ long getCreateTime();
+
+ void createBridge(boolean durable,
+ boolean dynamic,
+ boolean srcIsQueue,
+ boolean srcIsLocal,
+ String src,
+ String dest,
+ String key, String tag, String excludes);
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfigType.java
new file mode 100644
index 0000000000..4dc46b70c9
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfigType.java
@@ -0,0 +1,136 @@
+/*
+ *
+ * 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.configuration;
+
+import org.apache.qpid.server.exchange.ExchangeType;
+
+import java.util.*;
+
+public final class LinkConfigType extends ConfigObjectType<LinkConfigType, LinkConfig>
+{
+ private static final List<LinkProperty<?>> LINK_PROPERTIES = new ArrayList<LinkProperty<?>>();
+
+ public static interface LinkProperty<S> extends ConfigProperty<LinkConfigType, LinkConfig, S>
+ {
+ }
+
+ private abstract static class LinkReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<LinkConfigType, LinkConfig, S> implements LinkProperty<S>
+ {
+ public LinkReadWriteProperty(String name)
+ {
+ super(name);
+ LINK_PROPERTIES.add(this);
+ }
+ }
+
+ private abstract static class LinkReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<LinkConfigType, LinkConfig, S> implements LinkProperty<S>
+ {
+ public LinkReadOnlyProperty(String name)
+ {
+ super(name);
+ LINK_PROPERTIES.add(this);
+ }
+ }
+
+ public static final LinkReadOnlyProperty<VirtualHostConfig> VIRTUAL_HOST_PROPERTY = new LinkReadOnlyProperty<VirtualHostConfig>("virtualHost")
+ {
+ public VirtualHostConfig getValue(LinkConfig object)
+ {
+ return object.getVirtualHost();
+ }
+ };
+
+ public static final LinkReadOnlyProperty<String> TRANSPORT_PROPERTY = new LinkReadOnlyProperty<String>("transport")
+ {
+ public String getValue(LinkConfig object)
+ {
+ return object.getTransport();
+ }
+ };
+
+ public static final LinkReadOnlyProperty<String> HOST_PROPERTY = new LinkReadOnlyProperty<String>("host")
+ {
+ public String getValue(LinkConfig object)
+ {
+ return object.getHost();
+ }
+ };
+
+ public static final LinkReadOnlyProperty<Integer> PORT_PROPERTY = new LinkReadOnlyProperty<Integer>("host")
+ {
+ public Integer getValue(LinkConfig object)
+ {
+ return object.getPort();
+ }
+ };
+
+ public static final LinkReadOnlyProperty<String> REMOTE_VHOST_PROPERTY = new LinkReadOnlyProperty<String>("remoteVhost")
+ {
+ public String getValue(LinkConfig object)
+ {
+ return object.getRemoteVhost();
+ }
+ };
+
+ public static final LinkReadOnlyProperty<String> AUTH_MECHANISM_PROPERTY = new LinkReadOnlyProperty<String>("authMechanism")
+ {
+ public String getValue(LinkConfig object)
+ {
+ return object.getAuthMechanism();
+ }
+ };
+
+ public static final LinkReadOnlyProperty<String> USERNAME_PROPERTY = new LinkReadOnlyProperty<String>("username")
+ {
+ public String getValue(LinkConfig object)
+ {
+ return object.getUsername();
+ }
+ };
+
+ public static final LinkReadOnlyProperty<String> PASSWORD_PROPERTY = new LinkReadOnlyProperty<String>("password")
+ {
+ public String getValue(LinkConfig object)
+ {
+ return object.getPassword();
+ }
+ };
+
+ private static final LinkConfigType INSTANCE = new LinkConfigType();
+
+ private LinkConfigType()
+ {
+ }
+
+ public Collection<LinkProperty<?>> getProperties()
+ {
+ return Collections.unmodifiableList(LINK_PROPERTIES);
+ }
+
+ public static LinkConfigType getInstance()
+ {
+ return INSTANCE;
+ }
+
+
+
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfig.java
new file mode 100644
index 0000000000..a451091fee
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfig.java
@@ -0,0 +1,72 @@
+/*
+ *
+ * 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.configuration;
+
+import java.util.Map;
+
+
+public interface QueueConfig extends ConfiguredObject<QueueConfigType, QueueConfig>
+{
+ VirtualHostConfig getVirtualHost();
+
+ String getName();
+
+ boolean isExclusive();
+
+ boolean isAutoDelete();
+
+ ExchangeConfig getAlternateExchange();
+
+ Map<String, Object> getArguments();
+
+ long getReceivedMessageCount();
+
+ int getMessageCount();
+
+ long getQueueDepth();
+
+ int getConsumerCount();
+
+ int getBindingCount();
+
+ ConfigStore getConfigStore();
+
+ long getMessageDequeueCount();
+
+ long getTotalEnqueueSize();
+
+ long getTotalDequeueSize();
+
+ int getBindingCountHigh();
+
+ long getPersistentByteEnqueues();
+
+ long getPersistentByteDequeues();
+
+ long getPersistentMsgEnqueues();
+
+ long getPersistentMsgDequeues();
+
+ void purge(long request);
+
+ long getCreateTime();
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfigType.java
new file mode 100644
index 0000000000..a794ed9747
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfigType.java
@@ -0,0 +1,121 @@
+/*
+ *
+ * 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.configuration;
+
+import org.apache.qpid.server.exchange.ExchangeType;
+
+import java.util.*;
+
+public final class QueueConfigType extends ConfigObjectType<QueueConfigType, QueueConfig>
+{
+ private static final List<QueueProperty<?>> QUEUE_PROPERTIES = new ArrayList<QueueProperty<?>>();
+
+ public static interface QueueProperty<S> extends ConfigProperty<QueueConfigType, QueueConfig, S>
+ {
+ }
+
+ private abstract static class QueueReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<QueueConfigType, QueueConfig, S> implements QueueProperty<S>
+ {
+ public QueueReadWriteProperty(String name)
+ {
+ super(name);
+ QUEUE_PROPERTIES.add(this);
+ }
+ }
+
+ private abstract static class QueueReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<QueueConfigType, QueueConfig, S> implements QueueProperty<S>
+ {
+ public QueueReadOnlyProperty(String name)
+ {
+ super(name);
+ QUEUE_PROPERTIES.add(this);
+ }
+ }
+
+ public static final QueueReadOnlyProperty<VirtualHostConfig> VISTUAL_HOST_PROPERTY = new QueueReadOnlyProperty<VirtualHostConfig>("virtualHost")
+ {
+ public VirtualHostConfig getValue(QueueConfig object)
+ {
+ return object.getVirtualHost();
+ }
+ };
+
+ public static final QueueReadOnlyProperty<String> NAME_PROPERTY = new QueueReadOnlyProperty<String>("name")
+ {
+ public String getValue(QueueConfig object)
+ {
+ return object.getName();
+ }
+ };
+
+ public static final QueueReadOnlyProperty<Boolean> AUTODELETE_PROPERTY = new QueueReadOnlyProperty<Boolean>("autodelete")
+ {
+ public Boolean getValue(QueueConfig object)
+ {
+ return object.isAutoDelete();
+ }
+ };
+
+ public static final QueueReadOnlyProperty<Boolean> EXCLUSIVE_PROPERTY = new QueueReadOnlyProperty<Boolean>("exclusive")
+ {
+ public Boolean getValue(QueueConfig object)
+ {
+ return object.isExclusive();
+ }
+ };
+
+ public static final QueueReadOnlyProperty<ExchangeConfig> ALTERNATE_EXCHANGE_PROPERTY = new QueueReadOnlyProperty<ExchangeConfig>("alternateExchange")
+ {
+ public ExchangeConfig getValue(QueueConfig object)
+ {
+ return object.getAlternateExchange();
+ }
+ };
+
+ public static final QueueReadOnlyProperty<Map<String,Object>> ARGUMENTS = new QueueReadOnlyProperty<Map<String,Object>>("arguments")
+ {
+ public Map<String,Object> getValue(QueueConfig object)
+ {
+ return object.getArguments();
+ }
+ };
+
+
+ private static final QueueConfigType INSTANCE = new QueueConfigType();
+
+ private QueueConfigType()
+ {
+ }
+
+ public Collection<QueueProperty<?>> getProperties()
+ {
+ return Collections.unmodifiableList(QUEUE_PROPERTIES);
+ }
+
+ public static QueueConfigType getInstance()
+ {
+ return INSTANCE;
+ }
+
+
+
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java
index 5c73e353de..44759bb4b8 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java
@@ -118,4 +118,13 @@ public class QueueConfiguration
return _config.getLong("flowResumeCapacity", _vHostConfig.getFlowResumeCapacity());
}
+ public boolean isLVQ()
+ {
+ return _config.getBoolean("lvq", false);
+ }
+
+ public String getLVQKey()
+ {
+ return _config.getString("lvqKey", null);
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfig.java
new file mode 100644
index 0000000000..ae01ab25ea
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfig.java
@@ -0,0 +1,41 @@
+/*
+ *
+ * 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.configuration;
+
+public interface SessionConfig extends ConfiguredObject<SessionConfigType, SessionConfig>
+{
+ VirtualHostConfig getVirtualHost();
+
+ String getSessionName();
+
+ int getChannel();
+
+ ConnectionConfig getConnectionConfig();
+
+ boolean isAttached();
+
+ long getDetachedLifespan();
+
+ Long getExpiryTime();
+
+ Long getMaxClientRate();
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfigType.java
new file mode 100644
index 0000000000..97cf275575
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfigType.java
@@ -0,0 +1,136 @@
+/*
+ *
+ * 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.configuration;
+
+import org.apache.qpid.server.exchange.ExchangeType;
+
+import java.util.*;
+
+public final class SessionConfigType extends ConfigObjectType<SessionConfigType, SessionConfig>
+{
+ private static final List<SessionProperty<?>> SESSION_PROPERTIES = new ArrayList<SessionProperty<?>>();
+
+ public static interface SessionProperty<S> extends ConfigProperty<SessionConfigType, SessionConfig, S>
+ {
+ }
+
+ private abstract static class SessionReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<SessionConfigType, SessionConfig, S> implements SessionProperty<S>
+ {
+ public SessionReadWriteProperty(String name)
+ {
+ super(name);
+ SESSION_PROPERTIES.add(this);
+ }
+ }
+
+ private abstract static class SessionReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<SessionConfigType, SessionConfig, S> implements SessionProperty<S>
+ {
+ public SessionReadOnlyProperty(String name)
+ {
+ super(name);
+ SESSION_PROPERTIES.add(this);
+ }
+ }
+
+ public static final SessionReadOnlyProperty<VirtualHostConfig> VIRTUAL_HOST_PROPERTY = new SessionReadOnlyProperty<VirtualHostConfig>("virtualHost")
+ {
+ public VirtualHostConfig getValue(SessionConfig object)
+ {
+ return object.getVirtualHost();
+ }
+ };
+
+ public static final SessionReadOnlyProperty<String> NAME_PROPERTY = new SessionReadOnlyProperty<String>("name")
+ {
+ public String getValue(SessionConfig object)
+ {
+ return object.getSessionName();
+ }
+ };
+
+ public static final SessionReadOnlyProperty<Integer> CHANNEL_ID_PROPERTY = new SessionReadOnlyProperty<Integer>("channelId")
+ {
+ public Integer getValue(SessionConfig object)
+ {
+ return object.getChannel();
+ }
+ };
+
+ public static final SessionReadOnlyProperty<ConnectionConfig> CONNECTION_PROPERTY = new SessionReadOnlyProperty<ConnectionConfig>("connection")
+ {
+ public ConnectionConfig getValue(SessionConfig object)
+ {
+ return object.getConnectionConfig();
+ }
+ };
+
+ public static final SessionReadOnlyProperty<Boolean> ATTACHED_PROPERTY = new SessionReadOnlyProperty<Boolean>("attached")
+ {
+ public Boolean getValue(SessionConfig object)
+ {
+ return object.isAttached();
+ }
+ };
+
+ public static final SessionReadOnlyProperty<Long> DETACHED_LIFESPAN_PROPERTY = new SessionReadOnlyProperty<Long>("detachedLifespan")
+ {
+ public Long getValue(SessionConfig object)
+ {
+ return object.getDetachedLifespan();
+ }
+ };
+
+ public static final SessionReadOnlyProperty<Long> EXPIRE_TIME_PROPERTY = new SessionReadOnlyProperty<Long>("expireTime")
+ {
+ public Long getValue(SessionConfig object)
+ {
+ return object.getExpiryTime();
+ }
+ };
+
+ public static final SessionReadOnlyProperty<Long> MAX_CLIENT_RATE_PROPERTY = new SessionReadOnlyProperty<Long>("maxClientRate")
+ {
+ public Long getValue(SessionConfig object)
+ {
+ return object.getMaxClientRate();
+ }
+ };
+
+ private static final SessionConfigType INSTANCE = new SessionConfigType();
+
+ private SessionConfigType()
+ {
+ }
+
+ public Collection<SessionProperty<?>> getProperties()
+ {
+ return Collections.unmodifiableList(SESSION_PROPERTIES);
+ }
+
+ public static SessionConfigType getInstance()
+ {
+ return INSTANCE;
+ }
+
+
+
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfig.java
new file mode 100644
index 0000000000..985ecb2be9
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfig.java
@@ -0,0 +1,47 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.server.configuration;
+
+import java.util.Map;
+
+
+public interface SubscriptionConfig extends ConfiguredObject<SubscriptionConfigType, SubscriptionConfig>
+{
+
+ SessionConfig getSessionConfig();
+
+ QueueConfig getQueue();
+
+ String getName();
+
+ Map<String, Object> getArguments();
+
+ String getCreditMode();
+
+ boolean isBrowsing();
+
+ boolean isExclusive();
+
+ boolean isExplicitAcknowledge();
+
+
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfigType.java
new file mode 100644
index 0000000000..99d3273b55
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfigType.java
@@ -0,0 +1,136 @@
+/*
+ *
+ * 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.configuration;
+
+
+import java.util.*;
+
+public final class SubscriptionConfigType extends ConfigObjectType<SubscriptionConfigType, SubscriptionConfig>
+{
+ private static final List<SubscriptionProperty<?>> SUBSCRIPTION_PROPERTIES = new ArrayList<SubscriptionProperty<?>>();
+
+ public static interface SubscriptionProperty<S> extends ConfigProperty<SubscriptionConfigType, SubscriptionConfig, S>
+ {
+ }
+
+ private abstract static class SubscriptionReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<SubscriptionConfigType, SubscriptionConfig, S> implements SubscriptionProperty<S>
+ {
+ public SubscriptionReadWriteProperty(String name)
+ {
+ super(name);
+ SUBSCRIPTION_PROPERTIES.add(this);
+ }
+ }
+
+ private abstract static class SubscriptionReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<SubscriptionConfigType, SubscriptionConfig, S> implements SubscriptionProperty<S>
+ {
+ public SubscriptionReadOnlyProperty(String name)
+ {
+ super(name);
+ SUBSCRIPTION_PROPERTIES.add(this);
+ }
+ }
+
+ public static final SubscriptionReadOnlyProperty<SessionConfig> SESSION_PROPERTY = new SubscriptionReadOnlyProperty<SessionConfig>("session")
+ {
+ public SessionConfig getValue(SubscriptionConfig object)
+ {
+ return object.getSessionConfig();
+ }
+ };
+
+ public static final SubscriptionReadOnlyProperty<QueueConfig> QUEUE_PROPERTY = new SubscriptionReadOnlyProperty<QueueConfig>("queue")
+ {
+ public QueueConfig getValue(SubscriptionConfig object)
+ {
+ return object.getQueue();
+ }
+ };
+
+ public static final SubscriptionReadOnlyProperty<String> NAME_PROPERTY = new SubscriptionReadOnlyProperty<String>("name")
+ {
+ public String getValue(SubscriptionConfig object)
+ {
+ return object.getName();
+ }
+ };
+
+ public static final SubscriptionReadOnlyProperty<Map<String,Object>> ARGUMENTS = new SubscriptionReadOnlyProperty<Map<String,Object>>("arguments")
+ {
+ public Map<String,Object> getValue(SubscriptionConfig object)
+ {
+ return object.getArguments();
+ }
+ };
+
+ public static final SubscriptionReadOnlyProperty<String> CREDIT_MODE_PROPERTY = new SubscriptionReadOnlyProperty<String>("creditMode")
+ {
+ public String getValue(SubscriptionConfig object)
+ {
+ return object.getCreditMode();
+ }
+ };
+
+ public static final SubscriptionReadOnlyProperty<Boolean> BROWSING_PROPERTY = new SubscriptionReadOnlyProperty<Boolean>("browsing")
+ {
+ public Boolean getValue(SubscriptionConfig object)
+ {
+ return object.isBrowsing();
+ }
+ };
+
+ public static final SubscriptionReadOnlyProperty<Boolean> EXCLUSIVE_PROPERTY = new SubscriptionReadOnlyProperty<Boolean>("exclusive")
+ {
+ public Boolean getValue(SubscriptionConfig object)
+ {
+ return object.isExclusive();
+ }
+ };
+
+ public static final SubscriptionReadOnlyProperty<Boolean> EXPLICIT_ACK_PROPERTY = new SubscriptionReadOnlyProperty<Boolean>("explicitAck")
+ {
+ public Boolean getValue(SubscriptionConfig object)
+ {
+ return object.isExplicitAcknowledge();
+ }
+ };
+
+ private static final SubscriptionConfigType INSTANCE = new SubscriptionConfigType();
+
+ private SubscriptionConfigType()
+ {
+ }
+
+ public Collection<SubscriptionProperty<?>> getProperties()
+ {
+ return Collections.unmodifiableList(SUBSCRIPTION_PROPERTIES);
+ }
+
+
+ public static SubscriptionConfigType getInstance()
+ {
+ return INSTANCE;
+ }
+
+
+
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfig.java
new file mode 100644
index 0000000000..1e722ea191
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfig.java
@@ -0,0 +1,44 @@
+/*
+ *
+ * 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.configuration;
+
+public interface SystemConfig extends ConfiguredObject<SystemConfigType,SystemConfig>
+{
+ String getName();
+
+ String getOperatingSystemName();
+
+ String getNodeName();
+
+
+ String getOSRelease();
+
+ String getOSVersion();
+
+ String getOSArchitecture();
+
+ void addBroker(BrokerConfig broker);
+
+ void removeBroker(BrokerConfig broker);
+
+ long getCreateTime();
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigImpl.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigImpl.java
new file mode 100644
index 0000000000..09ebb07105
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigImpl.java
@@ -0,0 +1,136 @@
+/*
+ *
+ * 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.configuration;
+
+import java.util.UUID;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+public class SystemConfigImpl implements SystemConfig
+{
+ private static final String OS_NAME = System.getProperty("os.name");
+ private static final String OS_ARCH = System.getProperty("os.arch");
+ private static final String OS_VERSION = System.getProperty("os.version");
+
+ private final UUID _id;
+ private String _name;
+
+ private final String _host;
+
+ private final Map<UUID, BrokerConfig> _brokers = new ConcurrentHashMap<UUID, BrokerConfig>();
+
+ private final long _createTime = System.currentTimeMillis();
+ private final ConfigStore _store;
+
+ public SystemConfigImpl(ConfigStore store)
+ {
+ this(store.createId(), store);
+ }
+
+ public SystemConfigImpl(UUID id, ConfigStore store)
+ {
+ _id = id;
+ _store = store;
+ String host;
+ try
+ {
+ InetAddress addr = InetAddress.getLocalHost();
+ host = addr.getHostName();
+ }
+ catch (UnknownHostException e)
+ {
+ host="localhost";
+ }
+ _host = host;
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public String getOperatingSystemName()
+ {
+ return OS_NAME;
+ }
+
+ public String getNodeName()
+ {
+ return _host;
+ }
+
+ public String getOSRelease()
+ {
+ return OS_VERSION;
+ }
+
+ public String getOSVersion()
+ {
+ return "";
+ }
+
+ public String getOSArchitecture()
+ {
+ return OS_ARCH;
+ }
+
+ public UUID getId()
+ {
+ return _id;
+ }
+
+ public SystemConfigType getConfigType()
+ {
+ return SystemConfigType.getInstance();
+ }
+
+ public ConfiguredObject getParent()
+ {
+ return null;
+ }
+
+ public boolean isDurable()
+ {
+ return false;
+ }
+
+ public void addBroker(final BrokerConfig broker)
+ {
+ broker.setSystem(this);
+ _store.addConfiguredObject(broker);
+ _brokers.put(broker.getId(), broker);
+ }
+
+ public void removeBroker(final BrokerConfig broker)
+ {
+ _brokers.remove(broker.getId());
+ _store.removeConfiguredObject(broker);
+ }
+
+ public long getCreateTime()
+ {
+ return _createTime;
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigType.java
new file mode 100644
index 0000000000..f5aabd2345
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigType.java
@@ -0,0 +1,128 @@
+/*
+ *
+ * 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.configuration;
+
+import java.util.*;
+
+public final class SystemConfigType extends ConfigObjectType<SystemConfigType, SystemConfig>
+{
+ private static final List<SystemProperty<?>> SYSTEM_PROPERTIES = new ArrayList<SystemProperty<?>>();
+
+ public static interface SystemProperty<S> extends ConfigProperty<SystemConfigType, SystemConfig, S>
+ {
+ }
+
+ private abstract static class SystemReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<SystemConfigType, SystemConfig, S> implements SystemProperty<S>
+ {
+ public SystemReadWriteProperty(String name)
+ {
+ super(name);
+ SYSTEM_PROPERTIES.add(this);
+ }
+ }
+
+ private abstract static class SystemReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<SystemConfigType, SystemConfig, S> implements SystemProperty<S>
+ {
+ public SystemReadOnlyProperty(String name)
+ {
+ super(name);
+ SYSTEM_PROPERTIES.add(this);
+ }
+ }
+
+ public static final SystemReadOnlyProperty<String> NAME_PROPERTY = new SystemReadOnlyProperty<String>("name")
+ {
+ public String getValue(SystemConfig object)
+ {
+ return object.getName();
+ }
+ };
+
+ public static final SystemReadOnlyProperty<UUID> ID_PROPERTY = new SystemReadOnlyProperty<UUID>("id")
+ {
+ public UUID getValue(SystemConfig object)
+ {
+ return object.getId();
+ }
+ };
+
+ public static final SystemReadOnlyProperty<String> OS_NAME_PROPERTY = new SystemReadOnlyProperty<String>("osName")
+ {
+ public String getValue(SystemConfig object)
+ {
+ return object.getOperatingSystemName();
+ }
+ };
+
+ public static final SystemReadOnlyProperty<String> NODE_NAME_PROPERTY = new SystemReadOnlyProperty<String>("nodeName")
+ {
+ public String getValue(SystemConfig object)
+ {
+ return object.getNodeName();
+ }
+ };
+
+ public static final SystemReadOnlyProperty<String> RELEASE_PROPERTY = new SystemReadOnlyProperty<String>("release")
+ {
+ public String getValue(SystemConfig object)
+ {
+ return object.getOSRelease();
+ }
+ };
+
+ public static final SystemReadOnlyProperty<String> VERSION_PROPERTY = new SystemReadOnlyProperty<String>("version")
+ {
+ public String getValue(SystemConfig object)
+ {
+ return object.getOSVersion();
+ }
+ };
+
+ public static final SystemReadOnlyProperty<String> MACHINE_PROPERTY = new SystemReadOnlyProperty<String>("machine")
+ {
+ public String getValue(SystemConfig object)
+ {
+ return object.getOSArchitecture();
+ }
+ };
+
+ private static final SystemConfigType INSTANCE = new SystemConfigType();
+
+ private SystemConfigType()
+ {
+ }
+
+ public Collection<SystemProperty<?>> getProperties()
+ {
+ return Collections.unmodifiableList(SYSTEM_PROPERTIES);
+ }
+
+
+
+ public static SystemConfigType getInstance()
+ {
+ return INSTANCE;
+ }
+
+
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfig.java
new file mode 100644
index 0000000000..9431e5175f
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfig.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.configuration;
+
+public interface VirtualHostConfig extends ConfiguredObject<VirtualHostConfigType, VirtualHostConfig>
+{
+ String getName();
+
+ BrokerConfig getBroker();
+
+ String getFederationTag();
+
+ void setBroker(BrokerConfig brokerConfig);
+
+ long getCreateTime();
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfigType.java
new file mode 100644
index 0000000000..96682335bf
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfigType.java
@@ -0,0 +1,96 @@
+/*
+ *
+ * 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.configuration;
+
+import java.util.*;
+
+public class VirtualHostConfigType extends ConfigObjectType<VirtualHostConfigType, VirtualHostConfig>
+{
+ private static final List<VirtualHostProperty<?>> VIRTUAL_HOST_PROPERTIES = new ArrayList<VirtualHostProperty<?>>();
+ private static final VirtualHostConfigType INSTANCE = new VirtualHostConfigType();
+public static interface VirtualHostProperty<S> extends ConfigProperty<VirtualHostConfigType, VirtualHostConfig, S>
+ {
+ }
+
+ private abstract static class VirtualHostReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<VirtualHostConfigType, VirtualHostConfig, S> implements VirtualHostProperty<S>
+ {
+ public VirtualHostReadWriteProperty(String name)
+ {
+ super(name);
+ VIRTUAL_HOST_PROPERTIES.add(this);
+ }
+ }
+
+ private abstract static class VirtualHostReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<VirtualHostConfigType, VirtualHostConfig, S> implements VirtualHostProperty<S>
+ {
+ public VirtualHostReadOnlyProperty(String name)
+ {
+ super(name);
+ VIRTUAL_HOST_PROPERTIES.add(this);
+ }
+ }
+
+
+ public static final VirtualHostReadOnlyProperty<String> NAME_PROPERTY = new VirtualHostReadOnlyProperty<String>("name")
+ {
+ public String getValue(VirtualHostConfig object)
+ {
+ return object.getName();
+ }
+ };
+
+
+ public static final VirtualHostReadOnlyProperty<BrokerConfig> BROKER_PROPERTY = new VirtualHostReadOnlyProperty<BrokerConfig>("broker")
+ {
+ public BrokerConfig getValue(VirtualHostConfig object)
+ {
+ return object.getBroker();
+ }
+ };
+
+ public static final VirtualHostReadOnlyProperty<String> FEDERATION_TAG_PROPERTY = new VirtualHostReadOnlyProperty<String>("federationTag")
+ {
+ public String getValue(VirtualHostConfig object)
+ {
+ return object.getFederationTag();
+ }
+ };
+
+
+
+ public Collection<? extends ConfigProperty<VirtualHostConfigType, VirtualHostConfig, ?>> getProperties()
+ {
+ return Collections.unmodifiableList(VIRTUAL_HOST_PROPERTIES);
+ }
+
+
+ private VirtualHostConfigType()
+ {
+ }
+
+ public static VirtualHostConfigType getInstance()
+ {
+ return INSTANCE;
+ }
+
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
index 07f33b4a8f..32b95ff742 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
@@ -20,51 +20,57 @@
*/
package org.apache.qpid.server.exchange;
-import javax.management.MalformedObjectNameException;
-import javax.management.NotCompliantMBeanException;
-import javax.management.ObjectName;
-import javax.management.JMException;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.TabularType;
-import javax.management.openmbean.TabularDataSupport;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.SimpleType;
-import javax.management.openmbean.ArrayType;
+import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.management.common.mbeans.ManagedExchange;
-import org.apache.qpid.server.management.AMQManagedObject;
+import org.apache.qpid.server.binding.Binding;
+import org.apache.qpid.server.configuration.ConfigStore;
+import org.apache.qpid.server.configuration.ConfiguredObject;
+import org.apache.qpid.server.configuration.ExchangeConfigType;
+import org.apache.qpid.server.logging.LogSubject;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.messages.ExchangeMessages;
+import org.apache.qpid.server.logging.subjects.ExchangeLogSubject;
import org.apache.qpid.server.management.Managable;
import org.apache.qpid.server.management.ManagedObject;
-import org.apache.qpid.server.management.ManagedObjectRegistry;
-import org.apache.qpid.server.queue.QueueRegistry;
+import org.apache.qpid.server.message.InboundMessage;
import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.queue.BaseQueue;
+import org.apache.qpid.server.queue.QueueRegistry;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.messages.ExchangeMessages;
-import org.apache.qpid.server.logging.subjects.ExchangeLogSubject;
-import org.apache.qpid.server.logging.LogSubject;
-import org.apache.log4j.Logger;
+import javax.management.JMException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
import java.util.Map;
+import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
public abstract class AbstractExchange implements Exchange, Managable
{
+
+
private AMQShortString _name;
+ private final AtomicBoolean _closed = new AtomicBoolean();
private Exchange _alternateExchange;
protected boolean _durable;
- protected String _exchangeType;
protected int _ticket;
private VirtualHost _virtualHost;
- protected ExchangeMBean _exchangeMbean;
+ private final List<Exchange.Task> _closeTaskList = new CopyOnWriteArrayList<Exchange.Task>();
+
+
+ protected AbstractExchangeMBean _exchangeMbean;
/**
* Whether the exchange is automatically deleted once all queues have detached from it
@@ -75,95 +81,49 @@ public abstract class AbstractExchange implements Exchange, Managable
private LogSubject _logSubject;
private Map<ExchangeReferrer,Object> _referrers = new ConcurrentHashMap<ExchangeReferrer,Object>();
- /**
- * Abstract MBean class. This has some of the methods implemented from
- * management intrerface for exchanges. Any implementaion of an
- * Exchange MBean should extend this class.
- */
- protected abstract class ExchangeMBean extends AMQManagedObject implements ManagedExchange
- {
- // open mbean data types for representing exchange bindings
- protected OpenType[] _bindingItemTypes;
- protected CompositeType _bindingDataType;
- protected TabularType _bindinglistDataType;
- protected TabularDataSupport _bindingList;
+ private final CopyOnWriteArrayList<Binding> _bindings = new CopyOnWriteArrayList<Binding>();
+ private final ExchangeType<? extends Exchange> _type;
+ private UUID _id;
+ private final AtomicInteger _bindingCountHigh = new AtomicInteger();
+ private final AtomicLong _receivedMessageCount = new AtomicLong();
+ private final AtomicLong _receivedMessageSize = new AtomicLong();
+ private final AtomicLong _routedMessageCount = new AtomicLong();
+ private final AtomicLong _routedMessageSize = new AtomicLong();
+ private final CopyOnWriteArrayList<Exchange.BindingListener> _listeners = new CopyOnWriteArrayList<Exchange.BindingListener>();
+/*
+=======
public ExchangeMBean() throws NotCompliantMBeanException
{
super(ManagedExchange.class, ManagedExchange.TYPE);
}
+>>>>>>> .r902547
+*/
- protected void init() throws OpenDataException
- {
- _bindingItemTypes = new OpenType[2];
- _bindingItemTypes[0] = SimpleType.STRING;
- _bindingItemTypes[1] = new ArrayType(1, SimpleType.STRING);
- _bindingDataType = new CompositeType("Exchange Binding", "Binding key and Queue names",
- COMPOSITE_ITEM_NAMES, COMPOSITE_ITEM_DESCRIPTIONS, _bindingItemTypes);
- _bindinglistDataType = new TabularType("Exchange Bindings", "Exchange Bindings for " + getName(),
- _bindingDataType, TABULAR_UNIQUE_INDEX);
- }
-
- public ManagedObject getParentObject()
- {
- return _virtualHost.getManagedObject();
- }
-
- public String getObjectInstanceName()
- {
- return _name.toString();
- }
-
- public String getName()
- {
- return _name.toString();
- }
-
- public String getExchangeType()
- {
- return _exchangeType;
- }
-
- public Integer getTicketNo()
- {
- return _ticket;
- }
-
- public boolean isDurable()
- {
- return _durable;
- }
-
- public boolean isAutoDelete()
- {
- return _autoDelete;
- }
-
- // Added exchangetype in the object name lets maangement apps to do any customization required
- public ObjectName getObjectName() throws MalformedObjectNameException
- {
- String objNameString = super.getObjectName().toString();
- objNameString = objNameString + ",ExchangeType=" + _exchangeType;
- return new ObjectName(objNameString);
- }
+ // TODO
+ private long _createTime = System.currentTimeMillis();
- protected ManagedObjectRegistry getManagedObjectRegistry()
- {
- return ApplicationRegistry.getInstance().getManagedObjectRegistry();
- }
- } // End of MBean class
+ public AbstractExchange(final ExchangeType<? extends Exchange> type)
+ {
+ _type = type;
+ }
- public AMQShortString getName()
+ public AMQShortString getNameShortString()
{
return _name;
}
+ public final AMQShortString getTypeShortString()
+ {
+ return _type.getName();
+ }
+
/**
* Concrete exchanges must implement this method in order to create the managed representation. This is
* called during initialisation (template method pattern).
* @return the MBean
*/
- protected abstract ExchangeMBean createMBean() throws JMException;
+ protected abstract AbstractExchangeMBean createMBean() throws JMException;
public void initialise(VirtualHost host, AMQShortString name, boolean durable, int ticket, boolean autoDelete)
throws AMQException
@@ -173,6 +133,11 @@ public abstract class AbstractExchange implements Exchange, Managable
_durable = durable;
_autoDelete = autoDelete;
_ticket = ticket;
+
+ // TODO - fix
+ _id = getConfigStore().createId();
+
+ getConfigStore().addConfiguredObject(this);
try
{
_exchangeMbean = createMBean();
@@ -185,7 +150,12 @@ public abstract class AbstractExchange implements Exchange, Managable
_logSubject = new ExchangeLogSubject(this, this.getVirtualHost());
// Log Exchange creation
- CurrentActor.get().message(ExchangeMessages.EXH_CREATED(String.valueOf(getType()), String.valueOf(name), durable));
+ CurrentActor.get().message(ExchangeMessages.EXH_CREATED(String.valueOf(getTypeShortString()), String.valueOf(name), durable));
+ }
+
+ public ConfigStore getConfigStore()
+ {
+ return getVirtualHost().getConfigStore();
}
public abstract Logger getLogger();
@@ -207,21 +177,32 @@ public abstract class AbstractExchange implements Exchange, Managable
public void close() throws AMQException
{
- if (_exchangeMbean != null)
- {
- _exchangeMbean.unregister();
- }
- if(_alternateExchange != null)
+
+ if(_closed.compareAndSet(false,true))
{
- _alternateExchange.removeReference(this);
+ if (_exchangeMbean != null)
+ {
+ _exchangeMbean.unregister();
+ }
+ getConfigStore().removeConfiguredObject(this);
+ if(_alternateExchange != null)
+ {
+ _alternateExchange.removeReference(this);
+ }
+
+ CurrentActor.get().message(_logSubject, ExchangeMessages.EXH_DELETED());
+
+ for(Task task : _closeTaskList)
+ {
+ task.onClose(this);
+ }
+ _closeTaskList.clear();
}
-
- CurrentActor.get().message(_logSubject, ExchangeMessages.EXH_DELETED());
}
public String toString()
{
- return getClass().getSimpleName() + "[" + getName() +"]";
+ return getClass().getSimpleName() + "[" + getNameShortString() +"]";
}
public ManagedObject getManagedObject()
@@ -288,4 +269,143 @@ public abstract class AbstractExchange implements Exchange, Managable
{
return !_referrers.isEmpty();
}
+
+ public void addCloseTask(final Task task)
+ {
+ _closeTaskList.add(task);
+ }
+
+ public void removeCloseTask(final Task task)
+ {
+ _closeTaskList.remove(task);
+ }
+
+ public final void addBinding(final Binding binding)
+ {
+ _bindings.add(binding);
+ int bindingCountSize = _bindings.size();
+ int maxBindingsSize;
+ while((maxBindingsSize = _bindingCountHigh.get()) < bindingCountSize)
+ {
+ _bindingCountHigh.compareAndSet(maxBindingsSize, bindingCountSize);
+ }
+ for(BindingListener listener : _listeners)
+ {
+ listener.bindingAdded(this, binding);
+ }
+ onBind(binding);
+ }
+
+ public long getBindingCountHigh()
+ {
+ return _bindingCountHigh.get();
+ }
+
+ public final void removeBinding(final Binding binding)
+ {
+ onUnbind(binding);
+ for(BindingListener listener : _listeners)
+ {
+ listener.bindingRemoved(this, binding);
+ }
+ _bindings.remove(binding);
+ }
+
+ public final Collection<Binding> getBindings()
+ {
+ return Collections.unmodifiableList(_bindings);
+ }
+
+ protected abstract void onBind(final Binding binding);
+
+ protected abstract void onUnbind(final Binding binding);
+
+
+ public String getName()
+ {
+ return _name.toString();
+ }
+
+ public ExchangeType getType()
+ {
+ return _type;
+ }
+
+ public Map<String, Object> getArguments()
+ {
+ // TODO - Fix
+ return Collections.EMPTY_MAP;
+ }
+
+ public UUID getId()
+ {
+ return _id;
+ }
+
+ public ExchangeConfigType getConfigType()
+ {
+ return ExchangeConfigType.getInstance();
+ }
+
+ public ConfiguredObject getParent()
+ {
+ return _virtualHost;
+ }
+
+ public long getBindingCount()
+ {
+ return getBindings().size();
+ }
+
+
+
+ public final ArrayList<? extends BaseQueue> route(final InboundMessage message)
+ {
+ _receivedMessageCount.incrementAndGet();
+ _receivedMessageSize.addAndGet(message.getSize());
+ final ArrayList<? extends BaseQueue> queues = doRoute(message);
+ if(queues != null && !queues.isEmpty())
+ {
+ _routedMessageCount.incrementAndGet();
+ _routedMessageSize.addAndGet(message.getSize());
+ }
+ return queues;
+ }
+
+ protected abstract ArrayList<? extends BaseQueue> doRoute(final InboundMessage message);
+
+ public long getMsgReceives()
+ {
+ return _receivedMessageCount.get();
+ }
+
+ public long getMsgRoutes()
+ {
+ return _routedMessageCount.get();
+ }
+
+ public long getByteReceives()
+ {
+ return _receivedMessageSize.get();
+ }
+
+ public long getByteRoutes()
+ {
+ return _routedMessageSize.get();
+ }
+
+ public long getCreateTime()
+ {
+ return _createTime;
+ }
+
+ public void addBindingListener(final BindingListener listener)
+ {
+ _listeners.add(listener);
+ }
+
+ public void removeBindingListener(final BindingListener listener)
+ {
+ _listeners.remove(listener);
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java
new file mode 100644
index 0000000000..ece8bc90fe
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java
@@ -0,0 +1,139 @@
+/*
+ *
+ * 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.exchange;
+
+import org.apache.qpid.server.management.AMQManagedObject;
+import org.apache.qpid.server.management.ManagedObject;
+import org.apache.qpid.server.management.ManagedObjectRegistry;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.actors.ManagementActor;
+import org.apache.qpid.management.common.mbeans.ManagedExchange;
+import org.apache.qpid.framing.AMQShortString;
+
+import javax.management.openmbean.*;
+import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectName;
+import javax.management.MalformedObjectNameException;
+import javax.management.JMException;
+
+/**
+ * Abstract MBean class. This has some of the methods implemented from
+ * management intrerface for exchanges. Any implementaion of an
+ * Exchange MBean should extend this class.
+ */
+public abstract class AbstractExchangeMBean<T extends AbstractExchange> extends AMQManagedObject implements ManagedExchange
+{
+ // open mbean data types for representing exchange bindings
+ protected OpenType[] _bindingItemTypes;
+ protected CompositeType _bindingDataType;
+ protected TabularType _bindinglistDataType;
+
+
+ private T _exchange;
+
+ public AbstractExchangeMBean(final T abstractExchange) throws NotCompliantMBeanException
+ {
+ super(ManagedExchange.class, ManagedExchange.TYPE);
+ _exchange = abstractExchange;
+ }
+
+ protected void init() throws OpenDataException
+ {
+ _bindingItemTypes = new OpenType[2];
+ _bindingItemTypes[0] = SimpleType.STRING;
+ _bindingItemTypes[1] = new ArrayType(1, SimpleType.STRING);
+ _bindingDataType = new CompositeType("Exchange Binding", "Binding key and Queue names",
+ COMPOSITE_ITEM_NAMES, COMPOSITE_ITEM_DESCRIPTIONS, _bindingItemTypes);
+ _bindinglistDataType = new TabularType("Exchange Bindings", "Exchange Bindings for " + getName(),
+ _bindingDataType, TABULAR_UNIQUE_INDEX);
+ }
+
+ public ManagedObject getParentObject()
+ {
+ return _exchange.getVirtualHost().getManagedObject();
+ }
+
+ public T getExchange()
+ {
+ return _exchange;
+ }
+
+
+ public String getObjectInstanceName()
+ {
+ return _exchange.getNameShortString().toString();
+ }
+
+ public String getName()
+ {
+ return _exchange.getNameShortString().toString();
+ }
+
+ public String getExchangeType()
+ {
+ return _exchange.getTypeShortString().toString();
+ }
+
+ public Integer getTicketNo()
+ {
+ return _exchange._ticket;
+ }
+
+ public boolean isDurable()
+ {
+ return _exchange._durable;
+ }
+
+ public boolean isAutoDelete()
+ {
+ return _exchange._autoDelete;
+ }
+
+ // Added exchangetype in the object name lets maangement apps to do any customization required
+ public ObjectName getObjectName() throws MalformedObjectNameException
+ {
+ String objNameString = super.getObjectName().toString();
+ objNameString = objNameString + ",ExchangeType=" + getExchangeType();
+ return new ObjectName(objNameString);
+ }
+
+ protected ManagedObjectRegistry getManagedObjectRegistry()
+ {
+ return ApplicationRegistry.getInstance().getManagedObjectRegistry();
+ }
+
+ public void createNewBinding(String queueName, String binding) throws JMException
+ {
+ VirtualHost vhost = getExchange().getVirtualHost();
+ AMQQueue queue = vhost.getQueueRegistry().getQueue(new AMQShortString(queueName));
+ if (queue == null)
+ {
+ throw new JMException("Queue \"" + queueName + "\" is not registered with the exchange.");
+ }
+
+ CurrentActor.set(new ManagementActor(_logActor.getRootMessageLogger()));
+ vhost.getBindingFactory().addBinding(binding,queue,getExchange(),null);
+ CurrentActor.remove();
+ }
+} // End of MBean class
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java
index 6b0cf89b95..1c4c341c14 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java
@@ -20,19 +20,20 @@
*/
package org.apache.qpid.server.exchange;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
import org.apache.qpid.AMQUnknownExchangeType;
import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.qmf.ManagementExchange;
import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
public class DefaultExchangeFactory implements ExchangeFactory
{
private static final Logger _logger = Logger.getLogger(DefaultExchangeFactory.class);
@@ -47,6 +48,7 @@ public class DefaultExchangeFactory implements ExchangeFactory
registerExchangeType(TopicExchange.TYPE);
registerExchangeType(HeadersExchange.TYPE);
registerExchangeType(FanoutExchange.TYPE);
+ registerExchangeType(ManagementExchange.TYPE);
}
public void registerExchangeType(ExchangeType<? extends Exchange> type)
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java
index 7b21ad6b91..84444450c9 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java
@@ -66,8 +66,8 @@ public class DefaultExchangeRegistry implements ExchangeRegistry
public void registerExchange(Exchange exchange) throws AMQException
{
- _exchangeMap.put(exchange.getName(), exchange);
- _exchangeMapStr.put(exchange.getName().toString(), exchange);
+ _exchangeMap.put(exchange.getNameShortString(), exchange);
+ _exchangeMapStr.put(exchange.getNameShortString().toString(), exchange);
}
public void setDefaultExchange(Exchange exchange)
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java
index 3c3902c545..cb0d8ecf8f 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java
@@ -20,40 +20,29 @@
*/
package org.apache.qpid.server.exchange;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import javax.management.JMException;
-import javax.management.MBeanException;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.TabularData;
-import javax.management.openmbean.TabularDataSupport;
-
import org.apache.log4j.Logger;
+
import org.apache.qpid.AMQException;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
-import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.server.binding.Binding;
+import org.apache.qpid.server.message.InboundMessage;
import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.message.InboundMessage;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.actors.ManagementActor;
+
+import javax.management.JMException;
+import java.util.ArrayList;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
public class DirectExchange extends AbstractExchange
{
private static final Logger _logger = Logger.getLogger(DirectExchange.class);
- /**
- * Maps from queue name to queue instances
- */
- private final Index _index = new Index();
+ private final ConcurrentHashMap<String, CopyOnWriteArraySet<Binding>> _bindingsByKey =
+ new ConcurrentHashMap<String, CopyOnWriteArraySet<Binding>>();
public static final ExchangeType<DirectExchange> TYPE = new ExchangeType<DirectExchange>()
{
@@ -85,73 +74,15 @@ public class DirectExchange extends AbstractExchange
}
};
- /**
- * MBean class implementing the management interfaces.
- */
- @MBeanDescription("Management Bean for Direct Exchange")
- private final class DirectExchangeMBean extends ExchangeMBean
- {
- @MBeanConstructor("Creates an MBean for AMQ direct exchange")
- public DirectExchangeMBean() throws JMException
- {
- super();
- _exchangeType = "direct";
- init();
- }
-
- public TabularData bindings() throws OpenDataException
- {
- Map<AMQShortString, List<AMQQueue>> bindings = _index.getBindingsMap();
- _bindingList = new TabularDataSupport(_bindinglistDataType);
-
- for (Map.Entry<AMQShortString, List<AMQQueue>> entry : bindings.entrySet())
- {
- AMQShortString key = entry.getKey();
- List<String> queueList = new ArrayList<String>();
-
- List<AMQQueue> queues = entry.getValue();
- for (AMQQueue q : queues)
- {
- queueList.add(q.getName().toString());
- }
-
- Object[] bindingItemValues = {key.toString(), queueList.toArray(new String[0])};
- CompositeData bindingData = new CompositeDataSupport(_bindingDataType, COMPOSITE_ITEM_NAMES, bindingItemValues);
- _bindingList.put(bindingData);
- }
-
- return _bindingList;
- }
-
- public void createNewBinding(String queueName, String binding) throws JMException
- {
- AMQQueue queue = getQueueRegistry().getQueue(new AMQShortString(queueName));
- if (queue == null)
- {
- throw new JMException("Queue \"" + queueName + "\" is not registered with the exchange.");
- }
-
- CurrentActor.set(new ManagementActor(_logActor.getRootMessageLogger()));
- try
- {
- queue.bind(DirectExchange.this, new AMQShortString(binding), null);
- }
- catch (AMQException ex)
- {
- throw new MBeanException(ex);
- }
- finally
- {
- CurrentActor.remove();
- }
- }
-
- }// End of MBean class
+ public DirectExchange()
+ {
+ super(TYPE);
+ }
- protected ExchangeMBean createMBean() throws JMException
+ protected AbstractExchangeMBean createMBean() throws JMException
{
- return new DirectExchangeMBean();
+ return new DirectExchangeMBean(this);
}
public Logger getLogger()
@@ -159,68 +90,36 @@ public class DirectExchange extends AbstractExchange
return _logger;
}
- public AMQShortString getType()
- {
- return ExchangeDefaults.DIRECT_EXCHANGE_CLASS;
- }
- public void registerQueue(String routingKey, AMQQueue queue, Map<String,Object> args) throws AMQException
+ public ArrayList<? extends BaseQueue> doRoute(InboundMessage payload)
{
- registerQueue(new AMQShortString(routingKey), queue);
- }
- public void registerQueue(AMQShortString routingKey, AMQQueue queue, FieldTable args) throws AMQException
- {
- registerQueue(routingKey, queue);
- }
+ final String routingKey = payload.getRoutingKey();
- private void registerQueue(AMQShortString routingKey, AMQQueue queue) throws AMQException
- {
- assert queue != null;
- assert routingKey != null;
- if (!_index.add(routingKey, queue))
+ CopyOnWriteArraySet<Binding> bindings = _bindingsByKey.get(routingKey == null ? "" : routingKey);
+
+ if(bindings != null)
{
- if (_logger.isDebugEnabled())
+ final ArrayList<BaseQueue> queues = new ArrayList<BaseQueue>(bindings.size());
+
+ for(Binding binding : bindings)
{
- _logger.debug("Queue (" + queue + ") is already registered with routing key " + routingKey);
+ queues.add(binding.getQueue());
+ binding.incrementMatches();
}
- }
- else
- {
+
if (_logger.isDebugEnabled())
{
- _logger.debug("Binding queue:" + queue + " with routing key '" + routingKey +"' to exchange:" + this);
+ _logger.debug("Publishing message to queue " + queues);
}
- }
- }
- public void deregisterQueue(AMQShortString routingKey, AMQQueue queue, FieldTable args) throws AMQException
- {
- assert queue != null;
- assert routingKey != null;
-
- if (!_index.remove(routingKey, queue))
- {
- throw new AMQException(AMQConstant.NOT_FOUND, "Queue " + queue + " was not registered with exchange " + this.getName() +
- " with routing key " + routingKey + ". No queue was registered with that _routing key");
+ return queues;
}
- }
-
- public ArrayList<AMQQueue> route(InboundMessage payload)
- {
-
- final String routingKey = payload.getRoutingKey();
-
-
- final ArrayList<AMQQueue> queues = (routingKey == null) ? _index.get("") : _index.get(routingKey);
-
- if (_logger.isDebugEnabled())
+ else
{
- _logger.debug("Publishing message to queue " + queues);
+ return new ArrayList<BaseQueue>(0);
}
- return queues;
-
}
@@ -232,24 +131,40 @@ public class DirectExchange extends AbstractExchange
public boolean isBound(AMQShortString routingKey, AMQQueue queue)
{
- final List<AMQQueue> queues = _index.get(routingKey);
- return queues != null && queues.contains(queue);
+ String bindingKey = (routingKey == null) ? "" : routingKey.toString();
+ CopyOnWriteArraySet<Binding> bindings = _bindingsByKey.get(bindingKey);
+ if(bindings != null)
+ {
+ for(Binding binding : bindings)
+ {
+ if(binding.getQueue().equals(queue))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+
}
public boolean isBound(AMQShortString routingKey)
{
- final List<AMQQueue> queues = _index.get(routingKey);
- return queues != null && !queues.isEmpty();
+ String bindingKey = (routingKey == null) ? "" : routingKey.toString();
+ CopyOnWriteArraySet<Binding> bindings = _bindingsByKey.get(bindingKey);
+ return bindings != null && !bindings.isEmpty();
}
public boolean isBound(AMQQueue queue)
{
- Map<AMQShortString, List<AMQQueue>> bindings = _index.getBindingsMap();
- for (List<AMQQueue> queues : bindings.values())
+
+ for (CopyOnWriteArraySet<Binding> bindings : _bindingsByKey.values())
{
- if (queues.contains(queue))
+ for(Binding binding : bindings)
{
- return true;
+ if(binding.getQueue().equals(queue))
+ {
+ return true;
+ }
}
}
return false;
@@ -257,11 +172,45 @@ public class DirectExchange extends AbstractExchange
public boolean hasBindings()
{
- return !_index.getBindingsMap().isEmpty();
+ return !getBindings().isEmpty();
}
- public Map<AMQShortString, List<AMQQueue>> getBindings()
+ protected void onBind(final Binding binding)
{
- return _index.getBindingsMap();
+ String bindingKey = binding.getBindingKey();
+ AMQQueue queue = binding.getQueue();
+ AMQShortString routingKey = AMQShortString.valueOf(bindingKey);
+
+ assert queue != null;
+ assert routingKey != null;
+
+ CopyOnWriteArraySet<Binding> bindings = _bindingsByKey.get(bindingKey);
+
+ if(bindings == null)
+ {
+ bindings = new CopyOnWriteArraySet<Binding>();
+ CopyOnWriteArraySet<Binding> newBindings;
+ if((newBindings = _bindingsByKey.putIfAbsent(bindingKey, bindings)) != null)
+ {
+ bindings = newBindings;
+ }
+ }
+
+ bindings.add(binding);
+
+ }
+
+ protected void onUnbind(final Binding binding)
+ {
+ assert binding != null;
+
+ CopyOnWriteArraySet<Binding> bindings = _bindingsByKey.get(binding.getBindingKey());
+ if(bindings != null)
+ {
+ bindings.remove(binding);
+ }
+
}
+
+
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeMBean.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeMBean.java
new file mode 100644
index 0000000000..086832c045
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeMBean.java
@@ -0,0 +1,79 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.exchange;
+
+import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
+import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor;
+import org.apache.qpid.server.binding.Binding;
+
+import javax.management.JMException;
+import javax.management.openmbean.*;
+import java.util.List;
+import java.util.Map;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * MBean class implementing the management interfaces.
+ */
+@MBeanDescription("Management Bean for Direct Exchange")
+final class DirectExchangeMBean extends AbstractExchangeMBean<DirectExchange>
+{
+ @MBeanConstructor("Creates an MBean for AMQ direct exchange")
+ public DirectExchangeMBean(final DirectExchange exchange) throws JMException
+ {
+ super(exchange);
+
+ init();
+ }
+
+ public TabularData bindings() throws OpenDataException
+ {
+ TabularDataSupport bindingList = new TabularDataSupport(_bindinglistDataType);
+
+ Map<String, List<String>> bindingMap = new HashMap<String, List<String>>();
+
+ for (Binding binding : getExchange().getBindings())
+ {
+ String key = binding.getBindingKey();
+ List<String> queueList = bindingMap.get(key);
+ if(queueList == null)
+ {
+ queueList = new ArrayList<String>();
+ bindingMap.put(key, queueList);
+ }
+ queueList.add(binding.getQueue().getNameShortString().toString());
+
+ }
+
+ for(Map.Entry<String, List<String>> entry : bindingMap.entrySet())
+ {
+ Object[] bindingItemValues = {entry.getKey(), entry.getValue().toArray(new String[0])};
+ CompositeData bindingData = new CompositeDataSupport(_bindingDataType, COMPOSITE_ITEM_NAMES, bindingItemValues);
+ bindingList.put(bindingData);
+ }
+
+ return bindingList;
+ }
+
+
+
+}// End of MBean class
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java
index 4bbdeaef1c..8a31b1bab1 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java
@@ -25,17 +25,31 @@ import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.message.InboundMessage;
+import org.apache.qpid.server.binding.BindingFactory;
+import org.apache.qpid.server.binding.Binding;
+import org.apache.qpid.server.configuration.ExchangeConfig;
import javax.management.JMException;
import java.util.ArrayList;
+import java.util.List;
+import java.util.Collection;
+import java.util.concurrent.CopyOnWriteArrayList;
-public interface Exchange extends ExchangeReferrer
+public interface Exchange extends ExchangeReferrer, ExchangeConfig
{
- AMQShortString getName();
- AMQShortString getType();
+ public interface BindingListener
+ {
+ void bindingAdded(Exchange exchange, Binding binding);
+ void bindingRemoved(Exchange exchange, Binding binding);
+ }
+
+ AMQShortString getNameShortString();
+
+ AMQShortString getTypeShortString();
void initialise(VirtualHost host, AMQShortString name, boolean durable, int ticket, boolean autoDelete)
throws AMQException, JMException;
@@ -51,13 +65,8 @@ public interface Exchange extends ExchangeReferrer
void close() throws AMQException;
- void registerQueue(AMQShortString routingKey, AMQQueue queue, FieldTable args) throws AMQException;
-
-
- void deregisterQueue(AMQShortString routingKey, AMQQueue queue, FieldTable args) throws AMQException;
-
- ArrayList<AMQQueue> route(InboundMessage message);
+ ArrayList<? extends BaseQueue> route(InboundMessage message);
/**
@@ -101,6 +110,11 @@ public interface Exchange extends ExchangeReferrer
boolean isBound(String bindingKey);
+ void addCloseTask(Task task);
+
+ void removeCloseTask(Task task);
+
+
Exchange getAlternateExchange();
void setAlternateExchange(Exchange exchange);
@@ -110,4 +124,20 @@ public interface Exchange extends ExchangeReferrer
void addReference(ExchangeReferrer exchange);
boolean hasReferrers();
+
+ void addBinding(Binding binding);
+
+ void removeBinding(Binding binding);
+
+ Collection<Binding> getBindings();
+
+ public void addBindingListener(BindingListener listener);
+
+ public void removeBindingListener(BindingListener listener);
+
+
+ public static interface Task
+ {
+ public void onClose(Exchange exchange);
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java
index 00f8ebd856..bd75f7bc51 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java
@@ -21,109 +21,35 @@
package org.apache.qpid.server.exchange;
import org.apache.log4j.Logger;
+
import org.apache.qpid.AMQException;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
-import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.server.binding.Binding;
+import org.apache.qpid.server.message.InboundMessage;
import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.message.InboundMessage;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.actors.ManagementActor;
import javax.management.JMException;
-import javax.management.MBeanException;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.TabularData;
-import javax.management.openmbean.TabularDataSupport;
-import java.util.List;
-import java.util.Map;
import java.util.ArrayList;
-import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.ConcurrentHashMap;
public class FanoutExchange extends AbstractExchange
{
private static final Logger _logger = Logger.getLogger(FanoutExchange.class);
+ private static final Integer ONE = Integer.valueOf(1);
+
/**
* Maps from queue name to queue instances
*/
- private final CopyOnWriteArraySet<AMQQueue> _queues = new CopyOnWriteArraySet<AMQQueue>();
+ private final ConcurrentHashMap<AMQQueue,Integer> _queues = new ConcurrentHashMap<AMQQueue,Integer>();
- /**
- * MBean class implementing the management interfaces.
- */
- @MBeanDescription("Management Bean for Fanout Exchange")
- private final class FanoutExchangeMBean extends ExchangeMBean
+ protected AbstractExchangeMBean createMBean() throws JMException
{
- private static final String BINDING_KEY_SUBSTITUTE = "*";
-
- @MBeanConstructor("Creates an MBean for AMQ fanout exchange")
- public FanoutExchangeMBean() throws JMException
- {
- super();
- _exchangeType = "fanout";
- init();
- }
-
- public TabularData bindings() throws OpenDataException
- {
-
- _bindingList = new TabularDataSupport(_bindinglistDataType);
-
- if(_queues.isEmpty())
- {
- return _bindingList;
- }
-
- ArrayList<String> queueNames = new ArrayList<String>();
-
- for (AMQQueue queue : _queues)
- {
- String queueName = queue.getName().toString();
- queueNames.add(queueName);
- }
-
- Object[] bindingItemValues = {BINDING_KEY_SUBSTITUTE, queueNames.toArray(new String[0])};
- CompositeData bindingData = new CompositeDataSupport(_bindingDataType, COMPOSITE_ITEM_NAMES, bindingItemValues);
- _bindingList.put(bindingData);
-
- return _bindingList;
- }
-
- public void createNewBinding(String queueName, String binding) throws JMException
- {
- AMQQueue queue = getQueueRegistry().getQueue(new AMQShortString(queueName));
- if (queue == null)
- {
- throw new JMException("Queue \"" + queueName + "\" is not registered with the exchange.");
- }
-
- CurrentActor.set(new ManagementActor(_logActor.getRootMessageLogger()));
- try
- {
- queue.bind(FanoutExchange.this, new AMQShortString(BINDING_KEY_SUBSTITUTE), null);
- }
- catch (AMQException ex)
- {
- throw new MBeanException(ex);
- }
- finally
- {
- CurrentActor.remove();
- }
- }
-
- } // End of MBean class
-
- protected ExchangeMBean createMBean() throws JMException
- {
- return new FanoutExchange.FanoutExchangeMBean();
+ return new FanoutExchangeMBean(this);
}
public Logger getLogger()
@@ -161,51 +87,26 @@ public class FanoutExchange extends AbstractExchange
}
};
- public Map<AMQShortString, List<AMQQueue>> getBindings()
+ public FanoutExchange()
{
- return null;
+ super(TYPE);
}
- public AMQShortString getType()
+ public ArrayList<BaseQueue> doRoute(InboundMessage payload)
{
- return ExchangeDefaults.FANOUT_EXCHANGE_CLASS;
- }
-
- public void registerQueue(AMQShortString routingKey, AMQQueue queue, FieldTable args) throws AMQException
- {
- assert queue != null;
- if (_queues.contains(queue))
- {
- _logger.debug("Queue " + queue + " is already registered");
- }
- else
- {
- _queues.add(queue);
- _logger.debug("Binding queue " + queue + " with routing key " + routingKey + " to exchange " + this);
- }
- }
- public void deregisterQueue(AMQShortString routingKey, AMQQueue queue, FieldTable args) throws AMQException
- {
- assert queue != null;
-
- if (!_queues.remove(queue))
+ if (_logger.isDebugEnabled())
{
- throw new AMQException(AMQConstant.NOT_FOUND, "Queue " + queue + " was not registered with exchange " + this.getName() + ". ");
+ _logger.debug("Publishing message to queue " + _queues);
}
- }
- public ArrayList<AMQQueue> route(InboundMessage payload)
- {
-
-
- if (_logger.isDebugEnabled())
+ for(Binding b : getBindings())
{
- _logger.debug("Publishing message to queue " + _queues);
+ b.incrementMatches();
}
- return new ArrayList(_queues);
+ return new ArrayList<BaseQueue>(_queues.keySet());
}
@@ -235,4 +136,71 @@ public class FanoutExchange extends AbstractExchange
{
return !_queues.isEmpty();
}
+
+ protected void onBind(final Binding binding)
+ {
+ AMQQueue queue = binding.getQueue();
+ assert queue != null;
+
+ Integer oldVal;
+
+ if((oldVal = _queues.putIfAbsent(queue, ONE)) != null)
+ {
+ Integer newVal = oldVal+1;
+ while(!_queues.replace(queue, oldVal, newVal))
+ {
+ oldVal = _queues.get(queue);
+ if(oldVal == null)
+ {
+ oldVal = _queues.putIfAbsent(queue, ONE);
+ if(oldVal == null)
+ {
+ break;
+ }
+ }
+ newVal = oldVal + 1;
+ }
+ }
+
+ if (_logger.isDebugEnabled())
+ {
+ _logger.debug("Binding queue " + queue
+ + " with routing key " + new AMQShortString(binding.getBindingKey()) + " to exchange " + this);
+ }
+ }
+
+ protected void onUnbind(final Binding binding)
+ {
+ AMQQueue queue = binding.getQueue();
+ Integer oldValue = _queues.get(queue);
+
+ boolean done = false;
+
+ while(!(done || oldValue == null))
+ {
+ while(!(done || oldValue == null) && oldValue.intValue() == 1)
+ {
+ if(!_queues.remove(queue, oldValue))
+ {
+ oldValue = _queues.get(queue);
+ }
+ else
+ {
+ done = true;
+ }
+ }
+ while(!(done || oldValue == null) && oldValue.intValue() != 1)
+ {
+ Integer newValue = oldValue - 1;
+ if(!_queues.replace(queue, oldValue, newValue))
+ {
+ oldValue = _queues.get(queue);
+ }
+ else
+ {
+ done = true;
+ }
+ }
+ }
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeMBean.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeMBean.java
new file mode 100644
index 0000000000..d5734f76a5
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeMBean.java
@@ -0,0 +1,68 @@
+/*
+ *
+ * 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.exchange;
+
+import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
+import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor;
+import org.apache.qpid.server.binding.Binding;
+
+import javax.management.JMException;
+import javax.management.openmbean.*;
+import java.util.ArrayList;
+
+/**
+ * MBean class implementing the management interfaces.
+ */
+@MBeanDescription("Management Bean for Fanout Exchange")
+final class FanoutExchangeMBean extends AbstractExchangeMBean<FanoutExchange>
+{
+ private static final String BINDING_KEY_SUBSTITUTE = "*";
+
+ @MBeanConstructor("Creates an MBean for AMQ fanout exchange")
+ public FanoutExchangeMBean(final FanoutExchange exchange) throws JMException
+ {
+ super(exchange);
+ init();
+ }
+
+ public TabularData bindings() throws OpenDataException
+ {
+
+ TabularDataSupport bindingList = new TabularDataSupport(_bindinglistDataType);
+
+
+ ArrayList<String> queueNames = new ArrayList<String>();
+
+ for (Binding binding : getExchange().getBindings())
+ {
+ String queueName = binding.getQueue().getNameShortString().toString();
+ queueNames.add(queueName);
+ }
+
+ Object[] bindingItemValues = {BINDING_KEY_SUBSTITUTE, queueNames.toArray(new String[0])};
+ CompositeData bindingData = new CompositeDataSupport(_bindingDataType, COMPOSITE_ITEM_NAMES, bindingItemValues);
+ bindingList.put(bindingData);
+
+ return bindingList;
+ }
+
+
+} // End of MBean class
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java
index 5677cc4510..ce0b14932f 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java
@@ -22,33 +22,20 @@ package org.apache.qpid.server.exchange;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
-import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.AMQTypedValue;
import org.apache.qpid.framing.BasicContentHeaderProperties;
import org.apache.qpid.framing.ContentHeaderBody;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.message.InboundMessage;
import org.apache.qpid.server.message.AMQMessageHeader;
+import org.apache.qpid.server.binding.Binding;
import javax.management.JMException;
-import javax.management.openmbean.ArrayType;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-import javax.management.openmbean.TabularData;
-import javax.management.openmbean.TabularDataSupport;
-import javax.management.openmbean.TabularType;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -119,151 +106,40 @@ public class HeadersExchange extends AbstractExchange
private final List<Registration> _bindings = new CopyOnWriteArrayList<Registration>();
private Map<AMQShortString, Registration> _bindingByKey = new ConcurrentHashMap<AMQShortString, Registration>();
- /**
- * HeadersExchangeMBean class implements the management interface for the
- * Header Exchanges.
- */
- @MBeanDescription("Management Bean for Headers Exchange")
- private final class HeadersExchangeMBean extends ExchangeMBean
- {
- @MBeanConstructor("Creates an MBean for AMQ Headers exchange")
- public HeadersExchangeMBean() throws JMException
- {
- super();
- _exchangeType = "headers";
- init();
- }
-
- /**
- * initialises the OpenType objects.
- */
- protected void init() throws OpenDataException
- {
-
- _bindingItemTypes = new OpenType[3];
- _bindingItemTypes[0] = SimpleType.INTEGER;
- _bindingItemTypes[1] = SimpleType.STRING;
- _bindingItemTypes[2] = new ArrayType(1, SimpleType.STRING);
- _bindingDataType = new CompositeType("Exchange Binding", "Queue name and header bindings",
- HEADERS_COMPOSITE_ITEM_NAMES, HEADERS_COMPOSITE_ITEM_DESC, _bindingItemTypes);
- _bindinglistDataType = new TabularType("Exchange Bindings", "List of exchange bindings for " + getName(),
- _bindingDataType, HEADERS_TABULAR_UNIQUE_INDEX);
- }
-
- public TabularData bindings() throws OpenDataException
- {
- _bindingList = new TabularDataSupport(_bindinglistDataType);
- int count = 1;
- for (Iterator<Registration> itr = _bindings.iterator(); itr.hasNext();)
- {
- Registration registration = itr.next();
- String queueName = registration.queue.getName().toString();
-
- HeadersBinding headers = registration.binding;
- FieldTable headerMappings = headers.getMappings();
- final List<String> mappingList = new ArrayList<String>();
-
- headerMappings.processOverElements(new FieldTable.FieldTableElementProcessor()
- {
-
- public boolean processElement(String propertyName, AMQTypedValue value)
- {
- mappingList.add(propertyName + "=" + value.getValue());
- return true;
- }
-
- public Object getResult()
- {
- return mappingList;
- }
- });
-
- Object[] bindingItemValues = {count++, queueName, mappingList.toArray(new String[0])};
- CompositeData bindingData = new CompositeDataSupport(_bindingDataType, HEADERS_COMPOSITE_ITEM_NAMES, bindingItemValues);
- _bindingList.put(bindingData);
- }
-
- return _bindingList;
- }
-
- /**
- * Creates bindings. Binding pattern is as follows-
- * <attributename>=<value>,<attributename>=<value>,...
- * @param queueName
- * @param binding
- * @throws javax.management.JMException
- */
- public void createNewBinding(String queueName, String binding) throws JMException
- {
- AMQQueue queue = getQueueRegistry().getQueue(new AMQShortString(queueName));
-
- if (queue == null)
- {
- throw new JMException("Queue \"" + queueName + "\" is not registered with the exchange.");
- }
-
- String[] bindings = binding.split(",");
- FieldTable bindingMap = new FieldTable();
- for (int i = 0; i < bindings.length; i++)
- {
- String[] keyAndValue = bindings[i].split("=");
- if (keyAndValue == null || keyAndValue.length == 0 || keyAndValue.length > 2)
- {
- throw new JMException("Format for headers binding should be \"<attribute1>=<value1>,<attribute2>=<value2>\" ");
- }
-
- if(keyAndValue.length ==1)
- {
- //no value was given, only a key. Use an empty value
- //to signal match on key presence alone
- bindingMap.setString(keyAndValue[0], "");
- }
- else
- {
- bindingMap.setString(keyAndValue[0], keyAndValue[1]);
- }
- }
-
- _bindings.add(new Registration(new HeadersBinding(bindingMap), queue, new AMQShortString(binding)));
- }
-
- } // End of MBean class
+ public HeadersExchange()
+ {
+ super(TYPE);
+ }
- public AMQShortString getType()
+ public void registerQueue(String routingKey, AMQQueue queue, Map<String,Object> args)
{
- return ExchangeDefaults.HEADERS_EXCHANGE_CLASS;
+ registerQueue(new AMQShortString(routingKey), queue, FieldTable.convertToFieldTable(args));
}
- public void registerQueue(AMQShortString routingKey, AMQQueue queue, FieldTable args) throws AMQException
+ public void registerQueue(AMQShortString routingKey, AMQQueue queue, FieldTable args)
{
- _logger.debug("Exchange " + getName() + ": Binding " + queue.getName() + " with " + args);
+ _logger.debug("Exchange " + getNameShortString() + ": Binding " + queue.getNameShortString() + " with " + args);
Registration registration = new Registration(new HeadersBinding(args), queue, routingKey);
_bindings.add(registration);
}
- public void deregisterQueue(AMQShortString routingKey, AMQQueue queue, FieldTable args) throws AMQException
+ public void deregisterQueue(String routingKey, AMQQueue queue, Map<String,Object> args)
{
- _logger.debug("Exchange " + getName() + ": Unbinding " + queue.getName());
-
- if(!_bindings.remove(new Registration(args == null ? null : new HeadersBinding(args), queue, routingKey)))
- {
- throw new AMQException(AMQConstant.NOT_FOUND, "Queue " + queue + " was not registered with exchange " + this.getName()
- + " with headers args " + args);
- }
+ _bindings.remove(new Registration(args == null ? null : new HeadersBinding(FieldTable.convertToFieldTable(args)), queue, new AMQShortString(routingKey)));
}
- public ArrayList<AMQQueue> route(InboundMessage payload)
+ public ArrayList<BaseQueue> doRoute(InboundMessage payload)
{
AMQMessageHeader header = payload.getMessageHeader();
if (_logger.isDebugEnabled())
{
- _logger.debug("Exchange " + getName() + ": routing message with headers " + header);
+ _logger.debug("Exchange " + getNameShortString() + ": routing message with headers " + header);
}
boolean routed = false;
- ArrayList<AMQQueue> queues = new ArrayList<AMQQueue>();
+ ArrayList<BaseQueue> queues = new ArrayList<BaseQueue>();
for (Registration e : _bindings)
{
@@ -271,8 +147,8 @@ public class HeadersExchange extends AbstractExchange
{
if (_logger.isDebugEnabled())
{
- _logger.debug("Exchange " + getName() + ": delivering message with headers " +
- header + " to " + e.queue.getName());
+ _logger.debug("Exchange " + getNameShortString() + ": delivering message with headers " +
+ header + " to " + e.queue.getNameShortString());
}
queues.add(e.queue);
@@ -315,6 +191,8 @@ public class HeadersExchange extends AbstractExchange
return !_bindings.isEmpty();
}
+
+
protected FieldTable getHeaders(ContentHeaderBody contentHeaderFrame)
{
//what if the content type is not 'basic'? 'file' and 'stream' content classes also define headers,
@@ -322,14 +200,9 @@ public class HeadersExchange extends AbstractExchange
return ((BasicContentHeaderProperties) contentHeaderFrame.properties).getHeaders();
}
- protected ExchangeMBean createMBean() throws JMException
+ protected AbstractExchangeMBean createMBean() throws JMException
{
- return new HeadersExchangeMBean();
- }
-
- public Map<AMQShortString, List<AMQQueue>> getBindings()
- {
- return null;
+ return new HeadersExchangeMBean(this);
}
public Logger getLogger()
@@ -338,7 +211,7 @@ public class HeadersExchange extends AbstractExchange
}
- private static class Registration
+ static class Registration
{
private final HeadersBinding binding;
private final AMQQueue queue;
@@ -365,5 +238,31 @@ public class HeadersExchange extends AbstractExchange
&& (routingKey == null ? ((Registration)o).routingKey == null
: routingKey.equals(((Registration)o).routingKey));
}
+
+ public HeadersBinding getBinding()
+ {
+ return binding;
+ }
+
+ public AMQQueue getQueue()
+ {
+ return queue;
+ }
+
+ public AMQShortString getRoutingKey()
+ {
+ return routingKey;
+ }
}
+
+ protected void onBind(final Binding binding)
+ {
+ registerQueue(binding.getBindingKey(), binding.getQueue(), binding.getArguments());
+ }
+
+ protected void onUnbind(final Binding binding)
+ {
+ deregisterQueue(binding.getBindingKey(), binding.getQueue(), binding.getArguments());
+ }
+
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeMBean.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeMBean.java
new file mode 100644
index 0000000000..2c7985b480
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeMBean.java
@@ -0,0 +1,96 @@
+/*
+ *
+ * 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.exchange;
+
+import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
+import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor;
+import org.apache.qpid.server.binding.Binding;
+
+import javax.management.JMException;
+import javax.management.openmbean.*;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+
+/**
+ * HeadersExchangeMBean class implements the management interface for the
+ * Header Exchanges.
+ */
+@MBeanDescription("Management Bean for Headers Exchange")
+final class HeadersExchangeMBean extends AbstractExchangeMBean<HeadersExchange>
+{
+
+ @MBeanConstructor("Creates an MBean for AMQ Headers exchange")
+ public HeadersExchangeMBean(final HeadersExchange headersExchange) throws JMException
+ {
+ super(headersExchange);
+ init();
+ }
+
+ /**
+ * initialises the OpenType objects.
+ */
+ protected void init() throws OpenDataException
+ {
+
+ _bindingItemTypes = new OpenType[3];
+ _bindingItemTypes[0] = SimpleType.INTEGER;
+ _bindingItemTypes[1] = SimpleType.STRING;
+ _bindingItemTypes[2] = new ArrayType(1, SimpleType.STRING);
+ _bindingDataType = new CompositeType("Exchange Binding", "Queue name and header bindings",
+ HEADERS_COMPOSITE_ITEM_NAMES, HEADERS_COMPOSITE_ITEM_DESC, _bindingItemTypes);
+ _bindinglistDataType = new TabularType("Exchange Bindings", "List of exchange bindings for " + getName(),
+ _bindingDataType, HEADERS_TABULAR_UNIQUE_INDEX);
+ }
+
+ public TabularData bindings() throws OpenDataException
+ {
+ TabularDataSupport bindingList = new TabularDataSupport(_bindinglistDataType);
+ int count = 1;
+ for (Binding binding : getExchange().getBindings())
+ {
+
+ String queueName = binding.getQueue().getNameShortString().toString();
+
+
+ Map<String,Object> headerMappings = binding.getArguments();
+ final List<String> mappingList = new ArrayList<String>();
+
+ if(headerMappings != null)
+ {
+ for(Map.Entry<String,Object> entry : headerMappings.entrySet())
+ {
+
+ mappingList.add(entry.getKey() + "=" + entry.getValue());
+ }
+ }
+
+
+ Object[] bindingItemValues = {count++, queueName, mappingList.toArray(new String[0])};
+ CompositeData bindingData = new CompositeDataSupport(_bindingDataType, HEADERS_COMPOSITE_ITEM_NAMES, bindingItemValues);
+ bindingList.put(bindingData);
+ }
+
+ return bindingList;
+ }
+
+
+} // End of MBean class
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/Index.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/Index.java
deleted file mode 100644
index 90d04c814a..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/Index.java
+++ /dev/null
@@ -1,114 +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.exchange;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.ArrayList;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.queue.AMQQueue;
-
-/**
- * An index of queues against routing key. Allows multiple queues to be stored
- * against the same key. Used in the DirectExchange.
- */
-class Index
-{
- private ConcurrentMap<AMQShortString, ArrayList<AMQQueue>> _index
- = new ConcurrentHashMap<AMQShortString, ArrayList<AMQQueue>>();
- private ConcurrentMap<String, ArrayList<AMQQueue>> _stringIndex
- = new ConcurrentHashMap<String, ArrayList<AMQQueue>>();
-
-
- synchronized boolean add(AMQShortString key, AMQQueue queue)
- {
- ArrayList<AMQQueue> queues = _index.get(key);
- if(queues == null)
- {
- queues = new ArrayList<AMQQueue>();
- }
- else
- {
- queues = new ArrayList<AMQQueue>(queues);
- }
-
- //next call is atomic, so there is no race to create the list
- _index.put(key, queues);
- _stringIndex.put(key.toString(), queues);
-
- if(queues.contains(queue))
- {
- return false;
- }
- else
- {
- return queues.add(queue);
- }
- }
-
-
-
- synchronized boolean remove(AMQShortString key, AMQQueue queue)
- {
- ArrayList<AMQQueue> queues = _index.get(key);
- if (queues != null)
- {
- queues = new ArrayList<AMQQueue>(queues);
- boolean removed = queues.remove(queue);
- if(removed)
- {
- if (queues.size() == 0)
- {
- _index.remove(key);
- _stringIndex.remove(key.toString());
- }
- else
- {
- _index.put(key, queues);
- _stringIndex.put(key.toString(), queues);
- }
- }
- return removed;
- }
- return false;
- }
-
- ArrayList<AMQQueue> get(AMQShortString key)
- {
- return _index.get(key);
- }
-
- ArrayList<AMQQueue> get(String key)
- {
- return _stringIndex.get(key);
- }
-
-
- Map<AMQShortString, List<AMQQueue>> getBindingsMap()
- {
- return new HashMap<AMQShortString, List<AMQQueue>>(_index);
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java
index d5ca5a8a81..14f15dd92c 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java
@@ -21,32 +21,21 @@
package org.apache.qpid.server.exchange;
import org.apache.log4j.Logger;
+
import org.apache.qpid.AMQException;
+import org.apache.qpid.AMQInvalidArgumentException;
import org.apache.qpid.common.AMQPFilterTypes;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
-import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.framing.AMQShortStringTokenizer;
import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.exchange.topic.TopicParser;
-import org.apache.qpid.server.exchange.topic.TopicMatcherResult;
-import org.apache.qpid.server.filter.MessageFilter;
+import org.apache.qpid.server.exchange.topic.*;
import org.apache.qpid.server.filter.JMSSelectorFilter;
import org.apache.qpid.server.message.InboundMessage;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.actors.ManagementActor;
import javax.management.JMException;
-import javax.management.MBeanException;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.TabularData;
-import javax.management.openmbean.TabularDataSupport;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.lang.ref.WeakReference;
@@ -87,314 +76,45 @@ public class TopicExchange extends AbstractExchange
private static final Logger _logger = Logger.getLogger(TopicExchange.class);
-/*
- private final ConcurrentHashMap<AMQShortString, List<AMQQueue>> _bindingKey2queues =
- new ConcurrentHashMap<AMQShortString, List<AMQQueue>>();
- private final ConcurrentHashMap<AMQShortString, List<AMQQueue>> _simpleBindingKey2queues =
- new ConcurrentHashMap<AMQShortString, List<AMQQueue>>();
- private final ConcurrentHashMap<AMQShortString, List<AMQQueue>> _wildCardBindingKey2queues =
- new ConcurrentHashMap<AMQShortString, List<AMQQueue>>();
-*/
- // private ConcurrentHashMap<AMQShortString, AMQQueue> _routingKey2queue = new ConcurrentHashMap<AMQShortString, AMQQueue>();
- private static final byte TOPIC_SEPARATOR = (byte)'.';
- private static final AMQShortString TOPIC_SEPARATOR_AS_SHORTSTRING = new AMQShortString(".");
- private static final AMQShortString AMQP_STAR_TOKEN = new AMQShortString("*");
- private static final AMQShortString AMQP_HASH_TOKEN = new AMQShortString("#");
-
- private static final byte HASH_BYTE = (byte)'#';
- private static final byte STAR_BYTE = (byte)'*';
+
private final TopicParser _parser = new TopicParser();
private final Map<AMQShortString, TopicExchangeResult> _topicExchangeResults =
new ConcurrentHashMap<AMQShortString, TopicExchangeResult>();
- private final Map<Binding, FieldTable> _bindings = new HashMap<Binding, FieldTable>();
+ private final Map<TopicBinding, FieldTable> _bindings = new HashMap<TopicBinding, FieldTable>();
private final Map<String, WeakReference<JMSSelectorFilter>> _selectorCache = new WeakHashMap<String, WeakReference<JMSSelectorFilter>>();
- public static class Binding
+ public TopicExchange()
{
- private final AMQShortString _bindingKey;
- private final AMQQueue _queue;
- private final FieldTable _args;
-
- public Binding(AMQShortString bindingKey, AMQQueue queue, FieldTable args)
- {
- _bindingKey = bindingKey;
- _queue = queue;
- _args = args;
- }
-
- public AMQShortString getBindingKey()
- {
- return _bindingKey;
- }
-
- public AMQQueue getQueue()
- {
- return _queue;
- }
-
- public int hashCode()
- {
- return (_bindingKey == null ? 1 : _bindingKey.hashCode())*31 +_queue.hashCode();
- }
-
- public boolean equals(Object o)
- {
- if(this == o)
- {
- return true;
- }
- if(o instanceof Binding)
- {
- Binding other = (Binding) o;
- return (_queue == other._queue)
- && ((_bindingKey == null) ? other._bindingKey == null : _bindingKey.equals(other._bindingKey));
- }
- return false;
- }
- }
-
-
-
- private final class TopicExchangeResult implements TopicMatcherResult
- {
- private final Map<AMQQueue, Integer> _unfilteredQueues = new ConcurrentHashMap<AMQQueue, Integer>();
- private final ConcurrentHashMap<AMQQueue, Map<MessageFilter,Integer>> _filteredQueues = new ConcurrentHashMap<AMQQueue, Map<MessageFilter, Integer>>();
-
- public void addUnfilteredQueue(AMQQueue queue)
- {
- Integer instances = _unfilteredQueues.get(queue);
- if(instances == null)
- {
- _unfilteredQueues.put(queue, 1);
- }
- else
- {
- _unfilteredQueues.put(queue, instances + 1);
- }
- }
-
- public void removeUnfilteredQueue(AMQQueue queue)
- {
- Integer instances = _unfilteredQueues.get(queue);
- if(instances == 1)
- {
- _unfilteredQueues.remove(queue);
- }
- else
- {
- _unfilteredQueues.put(queue,instances - 1);
- }
-
- }
-
-
- public void addFilteredQueue(AMQQueue queue, MessageFilter filter)
- {
- Map<MessageFilter,Integer> filters = _filteredQueues.get(queue);
- if(filters == null)
- {
- filters = new ConcurrentHashMap<MessageFilter,Integer>();
- _filteredQueues.put(queue, filters);
- }
- Integer instances = filters.get(filter);
- if(instances == null)
- {
- filters.put(filter,1);
- }
- else
- {
- filters.put(filter, instances + 1);
- }
-
- }
-
- public void removeFilteredQueue(AMQQueue queue, MessageFilter filter)
- {
- Map<MessageFilter,Integer> filters = _filteredQueues.get(queue);
- if(filters != null)
- {
- Integer instances = filters.get(filter);
- if(instances != null)
- {
- if(instances == 1)
- {
- filters.remove(filter);
- if(filters.isEmpty())
- {
- _filteredQueues.remove(queue);
- }
- }
- else
- {
- filters.put(filter, instances - 1);
- }
- }
-
- }
-
- }
-
- public void replaceQueueFilter(AMQQueue queue,
- MessageFilter oldFilter,
- MessageFilter newFilter)
- {
- Map<MessageFilter,Integer> filters = _filteredQueues.get(queue);
- Map<MessageFilter,Integer> newFilters = new ConcurrentHashMap<MessageFilter,Integer>(filters);
- Integer oldFilterInstances = filters.get(oldFilter);
- if(oldFilterInstances == 1)
- {
- newFilters.remove(oldFilter);
- }
- else
- {
- newFilters.put(oldFilter, oldFilterInstances-1);
- }
- Integer newFilterInstances = filters.get(newFilter);
- if(newFilterInstances == null)
- {
- newFilters.put(newFilter, 1);
- }
- else
- {
- newFilters.put(newFilter, newFilterInstances+1);
- }
- _filteredQueues.put(queue,newFilters);
- }
-
- public Collection<AMQQueue> processMessage(InboundMessage msg, Collection<AMQQueue> queues)
- {
- if(queues == null)
- {
- if(_filteredQueues.isEmpty())
- {
- return new ArrayList<AMQQueue>(_unfilteredQueues.keySet());
- }
- else
- {
- queues = new HashSet<AMQQueue>();
- }
- }
- else if(!(queues instanceof Set))
- {
- queues = new HashSet<AMQQueue>(queues);
- }
-
- queues.addAll(_unfilteredQueues.keySet());
- if(!_filteredQueues.isEmpty())
- {
- for(Map.Entry<AMQQueue, Map<MessageFilter, Integer>> entry : _filteredQueues.entrySet())
- {
- if(!queues.contains(entry.getKey()))
- {
- for(MessageFilter filter : entry.getValue().keySet())
- {
- if(filter.matches(msg))
- {
- queues.add(entry.getKey());
- }
- }
- }
- }
- }
- return queues;
- }
-
+ super(TYPE);
}
-
- /** TopicExchangeMBean class implements the management interface for the Topic exchanges. */
- @MBeanDescription("Management Bean for Topic Exchange")
- private final class TopicExchangeMBean extends ExchangeMBean
+ public synchronized void registerQueue(String rKey, AMQQueue queue, Map<String,Object> args)
{
- @MBeanConstructor("Creates an MBean for AMQ topic exchange")
- public TopicExchangeMBean() throws JMException
+ try
{
- super();
- _exchangeType = "topic";
- init();
+ registerQueue(new AMQShortString(rKey), queue, FieldTable.convertToFieldTable(args));
}
-
- /** returns exchange bindings in tabular form */
- public TabularData bindings() throws OpenDataException
+ catch (AMQInvalidArgumentException e)
{
- _bindingList = new TabularDataSupport(_bindinglistDataType);
- Map<String, List<String>> bindingData = new HashMap<String, List<String>>();
- for (Binding binding : _bindings.keySet())
- {
- String key = binding.getBindingKey().toString();
- List<String> queueNames = bindingData.get(key);
- if(queueNames == null)
- {
- queueNames = new ArrayList<String>();
- bindingData.put(key, queueNames);
- }
- queueNames.add(binding.getQueue().getName().toString());
-
- }
- for(Map.Entry<String, List<String>> entry : bindingData.entrySet())
- {
- Object[] bindingItemValues = {entry.getKey(), entry.getValue().toArray(new String[entry.getValue().size()]) };
- CompositeData bindingCompositeData = new CompositeDataSupport(_bindingDataType, COMPOSITE_ITEM_NAMES, bindingItemValues);
- _bindingList.put(bindingCompositeData);
- }
-
- return _bindingList;
+ throw new RuntimeException(e);
}
-
- public void createNewBinding(String queueName, String binding) throws JMException
- {
- AMQQueue queue = getQueueRegistry().getQueue(new AMQShortString(queueName));
- if (queue == null)
- {
- throw new JMException("Queue \"" + queueName + "\" is not registered with the exchange.");
- }
-
- CurrentActor.set(new ManagementActor(_logActor.getRootMessageLogger()));
- try
- {
- queue.bind(TopicExchange.this, new AMQShortString(binding), null);
- }
- catch (AMQException ex)
- {
- throw new MBeanException(ex);
- }
- finally
- {
- CurrentActor.remove();
- }
- }
-
- } // End of MBean class
-
- public AMQShortString getType()
- {
- return ExchangeDefaults.TOPIC_EXCHANGE_CLASS;
}
- public synchronized void registerQueue(AMQShortString rKey, AMQQueue queue, FieldTable args) throws AMQException
+ public synchronized void registerQueue(AMQShortString rKey, AMQQueue queue, FieldTable args) throws AMQInvalidArgumentException
{
assert queue != null;
assert rKey != null;
- _logger.debug("Registering queue " + queue.getName() + " with routing key " + rKey);
+ _logger.debug("Registering queue " + queue.getNameShortString() + " with routing key " + rKey);
- AMQShortString routingKey;
+ AMQShortString routingKey = TopicNormalizer.normalize(rKey);
- if(rKey.contains(HASH_BYTE) || rKey.contains(STAR_BYTE))
- {
- routingKey = normalize(rKey);
- }
- else
- {
- routingKey = rKey;
- }
-
- Binding binding = new Binding(rKey, queue, args);
+ TopicBinding binding = new TopicBinding(rKey, queue, args);
if(_bindings.containsKey(binding))
{
@@ -463,8 +183,7 @@ public class TopicExchange extends AbstractExchange
}
- private JMSSelectorFilter createSelectorFilter(final FieldTable args)
- throws AMQException
+ private JMSSelectorFilter createSelectorFilter(final FieldTable args) throws AMQInvalidArgumentException
{
final String selectorString = args.getString(AMQPFilterTypes.JMS_SELECTOR.getValue());
@@ -484,58 +203,7 @@ public class TopicExchange extends AbstractExchange
return args != null && args.containsKey(AMQPFilterTypes.JMS_SELECTOR.getValue()) && args.getString(AMQPFilterTypes.JMS_SELECTOR.getValue()).trim().length() != 0;
}
- private AMQShortString normalize(AMQShortString routingKey)
- {
- if(routingKey == null)
- {
- routingKey = AMQShortString.EMPTY_STRING;
- }
-
- AMQShortStringTokenizer routingTokens = routingKey.tokenize(TOPIC_SEPARATOR);
-
- List<AMQShortString> subscriptionList = new ArrayList<AMQShortString>();
-
- while (routingTokens.hasMoreTokens())
- {
- subscriptionList.add(routingTokens.nextToken());
- }
-
- int size = subscriptionList.size();
-
- for (int index = 0; index < size; index++)
- {
- // if there are more levels
- if ((index + 1) < size)
- {
- if (subscriptionList.get(index).equals(AMQP_HASH_TOKEN))
- {
- if (subscriptionList.get(index + 1).equals(AMQP_HASH_TOKEN))
- {
- // we don't need #.# delete this one
- subscriptionList.remove(index);
- size--;
- // redo this normalisation
- index--;
- }
-
- if (subscriptionList.get(index + 1).equals(AMQP_STAR_TOKEN))
- {
- // we don't want #.* swap to *.#
- // remove it and put it in at index + 1
- subscriptionList.add(index + 1, subscriptionList.remove(index));
- }
- }
- } // if we have more levels
- }
-
-
-
- AMQShortString normalizedString = AMQShortString.join(subscriptionList, TOPIC_SEPARATOR_AS_SHORTSTRING);
-
- return normalizedString;
- }
-
- public ArrayList<AMQQueue> route(InboundMessage payload)
+ public ArrayList<BaseQueue> doRoute(InboundMessage payload)
{
final AMQShortString routingKey = payload.getRoutingKey() == null
@@ -544,7 +212,7 @@ public class TopicExchange extends AbstractExchange
// The copy here is unfortunate, but not too bad relevant to the amount of
// things created and copied in getMatchedQueues
- ArrayList<AMQQueue> queues = new ArrayList<AMQQueue>();
+ ArrayList<BaseQueue> queues = new ArrayList<BaseQueue>();
queues.addAll(getMatchedQueues(payload, routingKey));
if(queues == null || queues.isEmpty())
@@ -558,7 +226,7 @@ public class TopicExchange extends AbstractExchange
public boolean isBound(AMQShortString routingKey, FieldTable arguments, AMQQueue queue)
{
- Binding binding = new Binding(routingKey, queue, arguments);
+ TopicBinding binding = new TopicBinding(routingKey, queue, arguments);
if (arguments == null)
{
return _bindings.containsKey(binding);
@@ -585,7 +253,7 @@ public class TopicExchange extends AbstractExchange
public boolean isBound(AMQShortString routingKey)
{
- for(Binding b : _bindings.keySet())
+ for(TopicBinding b : _bindings.keySet())
{
if(b.getBindingKey().equals(routingKey))
{
@@ -598,7 +266,7 @@ public class TopicExchange extends AbstractExchange
public boolean isBound(AMQQueue queue)
{
- for(Binding b : _bindings.keySet())
+ for(TopicBinding b : _bindings.keySet())
{
if(b.getQueue().equals(queue))
{
@@ -614,37 +282,45 @@ public class TopicExchange extends AbstractExchange
return !_bindings.isEmpty();
}
- public synchronized void deregisterQueue(AMQShortString rKey, AMQQueue queue, FieldTable args) throws AMQException
- {
- assert queue != null;
- assert rKey != null;
-
- Binding binding = new Binding(rKey, queue, args);
-
- if (!_bindings.containsKey(binding))
- {
- throw new AMQException(AMQConstant.NOT_FOUND, "Queue " + queue.getName() + " was not registered with exchange " + this.getName()
- + " with routing key " + rKey + ".");
- }
+ public void deregisterQueue(String rKey, AMQQueue queue, Map<String, Object> args)
+ {
+ removeBinding(new TopicBinding(new AMQShortString(rKey), queue, FieldTable.convertToFieldTable(args)));
+ }
- FieldTable bindingArgs = _bindings.remove(binding);
- AMQShortString bindingKey = normalize(rKey);
- TopicExchangeResult result = _topicExchangeResults.get(bindingKey);
- if(argumentsContainSelector(bindingArgs))
+ private boolean removeBinding(final TopicBinding binding)
+ {
+ if(_bindings.containsKey(binding))
{
- result.removeFilteredQueue(queue, createSelectorFilter(bindingArgs));
+ FieldTable bindingArgs = _bindings.remove(binding);
+ AMQShortString bindingKey = TopicNormalizer.normalize(binding.getBindingKey());
+ TopicExchangeResult result = _topicExchangeResults.get(bindingKey);
+ if(argumentsContainSelector(bindingArgs))
+ {
+ try
+ {
+ result.removeFilteredQueue(binding.getQueue(), createSelectorFilter(bindingArgs));
+ }
+ catch (AMQInvalidArgumentException e)
+ {
+ return false;
+ }
+ }
+ else
+ {
+ result.removeUnfilteredQueue(binding.getQueue());
+ }
+ return true;
}
else
{
- result.removeUnfilteredQueue(queue);
+ return false;
}
-
}
- protected ExchangeMBean createMBean() throws JMException
+ protected AbstractExchangeMBean createMBean() throws JMException
{
- return new TopicExchangeMBean();
+ return new TopicExchangeMBean(this);
}
public Logger getLogger()
@@ -673,4 +349,15 @@ public class TopicExchange extends AbstractExchange
}
+
+ protected void onBind(final org.apache.qpid.server.binding.Binding binding)
+ {
+ registerQueue(binding.getBindingKey(),binding.getQueue(),binding.getArguments());
+ }
+
+ protected void onUnbind(final org.apache.qpid.server.binding.Binding binding)
+ {
+ deregisterQueue(binding.getBindingKey(),binding.getQueue(),binding.getArguments());
+ }
+
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeMBean.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeMBean.java
new file mode 100644
index 0000000000..de39822ff7
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeMBean.java
@@ -0,0 +1,74 @@
+/*
+ *
+ * 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.exchange;
+
+import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
+import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor;
+import org.apache.qpid.server.binding.Binding;
+
+import javax.management.JMException;
+import javax.management.openmbean.*;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.ArrayList;
+
+/** TopicExchangeMBean class implements the management interface for the Topic exchanges. */
+@MBeanDescription("Management Bean for Topic Exchange")
+final class TopicExchangeMBean extends AbstractExchangeMBean<TopicExchange>
+{
+ private TopicExchange _topicExchange;
+
+ @MBeanConstructor("Creates an MBean for AMQ topic exchange")
+ public TopicExchangeMBean(final TopicExchange topicExchange) throws JMException
+ {
+ super(topicExchange);
+ init();
+ }
+
+ /** returns exchange bindings in tabular form */
+ public TabularData bindings() throws OpenDataException
+ {
+ TabularDataSupport bindingList = new TabularDataSupport(_bindinglistDataType);
+ Map<String, List<String>> bindingData = new HashMap<String, List<String>>();
+ for (Binding binding : getExchange().getBindings())
+ {
+ String key = binding.getBindingKey();
+ List<String> queueNames = bindingData.get(key);
+ if(queueNames == null)
+ {
+ queueNames = new ArrayList<String>();
+ bindingData.put(key, queueNames);
+ }
+ queueNames.add(binding.getQueue().getNameShortString().toString());
+
+ }
+ for(Map.Entry<String, List<String>> entry : bindingData.entrySet())
+ {
+ Object[] bindingItemValues = {entry.getKey(), entry.getValue().toArray(new String[entry.getValue().size()]) };
+ CompositeData bindingCompositeData = new CompositeDataSupport(_bindingDataType, COMPOSITE_ITEM_NAMES, bindingItemValues);
+ bindingList.put(bindingCompositeData);
+ }
+
+ return bindingList;
+ }
+
+} // End of MBean class
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicBinding.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicBinding.java
new file mode 100644
index 0000000000..c6383a886e
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicBinding.java
@@ -0,0 +1,70 @@
+/*
+ *
+ * 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.exchange.topic;
+
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.exchange.TopicExchange;
+
+public class TopicBinding
+{
+ private final AMQShortString _bindingKey;
+ private final AMQQueue _queue;
+ private final FieldTable _args;
+
+ public TopicBinding(AMQShortString bindingKey, AMQQueue queue, FieldTable args)
+ {
+ _bindingKey = bindingKey;
+ _queue = queue;
+ _args = args;
+ }
+
+ public AMQShortString getBindingKey()
+ {
+ return _bindingKey;
+ }
+
+ public AMQQueue getQueue()
+ {
+ return _queue;
+ }
+
+ public int hashCode()
+ {
+ return (_bindingKey == null ? 1 : _bindingKey.hashCode())*31 +_queue.hashCode();
+ }
+
+ public boolean equals(Object o)
+ {
+ if(this == o)
+ {
+ return true;
+ }
+ if(o instanceof TopicBinding)
+ {
+ TopicBinding other = (TopicBinding) o;
+ return (_queue == other._queue)
+ && ((_bindingKey == null) ? other._bindingKey == null : _bindingKey.equals(other._bindingKey));
+ }
+ return false;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicExchangeResult.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicExchangeResult.java
new file mode 100644
index 0000000000..d9a779802f
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicExchangeResult.java
@@ -0,0 +1,179 @@
+/*
+ *
+ * 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.exchange.topic;
+
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.filter.MessageFilter;
+import org.apache.qpid.server.message.InboundMessage;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+public final class TopicExchangeResult implements TopicMatcherResult
+{
+ private final Map<AMQQueue, Integer> _unfilteredQueues = new ConcurrentHashMap<AMQQueue, Integer>();
+ private final ConcurrentHashMap<AMQQueue, Map<MessageFilter,Integer>> _filteredQueues = new ConcurrentHashMap<AMQQueue, Map<MessageFilter, Integer>>();
+
+ public void addUnfilteredQueue(AMQQueue queue)
+ {
+ Integer instances = _unfilteredQueues.get(queue);
+ if(instances == null)
+ {
+ _unfilteredQueues.put(queue, 1);
+ }
+ else
+ {
+ _unfilteredQueues.put(queue, instances + 1);
+ }
+ }
+
+ public void removeUnfilteredQueue(AMQQueue queue)
+ {
+ Integer instances = _unfilteredQueues.get(queue);
+ if(instances == 1)
+ {
+ _unfilteredQueues.remove(queue);
+ }
+ else
+ {
+ _unfilteredQueues.put(queue,instances - 1);
+ }
+
+ }
+
+ public Collection<AMQQueue> getUnfilteredQueues()
+ {
+ return _unfilteredQueues.keySet();
+ }
+
+
+ public void addFilteredQueue(AMQQueue queue, MessageFilter filter)
+ {
+ Map<MessageFilter,Integer> filters = _filteredQueues.get(queue);
+ if(filters == null)
+ {
+ filters = new ConcurrentHashMap<MessageFilter,Integer>();
+ _filteredQueues.put(queue, filters);
+ }
+ Integer instances = filters.get(filter);
+ if(instances == null)
+ {
+ filters.put(filter,1);
+ }
+ else
+ {
+ filters.put(filter, instances + 1);
+ }
+
+ }
+
+ public void removeFilteredQueue(AMQQueue queue, MessageFilter filter)
+ {
+ Map<MessageFilter,Integer> filters = _filteredQueues.get(queue);
+ if(filters != null)
+ {
+ Integer instances = filters.get(filter);
+ if(instances != null)
+ {
+ if(instances == 1)
+ {
+ filters.remove(filter);
+ if(filters.isEmpty())
+ {
+ _filteredQueues.remove(queue);
+ }
+ }
+ else
+ {
+ filters.put(filter, instances - 1);
+ }
+ }
+
+ }
+
+ }
+
+ public void replaceQueueFilter(AMQQueue queue,
+ MessageFilter oldFilter,
+ MessageFilter newFilter)
+ {
+ Map<MessageFilter,Integer> filters = _filteredQueues.get(queue);
+ Map<MessageFilter,Integer> newFilters = new ConcurrentHashMap<MessageFilter,Integer>(filters);
+ Integer oldFilterInstances = filters.get(oldFilter);
+ if(oldFilterInstances == 1)
+ {
+ newFilters.remove(oldFilter);
+ }
+ else
+ {
+ newFilters.put(oldFilter, oldFilterInstances-1);
+ }
+ Integer newFilterInstances = filters.get(newFilter);
+ if(newFilterInstances == null)
+ {
+ newFilters.put(newFilter, 1);
+ }
+ else
+ {
+ newFilters.put(newFilter, newFilterInstances+1);
+ }
+ _filteredQueues.put(queue,newFilters);
+ }
+
+ public Collection<AMQQueue> processMessage(InboundMessage msg, Collection<AMQQueue> queues)
+ {
+ if(queues == null)
+ {
+ if(_filteredQueues.isEmpty())
+ {
+ return new ArrayList<AMQQueue>(_unfilteredQueues.keySet());
+ }
+ else
+ {
+ queues = new HashSet<AMQQueue>();
+ }
+ }
+ else if(!(queues instanceof Set))
+ {
+ queues = new HashSet<AMQQueue>(queues);
+ }
+
+ queues.addAll(_unfilteredQueues.keySet());
+ if(!_filteredQueues.isEmpty())
+ {
+ for(Map.Entry<AMQQueue, Map<MessageFilter, Integer>> entry : _filteredQueues.entrySet())
+ {
+ if(!queues.contains(entry.getKey()))
+ {
+ for(MessageFilter filter : entry.getValue().keySet())
+ {
+ if(filter.matches(msg))
+ {
+ queues.add(entry.getKey());
+ }
+ }
+ }
+ }
+ }
+ return queues;
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicNormalizer.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicNormalizer.java
new file mode 100644
index 0000000000..7e7cb6c0ae
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicNormalizer.java
@@ -0,0 +1,96 @@
+/*
+ *
+ * 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.exchange.topic;
+
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.AMQShortStringTokenizer;
+import org.apache.qpid.server.exchange.TopicExchange;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public class TopicNormalizer
+{
+ private static final byte TOPIC_SEPARATOR = (byte)'.';
+ private static final byte HASH_BYTE = (byte)'#';
+ private static final byte STAR_BYTE = (byte)'*';
+
+ private static final AMQShortString TOPIC_SEPARATOR_AS_SHORTSTRING = new AMQShortString(".");
+ private static final AMQShortString AMQP_STAR_TOKEN = new AMQShortString("*");
+ private static final AMQShortString AMQP_HASH_TOKEN = new AMQShortString("#");
+
+ public static AMQShortString normalize(AMQShortString routingKey)
+ {
+ if(routingKey == null)
+ {
+ return AMQShortString.EMPTY_STRING;
+ }
+ else if(!(routingKey.contains(HASH_BYTE) || routingKey.contains(STAR_BYTE)))
+ {
+ return routingKey;
+ }
+ else
+ {
+ AMQShortStringTokenizer routingTokens = routingKey.tokenize(TOPIC_SEPARATOR);
+
+ List<AMQShortString> subscriptionList = new ArrayList<AMQShortString>();
+
+ while (routingTokens.hasMoreTokens())
+ {
+ subscriptionList.add(routingTokens.nextToken());
+ }
+
+ int size = subscriptionList.size();
+
+ for (int index = 0; index < size; index++)
+ {
+ // if there are more levels
+ if ((index + 1) < size)
+ {
+ if (subscriptionList.get(index).equals(AMQP_HASH_TOKEN))
+ {
+ if (subscriptionList.get(index + 1).equals(AMQP_HASH_TOKEN))
+ {
+ // we don't need #.# delete this one
+ subscriptionList.remove(index);
+ size--;
+ // redo this normalisation
+ index--;
+ }
+
+ if (subscriptionList.get(index + 1).equals(AMQP_STAR_TOKEN))
+ {
+ // we don't want #.* swap to *.#
+ // remove it and put it in at index + 1
+ subscriptionList.add(index + 1, subscriptionList.remove(index));
+ }
+ }
+ } // if we have more levels
+ }
+
+
+
+ AMQShortString normalizedString = AMQShortString.join(subscriptionList, TOPIC_SEPARATOR_AS_SHORTSTRING);
+
+ return normalizedString;
+ }
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java b/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java
new file mode 100644
index 0000000000..c97d71dc39
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java
@@ -0,0 +1,807 @@
+/*
+ *
+ * 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.federation;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.server.binding.Binding;
+import org.apache.qpid.server.configuration.BridgeConfig;
+import org.apache.qpid.server.configuration.BridgeConfigType;
+import org.apache.qpid.server.configuration.ConfiguredObject;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.exchange.ExchangeRegistry;
+import org.apache.qpid.server.flow.FlowCreditManager_0_10;
+import org.apache.qpid.server.flow.WindowCreditManager;
+import org.apache.qpid.server.message.MessageMetaData_0_10;
+import org.apache.qpid.server.message.MessageTransferMessage;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.queue.AMQQueueFactory;
+import org.apache.qpid.server.queue.BaseQueue;
+import org.apache.qpid.server.queue.QueueRegistry;
+import org.apache.qpid.server.store.MessageStore;
+import org.apache.qpid.server.store.StoredMessage;
+import org.apache.qpid.server.subscription.Subscription_0_10;
+import org.apache.qpid.server.transport.ServerSession;
+import org.apache.qpid.server.txn.AutoCommitTransaction;
+import org.apache.qpid.server.txn.ServerTransaction;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.transport.DeliveryProperties;
+import org.apache.qpid.transport.MessageAcceptMode;
+import org.apache.qpid.transport.MessageAcquireMode;
+import org.apache.qpid.transport.MessageCreditUnit;
+import org.apache.qpid.transport.MessageFlowMode;
+import org.apache.qpid.transport.MessageReject;
+import org.apache.qpid.transport.MessageRejectCode;
+import org.apache.qpid.transport.MessageTransfer;
+import org.apache.qpid.transport.Option;
+import org.apache.qpid.transport.RangeSet;
+import org.apache.qpid.transport.Session;
+import org.apache.qpid.transport.SessionException;
+import org.apache.qpid.transport.SessionListener;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+public class Bridge implements BridgeConfig
+{
+ private final boolean _durable;
+ private final boolean _dynamic;
+ private final boolean _queueBridge;
+ private final boolean _localSource;
+ private final String _source;
+ private final String _destination;
+ private final String _key;
+ private final String _tag;
+ private final String _excludes;
+ private final BrokerLink _link;
+ private UUID _id;
+ private long _createTime = System.currentTimeMillis();
+
+ private Session _session;
+
+ private BridgeImpl _delegate;
+
+ private final int _bridgeNo;
+ private AutoCommitTransaction _transaction;
+
+ public Bridge(final BrokerLink brokerLink,
+ final int bridgeNo,
+ final boolean durable,
+ final boolean dynamic,
+ final boolean srcIsQueue,
+ final boolean srcIsLocal,
+ final String src,
+ final String dest,
+ final String key,
+ final String tag,
+ final String excludes)
+ {
+ _link = brokerLink;
+ _bridgeNo = bridgeNo;
+ _durable = durable;
+ _dynamic = dynamic;
+ _queueBridge = srcIsQueue;
+ _localSource = srcIsLocal;
+ _source = src;
+ _destination = dest;
+ _key = key;
+ _tag = tag;
+ _excludes = excludes;
+ _id = brokerLink.getConfigStore().createId();
+
+ _transaction = new AutoCommitTransaction(getVirtualHost().getMessageStore());
+
+ if(dynamic)
+ {
+ if(srcIsLocal)
+ {
+ // TODO
+ }
+ else
+ {
+ if(srcIsQueue)
+ {
+ // TODO
+ }
+ else
+ {
+ _delegate = new DynamicExchangeBridge();
+ }
+ }
+ }
+ else
+ {
+ if(srcIsLocal)
+ {
+ if(srcIsQueue)
+ {
+ _delegate = new StaticQueuePushBridge();
+ }
+ else
+ {
+ _delegate = new StaticExchangePushBridge();
+ }
+ }
+ else
+ {
+ if(srcIsQueue)
+ {
+ _delegate = new StaticQueuePullBridge();
+ }
+ else
+ {
+ _delegate = new StaticExchangePullBridge();
+ }
+ }
+ }
+ }
+
+ public UUID getId()
+ {
+ return _id;
+ }
+
+ public BridgeConfigType getConfigType()
+ {
+ return BridgeConfigType.getInstance();
+ }
+
+ public ConfiguredObject getParent()
+ {
+ return getLink();
+ }
+
+ public boolean isDurable()
+ {
+ return _durable;
+ }
+
+ public boolean isDynamic()
+ {
+ return _dynamic;
+ }
+
+ public boolean isQueueBridge()
+ {
+ return _queueBridge;
+ }
+
+ public boolean isLocalSource()
+ {
+ return _localSource;
+ }
+
+ public String getSource()
+ {
+ return _source;
+ }
+
+ public String getDestination()
+ {
+ return _destination;
+ }
+
+ public String getKey()
+ {
+ return _key;
+ }
+
+ public String getTag()
+ {
+ return _tag;
+ }
+
+ public String getExcludes()
+ {
+ return _excludes;
+ }
+
+ public BrokerLink getLink()
+ {
+ return _link;
+ }
+
+ public Integer getChannelId()
+ {
+ return (_session == null) ? 0 : _session.getChannel();
+ }
+
+ public int getAckBatching()
+ {
+ return 0;
+ }
+
+ public long getCreateTime()
+ {
+ return _createTime;
+ }
+
+ @Override
+ public boolean equals(final Object o)
+ {
+ if (this == o)
+ {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass())
+ {
+ return false;
+ }
+
+ final Bridge bridge = (Bridge) o;
+
+ if (_durable != bridge._durable)
+ {
+ return false;
+ }
+ if (_dynamic != bridge._dynamic)
+ {
+ return false;
+ }
+ if (_localSource != bridge._localSource)
+ {
+ return false;
+ }
+ if (_queueBridge != bridge._queueBridge)
+ {
+ return false;
+ }
+ if (_destination != null ? !_destination.equals(bridge._destination) : bridge._destination != null)
+ {
+ return false;
+ }
+ if (_excludes != null ? !_excludes.equals(bridge._excludes) : bridge._excludes != null)
+ {
+ return false;
+ }
+ if (_key != null ? !_key.equals(bridge._key) : bridge._key != null)
+ {
+ return false;
+ }
+ if (_source != null ? !_source.equals(bridge._source) : bridge._source != null)
+ {
+ return false;
+ }
+ if (_tag != null ? !_tag.equals(bridge._tag) : bridge._tag != null)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int result = (_durable ? 1 : 0);
+ result = 31 * result + (_dynamic ? 1 : 0);
+ result = 31 * result + (_queueBridge ? 1 : 0);
+ result = 31 * result + (_localSource ? 1 : 0);
+ result = 31 * result + (_source != null ? _source.hashCode() : 0);
+ result = 31 * result + (_destination != null ? _destination.hashCode() : 0);
+ result = 31 * result + (_key != null ? _key.hashCode() : 0);
+ result = 31 * result + (_tag != null ? _tag.hashCode() : 0);
+ result = 31 * result + (_excludes != null ? _excludes.hashCode() : 0);
+ return result;
+ }
+
+ public void setSession(final Session session)
+ {
+ _session = session;
+ _delegate.setSession(session);
+ }
+
+ private long getMessageWindowSize()
+ {
+ return 10l;
+ }
+
+
+ VirtualHost getVirtualHost()
+ {
+ return _link.getVirtualHost();
+ }
+
+ public void close()
+ {
+ // TODO
+ _delegate.close();
+ _session = null;
+ }
+
+
+ private interface BridgeImpl
+ {
+ void setSession(Session session);
+
+ void close();
+ }
+
+ private abstract class AbstractPullBridge implements BridgeImpl, SessionListener
+ {
+ public final void setSession(final Session session)
+ {
+ session.setSessionListener(this);
+ onSession();
+
+ }
+
+ abstract void onSession();
+
+
+
+ public void message(final Session ssn, final MessageTransfer xfr)
+ {
+ ExchangeRegistry exchangeRegistry = getVirtualHost().getExchangeRegistry();
+
+ Exchange exchange = exchangeRegistry.getExchange(_destination);
+
+ // TODO - deal with exchange not existing
+
+ DeliveryProperties delvProps = null;
+ if(xfr.getHeader() != null && (delvProps = xfr.getHeader().get(DeliveryProperties.class)) != null && delvProps.hasTtl() && !delvProps.hasExpiration())
+ {
+ delvProps.setExpiration(System.currentTimeMillis() + delvProps.getTtl());
+ }
+
+ MessageMetaData_0_10 messageMetaData = new MessageMetaData_0_10(xfr);
+ final MessageStore store = getVirtualHost().getMessageStore();
+ StoredMessage<MessageMetaData_0_10> storeMessage = store.addMessage(messageMetaData);
+ storeMessage.addContent(0,xfr.getBody());
+ storeMessage.flushToStore();
+ MessageTransferMessage message = new MessageTransferMessage(storeMessage, ((ServerSession)_session).getReference());
+
+ ArrayList<? extends BaseQueue> queues = exchange.route(message);
+
+
+
+ if(queues != null && queues.size() != 0)
+ {
+ enqueue(message, queues);
+ }
+ else
+ {
+ if(delvProps == null || !delvProps.hasDiscardUnroutable() || !delvProps.getDiscardUnroutable())
+ {
+ if(xfr.getAcceptMode() == MessageAcceptMode.EXPLICIT)
+ {
+ RangeSet rejects = new RangeSet();
+ rejects.add(xfr.getId());
+ MessageReject reject = new MessageReject(rejects, MessageRejectCode.UNROUTABLE, "Unroutable");
+ ssn.invoke(reject);
+ }
+ else
+ {
+ Exchange alternate = exchange.getAlternateExchange();
+ if(alternate != null)
+ {
+ queues = alternate.route(message);
+ if(queues != null && queues.size() != 0)
+ {
+ enqueue(message, queues);
+ }
+ else
+ {
+ //TODO - log the message discard
+ }
+ }
+ else
+ {
+ //TODO - log the message discard
+ }
+
+
+ }
+ }
+
+
+ }
+
+ ssn.processed(xfr);
+
+ }
+
+
+ private void enqueue(final ServerMessage message, final ArrayList<? extends BaseQueue> queues)
+ {
+ _transaction.enqueue(queues,message, new ServerTransaction.Action()
+ {
+
+ BaseQueue[] _queues = queues.toArray(new BaseQueue[queues.size()]);
+
+ public void postCommit()
+ {
+ for(int i = 0; i < _queues.length; i++)
+ {
+ try
+ {
+ _queues[i].enqueue(message);
+ }
+ catch (AMQException e)
+ {
+ // TODO
+
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ public void onRollback()
+ {
+ // NO-OP
+ }
+ });
+
+ }
+
+ public void exception(final Session session, final SessionException exception)
+ {
+ // TODO - Handle exceptions
+ }
+
+ public void closed(final Session session)
+ {
+ // TODO - handle close
+ }
+
+ public void opened(final Session session)
+ {
+ // this method never called
+ }
+
+ public void resumed(final Session session)
+ {
+ // will never resume these sessions
+ }
+
+
+
+ }
+
+ private final class StaticExchangePullBridge extends AbstractPullBridge
+ {
+ private final String _tmpQueueName = "bridge_queue_" + _bridgeNo + "_" + _link.getFederationTag();;
+
+ public void onSession()
+ {
+
+ final HashMap<String, Object> options = new HashMap<String, Object>();
+ options.put("qpid.trace.exclude", _link.getFederationTag());
+ options.put("qpid.trace.id",_link.getRemoteFederationTag());
+ _session.queueDeclare(_tmpQueueName,null, options, Option.AUTO_DELETE, Option.EXCLUSIVE);
+ _session.sync();
+ // todo check exception
+ final Map<String,Object> bindingArgs = new HashMap<String,Object>();
+ _session.exchangeBind(_tmpQueueName, _source, _key, bindingArgs);
+ _session.sync();
+ // todo check exception
+
+ final Map<String,Object> subscribeOptions = Collections.EMPTY_MAP;
+ final String subName = String.valueOf(_bridgeNo);
+ _session.messageSubscribe(_tmpQueueName,
+ subName,MessageAcceptMode.NONE,MessageAcquireMode.PRE_ACQUIRED,null,0l, subscribeOptions);
+ _session.sync();
+ // todo check exception
+
+ _session.messageSetFlowMode(subName,MessageFlowMode.WINDOW);
+ _session.messageFlow(subName, MessageCreditUnit.MESSAGE, getMessageWindowSize());
+ _session.messageFlow(subName, MessageCreditUnit.BYTE, 0xFFFFFFFF);
+
+ }
+
+ public void close()
+ {
+ // TODO
+ }
+ }
+
+ private final class StaticQueuePullBridge extends AbstractPullBridge
+ {
+
+ public void onSession()
+ {
+
+ final Map<String,Object> subscribeOptions = Collections.EMPTY_MAP;
+ final String subName = String.valueOf(_bridgeNo);
+ _session.messageSubscribe(_source,
+ subName,MessageAcceptMode.NONE,MessageAcquireMode.PRE_ACQUIRED,null,0l, subscribeOptions);
+ _session.sync();
+ // todo check exception
+
+ _session.messageSetFlowMode(subName,MessageFlowMode.WINDOW);
+ _session.messageFlow(subName, MessageCreditUnit.MESSAGE, getMessageWindowSize());
+ _session.messageFlow(subName, MessageCreditUnit.BYTE, 0xFFFFFFFF);
+
+ }
+
+ public void close()
+ {
+ // TODO
+ }
+ }
+
+ private final class DynamicExchangeBridge extends AbstractPullBridge implements Exchange.BindingListener
+ {
+ private final String _tmpQueueName = "bridge_queue_" + _bridgeNo + "_" + _link.getFederationTag();
+
+ private final ConcurrentMap<Binding,Binding> _bindings = new ConcurrentHashMap<Binding,Binding>();
+
+
+ void onSession()
+ {
+
+
+ final HashMap<String, Object> options = new HashMap<String, Object>();
+ options.put("qpid.trace.exclude", _link.getFederationTag());
+ options.put("qpid.trace.id",_link.getRemoteFederationTag());
+ _session.queueDeclare(_tmpQueueName,null, options, Option.AUTO_DELETE, Option.EXCLUSIVE);
+ _session.sync();
+ // todo - check exception
+
+ final Map<String,Object> subscribeOptions = Collections.EMPTY_MAP;
+ final String subName = String.valueOf(_bridgeNo);
+ _session.messageSubscribe(_tmpQueueName,
+ subName,MessageAcceptMode.NONE,MessageAcquireMode.PRE_ACQUIRED,null,0l, subscribeOptions);
+ _session.sync();
+ // todo check exception
+ _session.messageSetFlowMode(subName,MessageFlowMode.WINDOW);
+ _session.messageFlow(subName, MessageCreditUnit.MESSAGE, getMessageWindowSize());
+ _session.messageFlow(subName, MessageCreditUnit.BYTE, 0xFFFFFFFF);
+ _session.sync();
+ // todo check exception
+
+
+ ExchangeRegistry exchangeRegistry = getVirtualHost().getExchangeRegistry();
+
+ Exchange exchange = exchangeRegistry.getExchange(_destination);
+
+ // TODO - check null
+
+ exchange.addBindingListener(this);
+
+ Collection<Binding> bindings = exchange.getBindings();
+ for(Binding binding : bindings)
+ {
+ propogateBinding(binding);
+ }
+
+ }
+
+ private void propogateBinding(final Binding binding)
+ {
+ if(_bindings.putIfAbsent(binding,binding)== null)
+ {
+ Map<String,Object> arguments = new HashMap<String,Object>(binding.getArguments());
+
+ if(arguments.get("qpid.fed.origin") == null)
+ {
+ arguments.put("qpid.fed.op","");
+ arguments.put("qpid.fed.origin",_link.getFederationTag());
+ arguments.put("qpid.fed.tags",_link.getFederationTag());
+ }
+ else
+ {
+ String tags = (String) arguments.get("qpid.fed.tags");
+ if(tags == null)
+ {
+ tags = _link.getFederationTag();
+ }
+ else
+ {
+ if(Arrays.asList(tags.split(",")).contains(_link.getFederationTag()))
+ {
+ return;
+ }
+ tags += "," + _link.getFederationTag();
+ }
+ arguments.put("qpid.fed.tags", tags);
+ }
+
+ _session.exchangeBind(_tmpQueueName, _source, binding.getBindingKey(), arguments);
+ _session.sync();
+ // TODO - check exception?
+
+ }
+ }
+
+ private void propogateBindingRemoval(final Binding binding)
+ {
+ if(_bindings.remove(binding) != null)
+ {
+ // TODO - this is wrong!!!!
+ _session.exchangeUnbind(_tmpQueueName, _source, binding.getBindingKey());
+ }
+ }
+
+
+ public void bindingAdded(final Exchange exchange, final Binding binding)
+ {
+ propogateBinding(binding);
+ }
+
+ public void bindingRemoved(final Exchange exchange, final Binding binding)
+ {
+ propogateBindingRemoval(binding);
+ }
+
+ public void close()
+ {
+ // TODO
+ }
+ }
+
+ private class StaticExchangePushBridge implements BridgeImpl, SessionListener
+ {
+ private final String _tmpQueueName = "bridge_queue_" + _bridgeNo + "_" + _link.getFederationTag();
+ private AMQQueue _queue;
+
+ public void setSession(final Session session)
+ {
+ session.setSessionListener(this);
+
+ ExchangeRegistry exchangeRegistry = getVirtualHost().getExchangeRegistry();
+
+ Exchange exchange = exchangeRegistry.getExchange(_source);
+
+ // TODO - Check null
+
+ final HashMap<String, Object> options = new HashMap<String, Object>();
+ options.put("qpid.trace.exclude", _link.getFederationTag());
+ options.put("qpid.trace.id",_link.getRemoteFederationTag());
+
+ _queue = AMQQueueFactory.createAMQQueueImpl(_tmpQueueName,
+ isDurable(),
+ _link.getFederationTag(),
+ false,
+ getVirtualHost(),
+ options);
+
+ FlowCreditManager_0_10 creditManager = new WindowCreditManager(0xFFFFFFFF,getMessageWindowSize());
+
+ Subscription_0_10 sub = new Subscription_0_10((ServerSession)session,
+ _destination,
+ MessageAcceptMode.NONE,
+ MessageAcquireMode.PRE_ACQUIRED,
+ MessageFlowMode.WINDOW,
+ creditManager, null);
+
+ ((ServerSession)session).register(_destination, sub);
+
+ try
+ {
+ _queue.registerSubscription(sub, true);
+ }
+ catch (AMQException e)
+ {
+ // TODO
+ throw new RuntimeException(e);
+ }
+
+ getVirtualHost().getBindingFactory().addBinding(_key, _queue, exchange, Collections.EMPTY_MAP);
+ }
+
+ public void close()
+ {
+ // TODO
+ }
+
+ public void opened(final Session session)
+ {
+ // this method never called
+ }
+
+ public void resumed(final Session session)
+ {
+ // this session will never be resumed
+ }
+
+ public void message(final Session ssn, final MessageTransfer xfr)
+ {
+ // messages should not be sent ... should probably log error
+ }
+
+ public void exception(final Session session, final SessionException exception)
+ {
+ // TODO
+ }
+
+ public void closed(final Session session)
+ {
+ // TODO
+ }
+ }
+
+ private class StaticQueuePushBridge implements BridgeImpl, SessionListener
+ {
+ private AMQQueue _queue;
+
+ public void setSession(final Session session)
+ {
+ session.setSessionListener(this);
+
+ QueueRegistry queueRegistry = getVirtualHost().getQueueRegistry();
+
+ _queue = queueRegistry.getQueue(_source);
+
+ // TODO - null check
+
+ FlowCreditManager_0_10 creditManager = new WindowCreditManager(0xFFFFFFFF,getMessageWindowSize());
+
+ Subscription_0_10 sub = new Subscription_0_10((ServerSession)session,
+ _destination,
+ MessageAcceptMode.NONE,
+ MessageAcquireMode.PRE_ACQUIRED,
+ MessageFlowMode.WINDOW,
+ creditManager, null);
+
+ ((ServerSession)session).register(_destination, sub);
+
+ try
+ {
+ _queue.registerSubscription(sub, false);
+ }
+ catch (AMQException e)
+ {
+ // TODO
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ public void close()
+ {
+ // TODO
+ }
+
+ public void opened(final Session session)
+ {
+ // never called
+ }
+
+ public void resumed(final Session session)
+ {
+ // session will not resume
+ }
+
+ public void message(final Session ssn, final MessageTransfer xfr)
+ {
+ // should never be called ... should probably log error
+ }
+
+ public void exception(final Session session, final SessionException exception)
+ {
+ // TODO
+ }
+
+ public void closed(final Session session)
+ {
+ // TODO
+ }
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java b/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java
new file mode 100644
index 0000000000..bb6fb9dcc3
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java
@@ -0,0 +1,497 @@
+/*
+ *
+ * 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.federation;
+
+import org.apache.qpid.server.configuration.ConfigStore;
+import org.apache.qpid.server.configuration.ConfiguredObject;
+import org.apache.qpid.server.configuration.ConnectionConfig;
+import org.apache.qpid.server.configuration.ConnectionConfigType;
+import org.apache.qpid.server.configuration.LinkConfig;
+import org.apache.qpid.server.configuration.LinkConfigType;
+import org.apache.qpid.server.transport.ServerSession;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.transport.Binary;
+import org.apache.qpid.transport.Connection;
+import org.apache.qpid.transport.ConnectionException;
+import org.apache.qpid.transport.ConnectionListener;
+import org.apache.qpid.transport.Session;
+import org.apache.qpid.transport.SessionDelegate;
+import org.apache.qpid.transport.TransportException;
+
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
+
+public class BrokerLink implements LinkConfig, ConnectionListener
+{
+
+ private static final int CORE_POOL_SIZE = 4;
+
+ private static final ScheduledThreadPoolExecutor _threadPool =
+ new ScheduledThreadPoolExecutor(CORE_POOL_SIZE);
+
+
+ private final String _transport;
+ private final String _host;
+ private final int _port;
+ private final String _remoteVhost;
+ private final boolean _durable;
+ private final String _authMechanism;
+ private final String _username;
+ private final String _password;
+ private final VirtualHost _virtualHost;
+ private UUID _id;
+ private AtomicBoolean _closing = new AtomicBoolean();
+ private final long _createTime = System.currentTimeMillis();
+ private Connection _qpidConnection;
+ private AtomicReference<Thread> _executor = new AtomicReference<Thread>();
+ private AtomicInteger _bridgeId = new AtomicInteger();
+
+ private final ConcurrentHashMap<Bridge,Bridge> _bridges = new ConcurrentHashMap<Bridge,Bridge>();
+ private final ConcurrentHashMap<Bridge,Bridge> _activeBridges = new ConcurrentHashMap<Bridge,Bridge>();
+ private final ConcurrentLinkedQueue<Bridge> _pendingBridges = new ConcurrentLinkedQueue<Bridge>();
+ private String _remoteFederationTag;
+
+ private ConnectionConfig _connectionConfig;
+ private ConnectionException _exception;
+ private String _lastErrorMessage;
+ private int _retryDelay = 1;
+ private final Runnable _makeConnectionTask = new Runnable()
+ {
+ public void run()
+ {
+ doMakeConnection();
+ }
+ };;
+ ;
+
+ public static enum State
+ {
+ OPERATIONAL,
+ DOWN,
+ ESTABLISHING,
+ DELETED
+ }
+
+
+ private volatile State _state = State.DOWN;
+
+ private static final AtomicReferenceFieldUpdater<BrokerLink, State> _stateUpdater =
+ AtomicReferenceFieldUpdater.newUpdater(BrokerLink.class, State.class, "_state");
+
+ private class ConnectionConfigAdapter implements ConnectionConfig
+ {
+
+ private UUID _id = BrokerLink.this.getConfigStore().createId();
+
+ public VirtualHost getVirtualHost()
+ {
+ return BrokerLink.this.getVirtualHost();
+ }
+
+ public String getAddress()
+ {
+ return _host+":"+_port;
+ }
+
+ public Boolean isIncoming()
+ {
+ return false;
+ }
+
+ public Boolean isSystemConnection()
+ {
+ return true;
+ }
+
+ public Boolean isFederationLink()
+ {
+ return true;
+ }
+
+ public String getAuthId()
+ {
+ return _username;
+ }
+
+ public String getRemoteProcessName()
+ {
+ return null;
+ }
+
+ public Integer getRemotePID()
+ {
+ return null;
+ }
+
+ public Integer getRemoteParentPID()
+ {
+ return null;
+ }
+
+ public ConfigStore getConfigStore()
+ {
+ return getVirtualHost().getConfigStore();
+ }
+
+ public UUID getId()
+ {
+ return _id;
+ }
+
+ public ConnectionConfigType getConfigType()
+ {
+ return ConnectionConfigType.getInstance();
+ }
+
+ public ConfiguredObject getParent()
+ {
+ return getVirtualHost();
+ }
+
+ public boolean isDurable()
+ {
+ return false;
+ }
+ }
+
+ private class SessionFactory implements Connection.SessionFactory
+ {
+
+ public Session newSession(final Connection conn, final Binary name, final long expiry)
+ {
+ return new ServerSession(conn, new SessionDelegate(), name, expiry, _connectionConfig);
+ }
+ };
+
+
+ public BrokerLink(final VirtualHost virtualHost,
+ final String transport,
+ final String host,
+ final int port,
+ final String remoteVhost,
+ final boolean durable,
+ final String authMechanism, final String username, final String password)
+ {
+ _virtualHost = virtualHost;
+ _transport = transport;
+ _host = host;
+ _port = port;
+ _remoteVhost = remoteVhost;
+ _durable = durable;
+ _authMechanism = authMechanism;
+ _username = username;
+ _password = password;
+ _id = virtualHost.getConfigStore().createId();
+ _qpidConnection = new Connection();
+ _connectionConfig = new ConnectionConfigAdapter();
+ _qpidConnection.addConnectionListener(this);
+
+
+ makeConnection();
+ }
+
+ private final boolean updateState(State expected, State newState)
+ {
+ return _stateUpdater.compareAndSet(this,expected,newState);
+ }
+
+ private void makeConnection()
+ {
+ _threadPool.execute(_makeConnectionTask);
+ }
+
+
+
+ private void doMakeConnection()
+ {
+ if(updateState(State.DOWN, State.ESTABLISHING))
+ {
+ try
+ {
+ _qpidConnection.connect(_host, _port, _remoteVhost, _username, _password, "ssl".equals(_transport), _authMechanism);
+
+ final Map<String,Object> serverProps = _qpidConnection.getServerProperties();
+ _remoteFederationTag = (String) serverProps.get("qpid.federation_tag");
+ if(_remoteFederationTag == null)
+ {
+ _remoteFederationTag = UUID.fromString(_transport+":"+_host+":"+_port).toString();
+ }
+ _qpidConnection.setSessionFactory(new SessionFactory());
+ _qpidConnection.setAuthorizationID(_username == null ? "" : _username);
+
+ updateState(State.ESTABLISHING, State.OPERATIONAL);
+
+ _retryDelay = 1;
+
+ for(Bridge bridge : _bridges.values())
+ {
+ if(_state != State.OPERATIONAL)
+ {
+ break;
+ }
+ addBridge(bridge);
+ }
+
+
+ }
+ catch (TransportException e)
+ {
+ _lastErrorMessage = e.getMessage();
+ if(_retryDelay < 60)
+ {
+ _retryDelay <<= 1;
+ }
+
+ updateState(State.ESTABLISHING, State.DOWN);
+ _activeBridges.clear();
+ scheduleConnectionRetry();
+ }
+ }
+ }
+
+ private void scheduleConnectionRetry()
+ {
+ if(_state != State.DELETED)
+ {
+ _threadPool.schedule(_makeConnectionTask, _retryDelay, TimeUnit.SECONDS);
+ }
+ }
+
+ public VirtualHost getVirtualHost()
+ {
+ return _virtualHost;
+ }
+
+ public String getTransport()
+ {
+ return _transport;
+ }
+
+ public String getHost()
+ {
+ return _host;
+ }
+
+ public int getPort()
+ {
+ return _port;
+ }
+
+ public String getRemoteVhost()
+ {
+ return _remoteVhost;
+ }
+
+ public UUID getId()
+ {
+ return _id;
+ }
+
+ public LinkConfigType getConfigType()
+ {
+ return LinkConfigType.getInstance();
+ }
+
+ public ConfiguredObject getParent()
+ {
+ return getVirtualHost();
+ }
+
+ public boolean isDurable()
+ {
+ return _durable;
+ }
+
+ public String getAuthMechanism()
+ {
+ return _authMechanism;
+ }
+
+ public String getUsername()
+ {
+ return _username;
+ }
+
+ public String getPassword()
+ {
+ return _password;
+ }
+
+ @Override
+ public boolean equals(final Object o)
+ {
+ if (this == o)
+ {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass())
+ {
+ return false;
+ }
+
+ final BrokerLink that = (BrokerLink) o;
+
+ if (_port != that._port)
+ {
+ return false;
+ }
+ if (_host != null ? !_host.equals(that._host) : that._host != null)
+ {
+ return false;
+ }
+ if (_remoteVhost != null ? !_remoteVhost.equals(that._remoteVhost) : that._remoteVhost != null)
+ {
+ return false;
+ }
+ if (_transport != null ? !_transport.equals(that._transport) : that._transport != null)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int result = _transport != null ? _transport.hashCode() : 0;
+ result = 31 * result + (_host != null ? _host.hashCode() : 0);
+ result = 31 * result + _port;
+ result = 31 * result + (_remoteVhost != null ? _remoteVhost.hashCode() : 0);
+ return result;
+ }
+
+ public void close()
+ {
+ if(_closing.compareAndSet(false,true))
+ {
+ // TODO - close connection
+ for(Bridge bridge : _bridges.values())
+ {
+ bridge.close();
+ }
+ _bridges.clear();
+
+ _virtualHost.removeBrokerConnection(this);
+ }
+ }
+
+ public long getCreateTime()
+ {
+ return _createTime;
+ }
+
+ public void createBridge(final boolean durable,
+ final boolean dynamic,
+ final boolean srcIsQueue,
+ final boolean srcIsLocal,
+ final String src,
+ final String dest,
+ final String key,
+ final String tag,
+ final String excludes)
+ {
+ if(!_closing.get())
+ {
+ Bridge bridge = new Bridge(this, _bridgeId.incrementAndGet(), durable,dynamic,srcIsQueue,srcIsLocal,src,dest,key,tag,excludes);
+ if(_bridges.putIfAbsent(bridge, bridge) == null)
+ {
+
+ addBridge(bridge);
+ }
+ }
+
+
+ }
+
+ private void addBridge(final Bridge bridge)
+ {
+ getConfigStore().addConfiguredObject(bridge);
+
+ if(_state == State.OPERATIONAL && (_activeBridges.putIfAbsent(bridge,bridge) == null))
+ {
+
+
+ Session session = _qpidConnection.createSession("Bridge("
+ + (bridge.isDurable() ? "durable" : "transient")
+ + "," + (bridge.isDynamic() ? "dynamic" : "static")
+ + "," + (bridge.isQueueBridge() ? "queue" : "exchange")
+ + "," + (bridge.isLocalSource() ? "local-src" : "remote-src")
+ + ",[Source: '" + bridge.getSource() + "']"
+ + ",[Destination: '" + bridge.getDestination() + "']"
+ + ",[Key: '" + bridge.getKey() + "']"
+ + ",[Tag: '" + bridge.getTag() + "']"
+ + ".[Excludes: '" + bridge.getExcludes() + "'])");
+ bridge.setSession(session);
+
+
+ if(_closing.get())
+ {
+ bridge.close();
+ }
+ }
+
+ }
+
+ public void opened(final Connection connection)
+ {
+ // this method not called
+ }
+
+ public void exception(final Connection connection, final ConnectionException exception)
+ {
+ _exception = exception;
+ _lastErrorMessage = exception.getMessage();
+
+ }
+
+ public void closed(final Connection connection)
+ {
+ State currentState = _state;
+ if(currentState != State.DOWN && currentState != State.DELETED && updateState(currentState, State.DOWN))
+ {
+ scheduleConnectionRetry();
+ }
+ }
+
+ public ConfigStore getConfigStore()
+ {
+ return getVirtualHost().getConfigStore();
+ }
+
+ public String getFederationTag()
+ {
+ return getVirtualHost().getFederationTag();
+ }
+
+ public String getRemoteFederationTag()
+ {
+ return _remoteFederationTag;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/filter/JMSSelectorFilter.java b/java/broker/src/main/java/org/apache/qpid/server/filter/JMSSelectorFilter.java
index dacd047fea..f32de03841 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/filter/JMSSelectorFilter.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/filter/JMSSelectorFilter.java
@@ -22,6 +22,7 @@ package org.apache.qpid.server.filter;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
+import org.apache.qpid.AMQInvalidArgumentException;
import org.apache.qpid.server.filter.jms.selector.SelectorParser;
import org.apache.qpid.server.queue.Filterable;
@@ -33,7 +34,7 @@ public class JMSSelectorFilter implements MessageFilter
private String _selector;
private BooleanExpression _matcher;
- public JMSSelectorFilter(String selector) throws AMQException
+ public JMSSelectorFilter(String selector) throws AMQInvalidArgumentException
{
_selector = selector;
_matcher = new SelectorParser().parse(selector);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java
index 0343457a73..d806f9426a 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java
@@ -27,7 +27,6 @@ import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.server.AMQChannel;
import org.apache.qpid.server.protocol.AMQProtocolSession;
import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.security.access.Permission;
import org.apache.qpid.server.state.AMQStateManager;
import org.apache.qpid.server.state.StateAwareMethodListener;
import org.apache.qpid.server.virtualhost.VirtualHost;
@@ -102,11 +101,11 @@ public class BasicConsumeMethodHandler implements StateAwareMethodListener<Basic
body.getNoLocal(), body.getNowait(), queue))
{
throw body.getConnectionException(AMQConstant.ACCESS_REFUSED, "Permission denied");
- }
+ }
else if (queue.isExclusive() && !queue.isDurable() && queue.getExclusiveOwner() != session)
{
throw body.getConnectionException(AMQConstant.NOT_ALLOWED,
- "Queue " + queue.getName() + " is exclusive, but not created on this Connection.");
+ "Queue " + queue.getNameShortString() + " is exclusive, but not created on this Connection.");
}
if (body.getConsumerTag() != null)
@@ -163,14 +162,14 @@ public class BasicConsumeMethodHandler implements StateAwareMethodListener<Basic
{
throw body.getChannelException(AMQConstant.ACCESS_REFUSED,
"Cannot subscribe to queue "
- + queue.getName()
+ + queue.getNameShortString()
+ " as it already has an existing exclusive consumer");
}
catch (AMQQueue.ExistingSubscriptionPreventsExclusive e)
{
throw body.getChannelException(AMQConstant.ACCESS_REFUSED,
"Cannot subscribe to queue "
- + queue.getName()
+ + queue.getNameShortString()
+ " exclusively as it already has a consumer");
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java
index 1dd6f1413b..7cfd1fc121 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java
@@ -30,7 +30,6 @@ import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.exchange.ExchangeFactory;
import org.apache.qpid.server.exchange.ExchangeRegistry;
import org.apache.qpid.server.protocol.AMQProtocolSession;
-import org.apache.qpid.server.security.access.Permission;
import org.apache.qpid.server.state.AMQStateManager;
import org.apache.qpid.server.state.StateAwareMethodListener;
import org.apache.qpid.server.virtualhost.VirtualHost;
@@ -109,10 +108,10 @@ public class ExchangeDeclareHandler implements StateAwareMethodListener<Exchange
}
}
}
- else if (!exchange.getType().equals(body.getType()))
+ else if (!exchange.getTypeShortString().equals(body.getType()))
{
- throw new AMQConnectionException(AMQConstant.NOT_ALLOWED, "Attempt to redeclare exchange: " + body.getExchange() + " of type " + exchange.getType() + " to " + body.getType() +".",body.getClazz(), body.getMethod(),body.getMajor(),body.getMinor(),null);
+ throw new AMQConnectionException(AMQConstant.NOT_ALLOWED, "Attempt to redeclare exchange: " + body.getExchange() + " of type " + exchange.getTypeShortString() + " to " + body.getType() +".",body.getClazz(), body.getMethod(),body.getMajor(),body.getMinor(),null);
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueBindHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueBindHandler.java
index 57ce7a7240..0de3ded5a1 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueBindHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueBindHandler.java
@@ -7,9 +7,9 @@
* 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
@@ -21,21 +21,27 @@
package org.apache.qpid.server.handler;
import org.apache.log4j.Logger;
+
import org.apache.qpid.AMQException;
-import org.apache.qpid.AMQInvalidRoutingKeyException;
-import org.apache.qpid.framing.*;
+import org.apache.qpid.framing.AMQMethodBody;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.framing.MethodRegistry;
+import org.apache.qpid.framing.QueueBindBody;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.server.AMQChannel;
+import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.exchange.ExchangeRegistry;
import org.apache.qpid.server.protocol.AMQProtocolSession;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.QueueRegistry;
-import org.apache.qpid.server.security.access.Permission;
import org.apache.qpid.server.state.AMQStateManager;
import org.apache.qpid.server.state.StateAwareMethodListener;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import java.util.Map;
+
public class QueueBindHandler implements StateAwareMethodListener<QueueBindBody>
{
private static final Logger _log = Logger.getLogger(QueueBindHandler.class);
@@ -80,7 +86,7 @@ public class QueueBindHandler implements StateAwareMethodListener<QueueBindBody>
if (body.getRoutingKey() == null)
{
- routingKey = queue.getName();
+ routingKey = queue.getNameShortString();
}
else
{
@@ -116,18 +122,26 @@ public class QueueBindHandler implements StateAwareMethodListener<QueueBindBody>
else if (queue.isExclusive() && !queue.isDurable() && queue.getExclusiveOwner() != session)
{
throw body.getConnectionException(AMQConstant.NOT_ALLOWED,
- "Queue " + queue.getName() + " is exclusive, but not created on this Connection.");
+ "Queue " + queue.getNameShortString() + " is exclusive, but not created on this Connection.");
}
if (!exch.isBound(routingKey, body.getArguments(), queue))
{
- queue.bind(exch, routingKey, body.getArguments());
+ String bindingKey = String.valueOf(routingKey);
+ Map<String,Object> arguments = FieldTable.convertToMap(body.getArguments());
+
+ if(!virtualHost.getBindingFactory().addBinding(bindingKey, queue, exch, arguments))
+ {
+ Binding oldBinding = virtualHost.getBindingFactory().getBinding(bindingKey, queue, exch, arguments);
+
+ Map<String, Object> oldArgs = oldBinding.getArguments();
+ if((oldArgs == null && !arguments.isEmpty()) || (oldArgs != null && !oldArgs.equals(arguments)))
+ {
+ virtualHost.getBindingFactory().replaceBinding(bindingKey, queue, exch, arguments);
+ }
+ }
}
}
- catch (AMQInvalidRoutingKeyException rke)
- {
- throw body.getChannelException(AMQConstant.INVALID_ROUTING_KEY, routingKey.toString());
- }
catch (AMQException e)
{
throw body.getChannelException(AMQConstant.CHANNEL_ERROR, e.toString());
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java
index bb57fdbc36..5d5bd761c7 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java
@@ -21,6 +21,7 @@
package org.apache.qpid.server.handler;
import java.util.UUID;
+import java.util.Collections;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.log4j.Logger;
@@ -150,21 +151,21 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
{
Exchange defaultExchange = exchangeRegistry.getDefaultExchange();
- queue.bind(defaultExchange, queueName, null);
- _logger.info("Queue " + queueName + " bound to default exchange(" + defaultExchange.getName() + ")");
+ virtualHost.getBindingFactory().addBinding(String.valueOf(queueName), queue, defaultExchange, Collections.EMPTY_MAP);
+ _logger.info("Queue " + queueName + " bound to default exchange(" + defaultExchange.getNameShortString() + ")");
}
}
}
else if (queue.isExclusive() && !queue.isDurable() && queue.getExclusiveOwner() != session)
{
throw body.getConnectionException(AMQConstant.NOT_ALLOWED,
- "Queue " + queue.getName() + " is exclusive, but not created on this Connection.");
+ "Queue " + queue.getNameShortString() + " is exclusive, but not created on this Connection.");
}
else if(!body.getPassive() && ((queue.isExclusive()) != body.getExclusive()))
{
throw body.getChannelException(AMQConstant.ALREADY_EXISTS,
- "Cannot re-declare queue '" + queue.getName() + "' with different exclusivity (was: "
+ "Cannot re-declare queue '" + queue.getNameShortString() + "' with different exclusivity (was: "
+ queue.isExclusive() + " requested " + body.getExclusive() + ")");
}
else if (!body.getPassive() && body.getExclusive() && !queue.getExclusiveOwner().equals(queue.isDurable() ? session.getPrincipal().getName() : session))
@@ -178,13 +179,13 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
else if(!body.getPassive() && queue.isAutoDelete() != body.getAutoDelete())
{
throw body.getChannelException(AMQConstant.ALREADY_EXISTS,
- "Cannot re-declare queue '" + queue.getName() + "' with different auto-delete (was: "
+ "Cannot re-declare queue '" + queue.getNameShortString() + "' with different auto-delete (was: "
+ queue.isAutoDelete() + " requested " + body.getAutoDelete() + ")");
}
else if(!body.getPassive() && queue.isDurable() != body.getDurable())
{
throw body.getChannelException(AMQConstant.ALREADY_EXISTS,
- "Cannot re-declare queue '" + queue.getName() + "' with different durability (was: "
+ "Cannot re-declare queue '" + queue.getNameShortString() + "' with different durability (was: "
+ queue.isDurable() + " requested " + body.getDurable() + ")");
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java
index 3d58ec2133..93acc94816 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java
@@ -7,9 +7,9 @@
* 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
@@ -30,11 +30,9 @@ import org.apache.qpid.server.queue.QueueRegistry;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.state.AMQStateManager;
import org.apache.qpid.server.state.StateAwareMethodListener;
-import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.store.DurableConfigurationStore;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.AMQChannel;
-import org.apache.qpid.server.security.access.Permission;
public class QueueDeleteHandler implements StateAwareMethodListener<QueueDeleteBody>
{
@@ -75,7 +73,7 @@ public class QueueDeleteHandler implements StateAwareMethodListener<QueueDeleteB
throw body.getChannelNotFoundException(channelId);
}
- //get the default queue on the channel:
+ //get the default queue on the channel:
queue = channel.getDefaultQueue();
}
else
@@ -104,7 +102,7 @@ public class QueueDeleteHandler implements StateAwareMethodListener<QueueDeleteB
}
else
{
-
+
//Perform ACLs
if (!virtualHost.getAccessManager().authoriseDelete(session, queue))
{
@@ -113,7 +111,7 @@ public class QueueDeleteHandler implements StateAwareMethodListener<QueueDeleteB
else if (queue.isExclusive() && !queue.isDurable() && queue.getExclusiveOwner() != session)
{
throw body.getConnectionException(AMQConstant.NOT_ALLOWED,
- "Queue " + queue.getName() + " is exclusive, but not created on this Connection.");
+ "Queue " + queue.getNameShortString() + " is exclusive, but not created on this Connection.");
}
int purged = queue.delete();
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueUnbindHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueUnbindHandler.java
index 31401ce9d9..29c30de9cc 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueUnbindHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueUnbindHandler.java
@@ -106,23 +106,16 @@ public class QueueUnbindHandler implements StateAwareMethodListener<QueueUnbindB
throw body.getConnectionException(AMQConstant.ACCESS_REFUSED, "Permission denied");
}
- try
+ if(virtualHost.getBindingFactory().getBinding(String.valueOf(routingKey), queue, exch, FieldTable.convertToMap(body.getArguments())) == null)
{
- queue.unBind(exch, routingKey, body.getArguments());
+ throw body.getChannelException(AMQConstant.NOT_FOUND,"No such binding");
}
- catch (AMQInvalidRoutingKeyException rke)
- {
- throw body.getChannelException(AMQConstant.INVALID_ROUTING_KEY, routingKey.toString());
- }
- catch (AMQException e)
+ else
{
- if(e.getErrorCode() == AMQConstant.NOT_FOUND)
- {
- throw body.getChannelException(AMQConstant.NOT_FOUND,e.getMessage(),e);
- }
- throw body.getChannelException(AMQConstant.CHANNEL_ERROR, e.toString());
+ virtualHost.getBindingFactory().removeBinding(String.valueOf(routingKey), queue, exch, FieldTable.convertToMap(body.getArguments()));
}
+
if (_log.isInfoEnabled())
{
_log.info("Binding queue " + queue + " to exchange " + exch + " with routing key " + routingKey);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/BindingLogSubject.java b/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/BindingLogSubject.java
index fd171fea5a..69139d38a3 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/BindingLogSubject.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/BindingLogSubject.java
@@ -20,7 +20,6 @@
*/
package org.apache.qpid.server.logging.subjects;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.queue.AMQQueue;
@@ -49,13 +48,13 @@ public class BindingLogSubject extends AbstractLogSubject
* @param exchange
* @param queue
*/
- public BindingLogSubject(AMQShortString routingKey, Exchange exchange,
+ public BindingLogSubject(String routingKey, Exchange exchange,
AMQQueue queue)
{
setLogStringWithFormat(BINDING_FORMAT, queue.getVirtualHost().getName(),
- exchange.getType(),
- exchange.getName(),
- queue.getName(),
+ exchange.getTypeShortString(),
+ exchange.getNameShortString(),
+ queue.getNameShortString(),
routingKey);
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ExchangeLogSubject.java b/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ExchangeLogSubject.java
index 21e5f5e4ce..0fc2d7392f 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ExchangeLogSubject.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ExchangeLogSubject.java
@@ -41,6 +41,6 @@ public class ExchangeLogSubject extends AbstractLogSubject
public ExchangeLogSubject(Exchange exchange, VirtualHost vhost)
{
setLogStringWithFormat(BINDING_FORMAT, vhost.getName(),
- exchange.getType(), exchange.getName());
+ exchange.getTypeShortString(), exchange.getNameShortString());
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/QueueLogSubject.java b/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/QueueLogSubject.java
index b132d9e93f..fd97318e8b 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/QueueLogSubject.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/QueueLogSubject.java
@@ -40,6 +40,6 @@ public class QueueLogSubject extends AbstractLogSubject
{
setLogStringWithFormat(LOG_FORMAT,
queue.getVirtualHost().getName(),
- queue.getName());
+ queue.getNameShortString());
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessageHeader.java b/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessageHeader.java
index 6c9311c3de..faac14f8a7 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessageHeader.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessageHeader.java
@@ -42,6 +42,10 @@ public interface AMQMessageHeader
String getReplyTo();
+ String getReplyToExchange();
+ String getReplyToRoutingKey();
+
+
Object getHeader(String name);
boolean containsHeaders(Set<String> names);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java
index 4a1f8dd191..194835ac02 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java
@@ -85,6 +85,19 @@ public class ContentHeaderBodyAdapter implements AMQMessageHeader
return getProperties().getReplyToAsString();
}
+ public String getReplyToExchange()
+ {
+ // TODO
+ return getReplyTo();
+ }
+
+ public String getReplyToRoutingKey()
+ {
+ // TODO
+ return getReplyTo();
+
+ }
+
public Object getHeader(String name)
{
FieldTable ft = getProperties().getHeaders();
diff --git a/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java b/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java
index b34a8fc470..2f8c2e09a2 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java
@@ -278,6 +278,18 @@ public class MessageMetaData implements StorableMessageMetaData
return getProperties().getReplyToAsString();
}
+ public String getReplyToExchange()
+ {
+ // TODO
+ return getReplyTo();
+ }
+
+ public String getReplyToRoutingKey()
+ {
+ // TODO
+ return getReplyTo();
+ }
+
public Object getHeader(String name)
{
FieldTable ft = getProperties().getHeaders();
diff --git a/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferHeader.java b/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferHeader.java
index 7fac7ab164..a15e16a64f 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferHeader.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferHeader.java
@@ -105,6 +105,30 @@ class MessageTransferHeader implements AMQMessageHeader
}
}
+ public String getReplyToExchange()
+ {
+ if (_messageProps != null && _messageProps.getReplyTo() != null)
+ {
+ return _messageProps.getReplyTo().getExchange();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public String getReplyToRoutingKey()
+ {
+ if (_messageProps != null && _messageProps.getReplyTo() != null)
+ {
+ return _messageProps.getReplyTo().getRoutingKey();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
public Object getHeader(String name)
{
Map<String, Object> appHeaders = _messageProps == null ? null : _messageProps.getApplicationHeaders();
diff --git a/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferMessage.java b/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferMessage.java
index e866ad5078..baa5dce14f 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferMessage.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferMessage.java
@@ -119,7 +119,7 @@ public class MessageTransferMessage implements InboundMessage, ServerMessage
public ByteBuffer getBody()
{
ByteBuffer body = getMetaData().getBody();
- if(body == null)
+ if(body == null && getSize() != 0l)
{
final int size = (int) getSize();
int pos = 0;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java
index ea8fbbd68f..ec74f79ace 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java
@@ -20,50 +20,16 @@
*/
package org.apache.qpid.server.protocol;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.nio.ByteBuffer;
-import java.security.Principal;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.atomic.AtomicMarkableReference;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import javax.management.JMException;
-import javax.security.sasl.SaslServer;
-
import org.apache.log4j.Logger;
import org.apache.mina.transport.vmpipe.VmPipeAddress;
+
import org.apache.qpid.AMQChannelException;
import org.apache.qpid.AMQConnectionException;
import org.apache.qpid.AMQException;
import org.apache.qpid.codec.AMQCodecFactory;
import org.apache.qpid.codec.AMQDecoder;
import org.apache.qpid.common.ClientProperties;
-import org.apache.qpid.framing.AMQBody;
-import org.apache.qpid.framing.AMQDataBlock;
-import org.apache.qpid.framing.AMQFrame;
-import org.apache.qpid.framing.AMQMethodBody;
-import org.apache.qpid.framing.AMQProtocolHeaderException;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.ChannelCloseOkBody;
-import org.apache.qpid.framing.ConnectionCloseBody;
-import org.apache.qpid.framing.ContentBody;
-import org.apache.qpid.framing.ContentHeaderBody;
-import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.framing.HeartbeatBody;
-import org.apache.qpid.framing.MethodDispatcher;
-import org.apache.qpid.framing.MethodRegistry;
-import org.apache.qpid.framing.ProtocolInitiation;
-import org.apache.qpid.framing.ProtocolVersion;
+import org.apache.qpid.framing.*;
import org.apache.qpid.pool.Job;
import org.apache.qpid.pool.ReferenceCountingExecutorService;
import org.apache.qpid.protocol.AMQConstant;
@@ -71,6 +37,10 @@ import org.apache.qpid.protocol.AMQMethodEvent;
import org.apache.qpid.protocol.AMQMethodListener;
import org.apache.qpid.protocol.ProtocolEngine;
import org.apache.qpid.server.AMQChannel;
+import org.apache.qpid.server.configuration.ConfigStore;
+import org.apache.qpid.server.configuration.ConfiguredObject;
+import org.apache.qpid.server.configuration.ConnectionConfig;
+import org.apache.qpid.server.configuration.ConnectionConfigType;
import org.apache.qpid.server.handler.ServerMethodDispatcherImpl;
import org.apache.qpid.server.logging.LogActor;
import org.apache.qpid.server.logging.LogSubject;
@@ -85,12 +55,31 @@ import org.apache.qpid.server.output.ProtocolOutputConverterRegistry;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.state.AMQState;
import org.apache.qpid.server.state.AMQStateManager;
-import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
import org.apache.qpid.transport.NetworkDriver;
import org.apache.qpid.transport.Sender;
-public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocolSession
+import javax.management.JMException;
+import javax.security.sasl.SaslServer;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocolSession, ConnectionConfig
{
private static final Logger _logger = Logger.getLogger(AMQProtocolEngine.class);
@@ -161,6 +150,8 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
private ReferenceCountingExecutorService _poolReference = ReferenceCountingExecutorService.getInstance();
private long _maxFrameSize;
private final AtomicBoolean _closing = new AtomicBoolean(false);
+ private final UUID _id;
+ private final ConfigStore _configStore;
public ManagedObject getManagedObject()
{
@@ -181,6 +172,10 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
_logSubject = new ConnectionLogSubject(this);
+ _configStore = virtualHostRegistry.getConfigStore();
+ _id = _configStore.createId();
+
+
_actor.message(ConnectionMessages.CON_OPEN(null, null, false, false));
}
@@ -765,6 +760,8 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
public void closeProtocolSession()
{
+ getConfigStore().removeConfiguredObject(this);
+
_networkDriver.close();
try
{
@@ -902,6 +899,8 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
_virtualHost = virtualHost;
_virtualHost.getConnectionRegistry().registerConnection(this);
+
+ _configStore.addConfiguredObject(this);
try
{
@@ -1067,4 +1066,69 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
}
}
+ public Boolean isIncoming()
+ {
+ return true;
+ }
+
+ public Boolean isSystemConnection()
+ {
+ return false;
+ }
+
+ public Boolean isFederationLink()
+ {
+ return false;
+ }
+
+ public String getAuthId()
+ {
+ return getAuthorizedID().getName();
+ }
+
+ public Integer getRemotePID()
+ {
+ return null;
+ }
+
+ public String getRemoteProcessName()
+ {
+ return null;
+ }
+
+ public Integer getRemoteParentPID()
+ {
+ return null;
+ }
+
+ public ConfigStore getConfigStore()
+ {
+ return _configStore;
+ }
+
+ public ConnectionConfigType getConfigType()
+ {
+ return ConnectionConfigType.getInstance();
+ }
+
+ public ConfiguredObject getParent()
+ {
+ return getVirtualHost();
+ }
+
+ public boolean isDurable()
+ {
+ return false;
+ }
+
+ public UUID getId()
+ {
+ return _id;
+ }
+
+ public String getAddress()
+ {
+ return String.valueOf(getRemoteAddress());
+ }
+
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java
index 0562d04b7b..8d832a6a79 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java
@@ -37,8 +37,19 @@
*/
package org.apache.qpid.server.protocol;
-import java.util.Date;
-import java.util.List;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.ConnectionCloseBody;
+import org.apache.qpid.framing.MethodRegistry;
+import org.apache.qpid.management.common.mbeans.ManagedConnection;
+import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor;
+import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
+import org.apache.qpid.protocol.AMQConstant;
+import org.apache.qpid.server.AMQChannel;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.actors.ManagementActor;
+import org.apache.qpid.server.management.AMQManagedObject;
+import org.apache.qpid.server.management.ManagedObject;
import javax.management.JMException;
import javax.management.MBeanException;
@@ -55,22 +66,8 @@ import javax.management.openmbean.SimpleType;
import javax.management.openmbean.TabularData;
import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.ConnectionCloseBody;
-import org.apache.qpid.framing.MethodRegistry;
-import org.apache.qpid.management.common.mbeans.ManagedConnection;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
-import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.server.AMQChannel;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.actors.ManagementActor;
-import org.apache.qpid.server.logging.LogActor;
-import org.apache.qpid.server.logging.RootMessageLogger;
-import org.apache.qpid.server.management.AMQManagedObject;
-import org.apache.qpid.server.management.ManagedObject;
+import java.util.Date;
+import java.util.List;
/**
* This MBean class implements the management interface. In order to make more attributes, operations and notifications
@@ -255,7 +252,7 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed
Object[] itemValues =
{
channel.getChannelId(), channel.isTransactional(),
- (channel.getDefaultQueue() != null) ? channel.getDefaultQueue().getName().asString() : null,
+ (channel.getDefaultQueue() != null) ? channel.getDefaultQueue().getNameShortString().asString() : null,
channel.getUnacknowledgedMessageMap().size(), channel.getBlocking()
};
@@ -291,7 +288,7 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed
// then the CurrentActor could be set in our JMX Proxy object.
// As it is we need to set the CurrentActor on all MBean methods
// Ideally we would not have a single method that can be called from
- // two contexts.
+ // two contexts.
boolean removeActor = false;
if (CurrentActor.get() == null)
{
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java
index 9a1c6c9418..b3cb90fc6e 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java
@@ -20,14 +20,14 @@
*/
package org.apache.qpid.server.protocol;
+import org.apache.log4j.Logger;
+
import org.apache.qpid.protocol.ProtocolEngine;
-import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.transport.NetworkDriver;
-import org.apache.qpid.transport.Connection;
-import org.apache.qpid.transport.ConnectionDelegate;
import org.apache.qpid.server.protocol.MultiVersionProtocolEngineFactory.VERSION;
+import org.apache.qpid.server.registry.IApplicationRegistry;
import org.apache.qpid.server.transport.ServerConnection;
-import org.apache.log4j.Logger;
+import org.apache.qpid.transport.ConnectionDelegate;
+import org.apache.qpid.transport.NetworkDriver;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
@@ -239,10 +239,10 @@ private static final byte[] AMQP_0_9_1_HEADER =
final ConnectionDelegate connDelegate =
new org.apache.qpid.server.transport.ServerConnectionDelegate(_appRegistry, _fqdn);
- Connection conn = new ServerConnection();
+ ServerConnection conn = new ServerConnection();
conn.setConnectionDelegate(connDelegate);
- return new ProtocolEngine_0_10( conn, _networkDriver);
+ return new ProtocolEngine_0_10( conn, _networkDriver, _appRegistry);
}
};
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngineFactory_0_10.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngineFactory_0_10.java
deleted file mode 100755
index 7c3adf8b7d..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngineFactory_0_10.java
+++ /dev/null
@@ -1,46 +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.protocol;
-
-import org.apache.qpid.protocol.ProtocolEngineFactory;
-import org.apache.qpid.protocol.ProtocolEngine;
-import org.apache.qpid.transport.NetworkDriver;
-import org.apache.qpid.transport.Connection;
-import org.apache.qpid.transport.ConnectionDelegate;
-import org.apache.qpid.server.transport.ServerConnection;
-import org.apache.qpid.server.protocol.ProtocolEngine_0_10;
-
-public class ProtocolEngineFactory_0_10 implements ProtocolEngineFactory
-{
- private ConnectionDelegate _delegate;
-
- public ProtocolEngineFactory_0_10(ConnectionDelegate delegate)
- {
- _delegate = delegate;
- }
-
- public ProtocolEngine newProtocolEngine(NetworkDriver networkDriver)
- {
- Connection conn = new ServerConnection();
- conn.setConnectionDelegate(_delegate);
- return new ProtocolEngine_0_10(conn, networkDriver);
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java
index e3cd3acd98..473f68028d 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java
@@ -26,23 +26,34 @@ import org.apache.qpid.transport.Connection;
import org.apache.qpid.transport.network.InputHandler;
import org.apache.qpid.transport.network.Assembler;
import org.apache.qpid.transport.network.Disassembler;
+import org.apache.qpid.server.configuration.*;
+import org.apache.qpid.server.transport.ServerConnection;
+import org.apache.qpid.server.registry.IApplicationRegistry;
import java.net.SocketAddress;
+import java.util.UUID;
-public class ProtocolEngine_0_10 extends InputHandler implements ProtocolEngine
+public class ProtocolEngine_0_10 extends InputHandler implements ProtocolEngine, ConnectionConfig
{
public static final int MAX_FRAME_SIZE = 64 * 1024 - 1;
private NetworkDriver _networkDriver;
private long _readBytes;
private long _writtenBytes;
- private Connection _connection;
+ private ServerConnection _connection;
+ private final UUID _id;
+ private final IApplicationRegistry _appRegistry;
- public ProtocolEngine_0_10(Connection conn, NetworkDriver networkDriver)
+ public ProtocolEngine_0_10(ServerConnection conn,
+ NetworkDriver networkDriver,
+ final IApplicationRegistry appRegistry)
{
super(new Assembler(conn));
_connection = conn;
+ _connection.setConnectionConfig(this);
_networkDriver = networkDriver;
+ _id = appRegistry.getConfigStore().createId();
+ _appRegistry = appRegistry;
}
public void setNetworkDriver(NetworkDriver driver)
@@ -50,6 +61,14 @@ public class ProtocolEngine_0_10 extends InputHandler implements ProtocolEngine
_networkDriver = driver;
Disassembler dis = new Disassembler(driver, MAX_FRAME_SIZE);
_connection.setSender(dis);
+ _connection.onOpen(new Runnable()
+ {
+ public void run()
+ {
+ getConfigStore().addConfiguredObject(ProtocolEngine_0_10.this);
+ }
+ });
+
}
public SocketAddress getRemoteAddress()
@@ -81,4 +100,81 @@ public class ProtocolEngine_0_10 extends InputHandler implements ProtocolEngine
{
//Todo
}
+
+ public VirtualHostConfig getVirtualHost()
+ {
+ return _connection.getVirtualHost();
+ }
+
+ public String getAddress()
+ {
+ return getRemoteAddress().toString();
+ }
+
+ public Boolean isIncoming()
+ {
+ return true;
+ }
+
+ public Boolean isSystemConnection()
+ {
+ return false;
+ }
+
+ public Boolean isFederationLink()
+ {
+ return false;
+ }
+
+ public String getAuthId()
+ {
+ return _connection.getAuthorizationID();
+ }
+
+ public String getRemoteProcessName()
+ {
+ return null;
+ }
+
+ public Integer getRemotePID()
+ {
+ return null;
+ }
+
+ public Integer getRemoteParentPID()
+ {
+ return null;
+ }
+
+ public ConfigStore getConfigStore()
+ {
+ return _appRegistry.getConfigStore();
+ }
+
+ public UUID getId()
+ {
+ return _id;
+ }
+
+ public ConnectionConfigType getConfigType()
+ {
+ return ConnectionConfigType.getInstance();
+ }
+
+ public ConfiguredObject getParent()
+ {
+ return getVirtualHost();
+ }
+
+ public boolean isDurable()
+ {
+ return false;
+ }
+
+ @Override
+ public void closed()
+ {
+ super.closed();
+ getConfigStore().removeConfiguredObject(this);
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java
index 51fbff76f4..d8986ec303 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java
@@ -21,9 +21,11 @@
package org.apache.qpid.server.queue;
import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.subscription.SubscriptionList;
import org.apache.qpid.server.subscription.Subscription;
+import org.apache.qpid.server.subscription.SubscriptionList;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+
+import java.util.Map;
public class AMQPriorityQueue extends SimpleAMQQueue
{
@@ -32,18 +34,18 @@ public class AMQPriorityQueue extends SimpleAMQQueue
final AMQShortString owner,
final boolean autoDelete,
final VirtualHost virtualHost,
- int priorities)
+ int priorities, Map<String, Object> arguments)
{
- super(name, durable, owner, autoDelete, virtualHost, new PriorityQueueList.Factory(priorities));
+ super(name, durable, owner, autoDelete, virtualHost, new PriorityQueueList.Factory(priorities),arguments);
}
public AMQPriorityQueue(String queueName,
boolean durable,
String owner,
boolean autoDelete,
- VirtualHost virtualHost, int priorities)
+ VirtualHost virtualHost, int priorities, Map<String,Object> arguments)
{
- this(new AMQShortString(queueName), durable, new AMQShortString(owner),autoDelete,virtualHost,priorities);
+ this(queueName == null ? null : new AMQShortString(queueName), durable, owner == null ? null : new AMQShortString(owner),autoDelete,virtualHost,priorities, arguments);
}
public int getPriorities()
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
index 028f7e15a4..81ea2083e0 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
@@ -20,44 +20,48 @@
*/
package org.apache.qpid.server.queue;
-import org.apache.qpid.server.management.Managable;
-import org.apache.qpid.server.management.ManagedObject;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.AMQChannel;
+import org.apache.qpid.server.binding.Binding;
+import org.apache.qpid.server.configuration.QueueConfig;
import org.apache.qpid.server.configuration.QueueConfiguration;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.exchange.ExchangeReferrer;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.server.subscription.Subscription;
-import org.apache.qpid.server.AMQChannel;
-import org.apache.qpid.server.store.TransactionLogResource;
+import org.apache.qpid.server.management.Managable;
+import org.apache.qpid.server.management.ManagedObject;
import org.apache.qpid.server.security.PrincipalHolder;
+import org.apache.qpid.server.store.TransactionLogResource;
+import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.txn.ServerTransaction;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.AMQException;
+import org.apache.qpid.server.virtualhost.VirtualHost;
import java.util.List;
-import java.util.Set;
import java.util.Map;
+import java.util.Set;
-public interface AMQQueue extends Managable, Comparable<AMQQueue>, ExchangeReferrer, TransactionLogResource
+public interface AMQQueue extends Managable, Comparable<AMQQueue>, ExchangeReferrer, TransactionLogResource, BaseQueue,
+ QueueConfig
{
boolean getDeleteOnNoConsumers();
void setDeleteOnNoConsumers(boolean b);
+ void addBinding(Binding binding);
+
+ void removeBinding(Binding binding);
+
+ List<Binding> getBindings();
+
+ int getBindingCount();
public interface Context
{
QueueEntry getLastSeenEntry();
}
- AMQShortString getName();
-
void setNoLocal(boolean b);
- boolean isDurable();
-
boolean isAutoDelete();
AMQShortString getOwner();
@@ -69,14 +73,6 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>, ExchangeRefer
VirtualHost getVirtualHost();
-
- void bind(Exchange exchange, AMQShortString routingKey, FieldTable arguments) throws AMQException;
-
- void unBind(Exchange exchange, AMQShortString routingKey, FieldTable arguments) throws AMQException;
-
- List<ExchangeBinding> getExchangeBindings();
-
-
void registerSubscription(final Subscription subscription, final boolean exclusive) throws AMQException;
void unregisterSubscription(final Subscription subscription) throws AMQException;
@@ -86,6 +82,8 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>, ExchangeRefer
int getActiveConsumerCount();
+ boolean hasExclusiveSubscriber();
+
boolean isUnused();
boolean isEmpty();
@@ -107,8 +105,6 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>, ExchangeRefer
int delete() throws AMQException;
- QueueEntry enqueue(ServerMessage message) throws AMQException;
-
void requeue(QueueEntry entry);
void requeue(QueueEntryImpl storeContext, Subscription subscription);
@@ -122,6 +118,8 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>, ExchangeRefer
void addQueueDeleteTask(final Task task);
+ void removeQueueDeleteTask(final Task task);
+
List<QueueEntry> getMessagesOnTheQueue();
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java
index d4a5b3258b..fd7dd4cc60 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java
@@ -23,16 +23,21 @@ package org.apache.qpid.server.queue;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.server.configuration.QueueConfiguration;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.configuration.QueueConfiguration;
import java.util.Map;
+import java.util.HashMap;
public class AMQQueueFactory
{
public static final AMQShortString X_QPID_PRIORITIES = new AMQShortString("x-qpid-priorities");
+ private static final String QPID_LVQ_KEY = "qpid.LVQ_key";
+ private static final String QPID_LAST_VALUE_QUEUE = "qpid.last_value_queue";
+ private static final String QPID_LAST_VALUE_QUEUE_KEY = "qpid.last_value_queue_key";
+
private abstract static class QueueProperty
{
@@ -130,21 +135,60 @@ public class AMQQueueFactory
boolean autoDelete,
VirtualHost virtualHost, final FieldTable arguments)
{
- final int priorities = arguments == null ? 1 : arguments.containsKey(X_QPID_PRIORITIES) ? arguments.getInteger(X_QPID_PRIORITIES) : 1;
+ return createAMQQueueImpl(name == null ? null : name.toString(),
+ durable,
+ owner == null ? null : owner.toString(),
+ autoDelete,
+ virtualHost,
+ FieldTable.convertToMap(arguments));
+ }
- AMQQueue q = null;
- if(priorities > 1)
+
+ public static AMQQueue createAMQQueueImpl(String queueName,
+ boolean durable,
+ String owner,
+ boolean autoDelete,
+ VirtualHost virtualHost, Map<String, Object> arguments)
+ {
+ int priorities = 1;
+ String conflationKey = null;
+ if(arguments != null)
{
- q = new AMQPriorityQueue(name, durable, owner, autoDelete, virtualHost, priorities);
+ if(arguments.containsKey(QPID_LAST_VALUE_QUEUE) || arguments.containsKey(QPID_LAST_VALUE_QUEUE_KEY))
+ {
+ conflationKey = (String) arguments.get(QPID_LAST_VALUE_QUEUE_KEY);
+ if(conflationKey == null)
+ {
+ conflationKey = QPID_LVQ_KEY;
+ }
+ }
+ else if(arguments.containsKey(X_QPID_PRIORITIES))
+ {
+ Object prioritiesObj = arguments.get(X_QPID_PRIORITIES);
+ if(prioritiesObj instanceof Number)
+ {
+ priorities = ((Number)prioritiesObj).intValue();
+ }
+ }
+ }
+
+ AMQQueue q;
+ if(conflationKey != null)
+ {
+ q = new ConflationQueue(queueName, durable, owner, autoDelete, virtualHost, arguments, conflationKey);
+ }
+ else if(priorities > 1)
+ {
+ q = new AMQPriorityQueue(queueName, durable, owner, autoDelete, virtualHost, priorities, arguments);
}
else
{
- q = new SimpleAMQQueue(name, durable, owner, autoDelete, virtualHost);
+ q = new SimpleAMQQueue(queueName, durable, owner, autoDelete, virtualHost, arguments);
}
//Register the new queue
virtualHost.getQueueRegistry().registerQueue(q);
- q.configure(virtualHost.getConfiguration().getQueueConfiguration(name.asString()));
+ q.configure(virtualHost.getConfiguration().getQueueConfiguration(queueName));
if(arguments != null)
{
@@ -158,29 +202,43 @@ public class AMQQueueFactory
}
return q;
+
}
+
public static AMQQueue createAMQQueueImpl(QueueConfiguration config, VirtualHost host) throws AMQException
{
- AMQShortString queueName = new AMQShortString(config.getName());
+ String queueName = config.getName();
boolean durable = config.getDurable();
boolean autodelete = config.getAutoDelete();
- AMQShortString owner = (config.getOwner() != null) ? new AMQShortString(config.getOwner()) : null;
- FieldTable arguments = null;
- boolean priority = config.getPriority();
- int priorities = config.getPriorities();
- if(priority || priorities > 0)
+ String owner = config.getOwner();
+ Map<String,Object> arguments = null;
+ if(config.isLVQ() || config.getLVQKey() != null)
{
if(arguments == null)
{
- arguments = new FieldTable();
+ arguments = new HashMap<String,Object>();
}
- if (priorities < 0)
+ arguments.put(QPID_LAST_VALUE_QUEUE, 1);
+ arguments.put(QPID_LAST_VALUE_QUEUE_KEY, config.getLVQKey() == null ? QPID_LVQ_KEY : config.getLVQKey());
+ }
+ else
+ {
+ boolean priority = config.getPriority();
+ int priorities = config.getPriorities();
+ if(priority || priorities > 0)
{
- priorities = 10;
+ if(arguments == null)
+ {
+ arguments = new HashMap<String,Object>();
+ }
+ if (priorities < 0)
+ {
+ priorities = 10;
+ }
+ arguments.put("x-qpid-priorities", priorities);
}
- arguments.put(new AMQShortString("x-qpid-priorities"), priorities);
}
AMQQueue q = createAMQQueueImpl(queueName, durable, owner, autodelete, host, arguments);
@@ -188,38 +246,4 @@ public class AMQQueueFactory
return q;
}
- public static AMQQueue createAMQQueueImpl(String queueName,
- boolean durable,
- String owner,
- boolean autoDelete,
- VirtualHost virtualHost, Map<String, Object> arguments)
- throws AMQException
- {
- int priorities = 1;
- if(arguments != null && arguments.containsKey(X_QPID_PRIORITIES))
- {
- Object prioritiesObj = arguments.get(X_QPID_PRIORITIES);
- if(prioritiesObj instanceof Number)
- {
- priorities = ((Number)prioritiesObj).intValue();
- }
- }
-
-
- AMQQueue q = null;
- if(priorities > 1)
- {
- q = new AMQPriorityQueue(queueName, durable, owner, autoDelete, virtualHost, priorities);
- }
- else
- {
- q = new SimpleAMQQueue(queueName, durable, owner, autoDelete, virtualHost);
- }
-
- //Register the new queue
- virtualHost.getQueueRegistry().registerQueue(q);
- q.configure(virtualHost.getConfiguration().getQueueConfiguration(queueName));
- return q;
-
- }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java
index c21d73cc41..6102e525e3 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java
@@ -95,7 +95,7 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
{
super(ManagedQueue.class, ManagedQueue.TYPE);
_queue = queue;
- _queueName = jmxEncode(new StringBuffer(queue.getName()), 0).toString();
+ _queueName = jmxEncode(new StringBuffer(queue.getNameShortString()), 0).toString();
}
public ManagedObject getParentObject()
@@ -252,7 +252,7 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
{
throw new IllegalArgumentException("Capacity must not be less than FlowResumeCapacity");
}
-
+
_queue.setCapacity(capacity);
}
@@ -267,10 +267,10 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
{
throw new IllegalArgumentException("FlowResumeCapacity must not exceed Capacity");
}
-
+
_queue.setFlowResumeCapacity(flowResumeCapacity);
}
-
+
public boolean isFlowOverfull()
{
return _queue.isOverfull();
@@ -309,7 +309,7 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
public void notifyClients(NotificationCheck notification, AMQQueue queue, String notificationMsg)
{
// important : add log to the log file - monitoring tools may be looking for this
- _logger.info(notification.name() + " On Queue " + queue.getName() + " - " + notificationMsg);
+ _logger.info(notification.name() + " On Queue " + queue.getNameShortString() + " - " + notificationMsg);
notificationMsg = notification.name() + " " + notificationMsg;
_lastNotification =
@@ -509,7 +509,7 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
private String[] getMessageTransferMessageHeaderProps(MessageTransferMessage msg)
{
List<String> list = new ArrayList<String>();
-
+
AMQMessageHeader header = msg.getMessageHeader();
MessageProperties msgProps = msg.getHeader().get(MessageProperties.class);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/BaseQueue.java b/java/broker/src/main/java/org/apache/qpid/server/queue/BaseQueue.java
new file mode 100644
index 0000000000..05e0efd9a6
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/BaseQueue.java
@@ -0,0 +1,42 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.server.queue;
+
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.server.store.TransactionLogResource;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+
+public interface BaseQueue extends TransactionLogResource
+{
+ public static interface PostEnqueueAction
+ {
+ public void onEnqueue(QueueEntry entry);
+ }
+
+ void enqueue(ServerMessage message) throws AMQException;
+ void enqueue(ServerMessage message, PostEnqueueAction action) throws AMQException;
+
+ boolean isDurable();
+
+ AMQShortString getNameShortString();
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueue.java b/java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueue.java
new file mode 100644
index 0000000000..26c0d7cf26
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueue.java
@@ -0,0 +1,42 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.server.queue;
+
+import org.apache.qpid.server.virtualhost.VirtualHost;
+
+import java.util.Map;
+
+public class ConflationQueue extends SimpleAMQQueue
+{
+ protected ConflationQueue(String name,
+ boolean durable,
+ String owner,
+ boolean autoDelete,
+ VirtualHost virtualHost,
+ Map<String, Object> args,
+ String conflationKey)
+ {
+ super(name, durable, owner, autoDelete, virtualHost, new ConflationQueueList.Factory(conflationKey), args);
+ }
+
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueueList.java b/java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueueList.java
new file mode 100644
index 0000000000..9a6e5c884a
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueueList.java
@@ -0,0 +1,168 @@
+/*
+ *
+ * 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.queue;
+
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.BasicContentHeaderProperties;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.server.store.StoreContext;
+import org.apache.qpid.server.subscription.Subscription;
+import org.apache.qpid.server.AMQChannel;
+import org.apache.qpid.server.txn.ServerTransaction;
+import org.apache.qpid.server.txn.AutoCommitTransaction;
+import org.apache.qpid.server.message.ServerMessage;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicReference;
+
+public class ConflationQueueList extends SimpleQueueEntryList
+{
+
+ private final String _conflationKey;
+ private final ConcurrentHashMap<Object, AtomicReference<QueueEntry>> _latestValuesMap =
+ new ConcurrentHashMap<Object, AtomicReference<QueueEntry>>();
+
+ public ConflationQueueList(AMQQueue queue, String conflationKey)
+ {
+ super(queue);
+ _conflationKey = conflationKey;
+ }
+
+ @Override
+ protected ConflationQueueEntry createQueueEntry(ServerMessage message)
+ {
+ return new ConflationQueueEntry(this, message);
+ }
+
+
+ @Override
+ public QueueEntry add(final ServerMessage message)
+ {
+ ConflationQueueEntry entry = (ConflationQueueEntry) (super.add(message));
+ AtomicReference<QueueEntry> latestValueReference = null;
+
+ Object value = message.getMessageHeader().getHeader(_conflationKey);
+ if(value != null)
+ {
+ latestValueReference = _latestValuesMap.get(value);
+ if(latestValueReference == null)
+ {
+ _latestValuesMap.putIfAbsent(value, new AtomicReference<QueueEntry>(entry));
+ latestValueReference = _latestValuesMap.get(value);
+ }
+ QueueEntry oldEntry;
+
+ do
+ {
+ oldEntry = latestValueReference.get();
+ }
+ while(oldEntry.compareTo(entry) < 0 && !latestValueReference.compareAndSet(oldEntry, entry));
+
+ if(oldEntry.compareTo(entry) < 0)
+ {
+ // We replaced some other entry to become the newest value
+ if(oldEntry.acquire())
+ {
+ discardEntry(oldEntry);
+ }
+ }
+ else if (oldEntry.compareTo(entry) > 0)
+ {
+ // A newer entry came along
+ discardEntry(entry);
+
+ }
+ }
+
+ entry.setLatestValueReference(latestValueReference);
+ return entry;
+ }
+
+ private void discardEntry(final QueueEntry entry)
+ {
+ if(entry.acquire())
+ {
+ ServerTransaction txn = new AutoCommitTransaction(getQueue().getVirtualHost().getTransactionLog());
+ txn.dequeue(entry.getQueue(),entry.getMessage(),
+ new ServerTransaction.Action()
+ {
+ public void postCommit()
+ {
+ entry.discard();
+ }
+
+ public void onRollback()
+ {
+
+ }
+ });
+ }
+ }
+
+ private final class ConflationQueueEntry extends QueueEntryImpl
+ {
+
+
+ private AtomicReference<QueueEntry> _latestValueReference;
+
+ public ConflationQueueEntry(SimpleQueueEntryList queueEntryList, ServerMessage message)
+ {
+ super(queueEntryList, message);
+ }
+
+
+ public void release()
+ {
+ super.release();
+
+ if(_latestValueReference != null)
+ {
+ if(_latestValueReference.get() != this)
+ {
+ discardEntry(this);
+ }
+ }
+
+ }
+
+ public void setLatestValueReference(final AtomicReference<QueueEntry> latestValueReference)
+ {
+ _latestValueReference = latestValueReference;
+ }
+ }
+
+ static class Factory implements QueueEntryListFactory
+ {
+ private final String _conflationKey;
+
+ Factory(String conflationKey)
+ {
+ _conflationKey = conflationKey;
+ }
+
+ public QueueEntryList createQueueEntryList(AMQQueue queue)
+ {
+ return new ConflationQueueList(queue, _conflationKey);
+ }
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java
index aea485e749..d76487073d 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java
@@ -20,7 +20,6 @@
*/
package org.apache.qpid.server.queue;
-import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.virtualhost.VirtualHost;
@@ -46,7 +45,7 @@ public class DefaultQueueRegistry implements QueueRegistry
public void registerQueue(AMQQueue queue)
{
- _queueMap.put(queue.getName(), queue);
+ _queueMap.put(queue.getNameShortString(), queue);
}
public void unregisterQueue(AMQShortString name)
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/ExchangeBinding.java b/java/broker/src/main/java/org/apache/qpid/server/queue/ExchangeBinding.java
deleted file mode 100644
index 2fd8e32fcd..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/ExchangeBinding.java
+++ /dev/null
@@ -1,91 +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.queue;
-
-import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.messages.BindingMessages;
-import org.apache.qpid.server.logging.subjects.BindingLogSubject;
-import org.apache.qpid.server.logging.LogSubject;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.AMQException;
-
-public class ExchangeBinding
-{
- private final Exchange _exchange;
- private final AMQShortString _routingKey;
- private final FieldTable _arguments;
-
- private static final FieldTable EMPTY_ARGUMENTS = new FieldTable();
- private LogSubject _logSubject;
-
- ExchangeBinding(AMQShortString routingKey, Exchange exchange, AMQQueue queue, FieldTable arguments)
- {
- _routingKey = routingKey == null ? AMQShortString.EMPTY_STRING : routingKey;
- _exchange = exchange;
- _arguments = arguments == null ? EMPTY_ARGUMENTS : arguments;
- _logSubject = new BindingLogSubject(routingKey,exchange,queue);
-
- CurrentActor.get().message(_logSubject, BindingMessages.BND_CREATED(String.valueOf(_arguments), arguments != null));
- }
-
-
-
- void unbind(AMQQueue queue) throws AMQException
- {
- _exchange.deregisterQueue(_routingKey, queue, _arguments);
-
- CurrentActor.get().message(_logSubject, BindingMessages.BND_DELETED());
- }
-
- public Exchange getExchange()
- {
- return _exchange;
- }
-
- public AMQShortString getRoutingKey()
- {
- return _routingKey;
- }
-
- public FieldTable getArguments()
- {
- return _arguments;
- }
-
- public int hashCode()
- {
- return (_exchange == null ? 0 : _exchange.hashCode())
- + (_routingKey == null ? 0 : _routingKey.hashCode());
- }
-
- public boolean equals(Object o)
- {
- if (!(o instanceof ExchangeBinding))
- {
- return false;
- }
- ExchangeBinding eb = (ExchangeBinding) o;
- return _exchange.equals(eb._exchange)
- && _routingKey.equals(eb._routingKey);
- }
-} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/ExchangeBindings.java b/java/broker/src/main/java/org/apache/qpid/server/queue/ExchangeBindings.java
deleted file mode 100644
index 89262aee59..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/ExchangeBindings.java
+++ /dev/null
@@ -1,82 +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.queue;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.server.exchange.Exchange;
-
-/**
- * When a queue is deleted, it should be deregistered from any
- * exchange it has been bound to. This class assists in this task,
- * by keeping track of all bindings for a given queue.
- */
-class ExchangeBindings
-{
- private final List<ExchangeBinding> _bindings = new CopyOnWriteArrayList<ExchangeBinding>();
- private final AMQQueue _queue;
-
- ExchangeBindings(AMQQueue queue)
- {
- _queue = queue;
- }
-
- /**
- * Adds the specified binding to those being tracked.
- * @param routingKey the routing key with which the queue whose bindings
- * are being tracked by the instance has been bound to the exchange
- * @param exchange the exchange bound to
- */
- void addBinding(AMQShortString routingKey, FieldTable arguments, Exchange exchange)
- {
- _bindings.add(new ExchangeBinding(routingKey, exchange, _queue, arguments));
- }
-
-
- public boolean remove(AMQShortString routingKey, FieldTable arguments, Exchange exchange)
- {
- return _bindings.remove(new ExchangeBinding(routingKey, exchange, _queue, arguments));
- }
-
-
- /**
- * Deregisters this queue from any exchange it has been bound to
- */
- void deregister() throws AMQException
- {
- //remove duplicates at this point
- HashSet<ExchangeBinding> copy = new HashSet<ExchangeBinding>(_bindings);
- for (ExchangeBinding b : copy)
- {
- b.unbind(_queue);
- }
- }
-
- List<ExchangeBinding> getExchangeBindings()
- {
- return _bindings;
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java b/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java
index da4173d5d3..2d2fb3a214 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java
@@ -63,7 +63,7 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes
* delivered. It is <b>cleared after delivery has been attempted</b>. Any persistent record of destinations is done
* by the message handle.
*/
- private ArrayList<AMQQueue> _destinationQueues;
+ private ArrayList<? extends BaseQueue> _destinationQueues;
private long _expiration;
@@ -131,7 +131,7 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes
}
- public ArrayList<AMQQueue> getDestinationQueues()
+ public ArrayList<? extends BaseQueue> getDestinationQueues()
{
return _destinationQueues;
}
@@ -225,7 +225,7 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes
}
- public void enqueue(final ArrayList<AMQQueue> queues)
+ public void enqueue(final ArrayList<? extends BaseQueue> queues)
{
_destinationQueues = queues;
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java
index a50e2b561d..edd1e0bdc3 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java
@@ -28,6 +28,7 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable
{
+
public static enum State
{
AVAILABLE,
@@ -163,6 +164,8 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable
boolean expired() throws AMQException;
+ boolean isAvailable();
+
boolean isAcquired();
boolean acquire();
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java
index 5873e8f566..ada7726fc0 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java
@@ -20,20 +20,23 @@
*/
package org.apache.qpid.server.queue;
+import org.apache.log4j.Logger;
+
import org.apache.qpid.AMQException;
-import org.apache.qpid.server.subscription.Subscription;
-import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.server.message.MessageReference;
-import org.apache.qpid.server.message.AMQMessageHeader;
import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.message.AMQMessageHeader;
+import org.apache.qpid.server.message.MessageReference;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.txn.AutoCommitTransaction;
import org.apache.qpid.server.txn.ServerTransaction;
-import org.apache.log4j.Logger;
-import java.util.*;
-import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
-import java.util.concurrent.atomic.AtomicLongFieldUpdater;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.atomic.AtomicLongFieldUpdater;
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
public class QueueEntryImpl implements QueueEntry
@@ -154,6 +157,11 @@ public class QueueEntryImpl implements QueueEntry
}
+ public boolean isAvailable()
+ {
+ return _state == AVAILABLE_STATE;
+ }
+
public boolean isAcquired()
{
return _state.getState() == State.ACQUIRED;
@@ -408,7 +416,7 @@ public class QueueEntryImpl implements QueueEntry
if(alternateExchange != null)
{
- final List<AMQQueue> rerouteQueues = alternateExchange.route(new InboundMessageAdapter(this));
+ final List<? extends BaseQueue> rerouteQueues = alternateExchange.route(new InboundMessageAdapter(this));
final ServerMessage message = getMessage();
if(rerouteQueues != null && rerouteQueues.size() != 0)
{
@@ -419,9 +427,9 @@ public class QueueEntryImpl implements QueueEntry
{
try
{
- for(AMQQueue queue : rerouteQueues)
+ for(BaseQueue queue : rerouteQueues)
{
- QueueEntry entry = queue.enqueue(message);
+ queue.enqueue(message);
}
}
catch (AMQException e)
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java b/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java
index 825aa9795e..d25d73b383 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java
@@ -1,39 +1,51 @@
package org.apache.qpid.server.queue;
-import java.util.*;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.Executor;
-import java.util.concurrent.atomic.*;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import javax.management.JMException;
-
import org.apache.log4j.Logger;
+
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.pool.ReadWriteRunnable;
import org.apache.qpid.pool.ReferenceCountingExecutorService;
+import org.apache.qpid.server.AMQChannel;
+import org.apache.qpid.server.binding.Binding;
+import org.apache.qpid.server.configuration.ConfigStore;
+import org.apache.qpid.server.configuration.ConfiguredObject;
+import org.apache.qpid.server.configuration.QueueConfigType;
import org.apache.qpid.server.configuration.QueueConfiguration;
import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.logging.LogActor;
+import org.apache.qpid.server.logging.LogSubject;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.actors.QueueActor;
+import org.apache.qpid.server.logging.messages.QueueMessages;
+import org.apache.qpid.server.logging.subjects.QueueLogSubject;
import org.apache.qpid.server.management.ManagedObject;
+import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.security.PrincipalHolder;
import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.subscription.SubscriptionList;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.server.security.PrincipalHolder;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.actors.QueueActor;
-import org.apache.qpid.server.logging.subjects.QueueLogSubject;
-import org.apache.qpid.server.logging.LogSubject;
-import org.apache.qpid.server.logging.LogActor;
-import org.apache.qpid.server.logging.messages.QueueMessages;
-import org.apache.qpid.server.AMQChannel;
-import org.apache.qpid.server.txn.ServerTransaction;
import org.apache.qpid.server.txn.AutoCommitTransaction;
import org.apache.qpid.server.txn.LocalTransaction;
+import org.apache.qpid.server.txn.ServerTransaction;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+
+import javax.management.JMException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
/*
*
@@ -81,7 +93,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
private Exchange _alternateExchange;
/** Used to track bindings to exchanges so that on deletion they can easily be cancelled. */
- private final ExchangeBindings _bindings = new ExchangeBindings(this);
+
protected final QueueEntryList _entries;
@@ -102,8 +114,15 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
private final AtomicLong _totalMessagesReceived = new AtomicLong();
+ private final AtomicLong _dequeueCount = new AtomicLong();
+ private final AtomicLong _dequeueSize = new AtomicLong();
+ private final AtomicLong _enqueueSize = new AtomicLong();
+ private final AtomicLong _persistentMessageEnqueueSize = new AtomicLong();
+ private final AtomicLong _persistentMessageDequeueSize = new AtomicLong();
+ private final AtomicLong _persistentMessageEnqueueCount = new AtomicLong();;
+ private final AtomicLong _persistentMessageDequeueCount = new AtomicLong();
-
+ private final AtomicInteger _bindingCountHigh = new AtomicInteger();
/** max allowed size(KB) of a single message */
public long _maximumMessageSize = ApplicationRegistry.getInstance().getConfiguration().getMaximumMessageSize();
@@ -151,18 +170,38 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
private final AtomicBoolean _overfull = new AtomicBoolean(false);
private boolean _deleteOnNoConsumers;
+ private final CopyOnWriteArrayList<Binding> _bindings = new CopyOnWriteArrayList<Binding>();
+ private UUID _id;
+ private final Map<String, Object> _arguments;
+
+ //TODO
+ private long _createTime = System.currentTimeMillis();
+
- protected SimpleAMQQueue(AMQShortString name, boolean durable, AMQShortString owner, boolean autoDelete, VirtualHost virtualHost)
+ protected SimpleAMQQueue(AMQShortString name, boolean durable, AMQShortString owner, boolean autoDelete, VirtualHost virtualHost, Map<String,Object> arguments)
{
- this(name, durable, owner, autoDelete, virtualHost, new SimpleQueueEntryList.Factory());
+ this(name, durable, owner, autoDelete, virtualHost, new SimpleQueueEntryList.Factory(),arguments);
}
+ public SimpleAMQQueue(String queueName, boolean durable, String owner, boolean autoDelete, VirtualHost virtualHost, Map<String, Object> arguments)
+ {
+ this(queueName, durable, owner,autoDelete,virtualHost,new SimpleQueueEntryList.Factory(),arguments);
+ }
+
+ public SimpleAMQQueue(String queueName, boolean durable, String owner, boolean autoDelete, VirtualHost virtualHost, QueueEntryListFactory entryListFactory, Map<String, Object> arguments)
+ {
+ this(queueName == null ? null : new AMQShortString(queueName), durable, owner == null ? null : new AMQShortString(owner),autoDelete,virtualHost,entryListFactory, arguments);
+ }
+
+
+
protected SimpleAMQQueue(AMQShortString name,
boolean durable,
AMQShortString owner,
boolean autoDelete,
VirtualHost virtualHost,
- QueueEntryListFactory entryListFactory)
+ QueueEntryListFactory entryListFactory,
+ Map<String,Object> arguments)
{
if (name == null)
@@ -182,6 +221,9 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
_autoDelete = autoDelete;
_virtualHost = virtualHost;
_entries = entryListFactory.createQueueEntryList(this);
+ _arguments = arguments;
+
+ _id = virtualHost.getConfigStore().createId();
_asyncDelivery = ReferenceCountingExecutorService.getInstance().acquireExecutorService();
@@ -208,6 +250,8 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
durable, !durable,
priorities > 0));
+ getConfigStore().addConfiguredObject(this);
+
try
{
_managedObject = new AMQQueueMBean(this);
@@ -222,12 +266,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
}
- public SimpleAMQQueue(String queueName, boolean durable, String owner, boolean autoDelete, VirtualHost virtualHost)
- throws AMQException
- {
- this(new AMQShortString(queueName), durable, owner == null ? null : new AMQShortString(owner),autoDelete,virtualHost);
- }
-
public void resetNotifications()
{
// This ensure that the notification checks for the configured alerts are created.
@@ -244,7 +282,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
_asyncDelivery.execute(runnable);
}
- public AMQShortString getName()
+ public AMQShortString getNameShortString()
{
return _name;
}
@@ -254,6 +292,21 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
_nolocal = nolocal;
}
+ public UUID getId()
+ {
+ return _id;
+ }
+
+ public QueueConfigType getConfigType()
+ {
+ return QueueConfigType.getInstance();
+ }
+
+ public ConfiguredObject getParent()
+ {
+ return getVirtualHost();
+ }
+
public boolean isDurable()
{
return _durable;
@@ -284,7 +337,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
public Map<String, Object> getArguments()
{
- return null;
+ return _arguments;
}
public boolean isAutoDelete()
@@ -313,56 +366,9 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
return _virtualHost;
}
- // ------ bind and unbind
-
- public void bind(Exchange exchange, String bindingKey, Map<String, Object> arguments) throws AMQException
- {
-
- FieldTable fieldTable = FieldTable.convertToFieldTable(arguments);
- AMQShortString routingKey = new AMQShortString(bindingKey);
-
- exchange.registerQueue(routingKey, this, fieldTable);
-
- if (isDurable() && exchange.isDurable())
- {
-
- _virtualHost.getDurableConfigurationStore().bindQueue(exchange, routingKey, this, fieldTable);
- }
-
- _bindings.addBinding(routingKey, fieldTable, exchange);
- }
-
-
- public void bind(Exchange exchange, AMQShortString routingKey, FieldTable arguments) throws AMQException
- {
-
- exchange.registerQueue(routingKey, this, arguments);
- if (isDurable() && exchange.isDurable())
- {
- _virtualHost.getDurableConfigurationStore().bindQueue(exchange, routingKey, this, arguments);
- }
-
- _bindings.addBinding(routingKey, arguments, exchange);
- }
-
- public void unBind(Exchange exchange, AMQShortString routingKey, FieldTable arguments) throws AMQException
+ public String getName()
{
- exchange.deregisterQueue(routingKey, this, arguments);
- if (isDurable() && exchange.isDurable())
- {
- _virtualHost.getDurableConfigurationStore().unbindQueue(exchange, routingKey, this, arguments);
- }
-
- boolean removed = _bindings.remove(routingKey, arguments, exchange);
- if (!removed)
- {
- _logger.error("Mismatch between queue bindings and exchange record of bindings");
- }
- }
-
- public List<ExchangeBinding> getExchangeBindings()
- {
- return new ArrayList<ExchangeBinding>(_bindings.getExchangeBindings());
+ return getNameShortString().toString();
}
// ------ Manage Subscriptions
@@ -370,7 +376,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
public synchronized void registerSubscription(final Subscription subscription, final boolean exclusive) throws AMQException
{
- if (isExclusiveSubscriber())
+ if (hasExclusiveSubscriber())
{
throw new ExistingExclusiveSubscription();
}
@@ -459,17 +465,54 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
_deleteOnNoConsumers = b;
}
+ public void addBinding(final Binding binding)
+ {
+ _bindings.add(binding);
+ int bindingCount = _bindings.size();
+ int bindingCountHigh;
+ while(bindingCount > (bindingCountHigh = _bindingCountHigh.get()))
+ {
+ if(_bindingCountHigh.compareAndSet(bindingCountHigh, bindingCount))
+ {
+ break;
+ }
+ }
+ }
+
+ public int getBindingCountHigh()
+ {
+ return _bindingCountHigh.get();
+ }
+
+ public void removeBinding(final Binding binding)
+ {
+ _bindings.remove(binding);
+ }
+
+ public List<Binding> getBindings()
+ {
+ return Collections.unmodifiableList(_bindings);
+ }
+
+ public int getBindingCount()
+ {
+ return getBindings().size();
+ }
// ------ Enqueue / Dequeue
+ public void enqueue(ServerMessage message) throws AMQException
+ {
+ enqueue(message, null);
+ }
- public QueueEntry enqueue(ServerMessage message) throws AMQException
+ public void enqueue(ServerMessage message, PostEnqueueAction action) throws AMQException
{
incrementQueueCount();
incrementQueueSize(message);
-
_totalMessagesReceived.incrementAndGet();
+
QueueEntry entry;
Subscription exclusiveSub = _exclusiveSubscriber;
@@ -554,7 +597,11 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
_managedObject.checkForNotification(entry.getMessage());
}
- return entry;
+ if(action != null)
+ {
+ action.onEnqueue(entry);
+ }
+
}
private void deliverToSubscription(final Subscription sub, final QueueEntry entry)
@@ -596,7 +643,14 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
private void incrementQueueSize(final ServerMessage message)
{
- getAtomicQueueSize().addAndGet(message.getSize());
+ long size = message.getSize();
+ getAtomicQueueSize().addAndGet(size);
+ _enqueueSize.addAndGet(size);
+ if(message.isPersistent() && isDurable())
+ {
+ _persistentMessageEnqueueSize.addAndGet(size);
+ _persistentMessageEnqueueCount.incrementAndGet();
+ }
}
private void incrementQueueCount()
@@ -654,7 +708,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
SubscriptionList.SubscriptionNodeIterator subscriberIter = _subscriptionList.iterator();
// iterate over all the subscribers, and if they are in advance of this queue entry then move them backwards
- while (subscriberIter.advance())
+ while (subscriberIter.advance() && entry.isAvailable())
{
Subscription sub = subscriberIter.getNode().getSubscription();
@@ -702,12 +756,21 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
private void decrementQueueSize(final QueueEntry entry)
{
- getAtomicQueueSize().addAndGet(-entry.getMessage().getSize());
+ final ServerMessage message = entry.getMessage();
+ long size = message.getSize();
+ getAtomicQueueSize().addAndGet(-size);
+ _dequeueSize.addAndGet(size);
+ if(message.isPersistent() && isDurable())
+ {
+ _persistentMessageDequeueSize.addAndGet(size);
+ _persistentMessageDequeueCount.incrementAndGet();
+ }
}
void decrementQueueCount()
{
getAtomicQueueCount().decrementAndGet();
+ _dequeueCount.incrementAndGet();
}
public boolean resend(final QueueEntry entry, final Subscription subscription) throws AMQException
@@ -834,7 +897,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
public int compareTo(final AMQQueue o)
{
- return _name.compareTo(o.getName());
+ return _name.compareTo(o.getNameShortString());
}
public AtomicInteger getAtomicQueueCount()
@@ -847,7 +910,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
return _atomicQueueSize;
}
- private boolean isExclusiveSubscriber()
+ public boolean hasExclusiveSubscriber()
{
return _exclusiveSubscriber != null;
}
@@ -1099,6 +1162,45 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
}
+ public void purge(final long request)
+ {
+ if(request == 0l)
+ {
+ clearQueue();
+ }
+ else if(request > 0l)
+ {
+
+ QueueEntryIterator queueListIterator = _entries.iterator();
+ long count = 0;
+
+ ServerTransaction txn = new LocalTransaction(getVirtualHost().getTransactionLog());
+
+ while (queueListIterator.advance())
+ {
+ QueueEntry node = queueListIterator.getNode();
+ if (!node.isDeleted() && node.acquire())
+ {
+ dequeueEntry(node, txn);
+ if(++count == request)
+ {
+ break;
+ }
+ }
+
+ }
+
+ txn.commit();
+
+
+ }
+ }
+
+ public long getCreateTime()
+ {
+ return _createTime;
+ }
+
// ------ Management functions
public void deleteMessageFromTop()
@@ -1172,11 +1274,21 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
_deleteTaskList.add(task);
}
+ public void removeQueueDeleteTask(final Task task)
+ {
+ _deleteTaskList.remove(task);
+ }
+
public int delete() throws AMQException
{
if (!_deleted.getAndSet(true))
{
+ for(Binding b : getBindings())
+ {
+ _virtualHost.getBindingFactory().removeBinding(b);
+ }
+
SubscriptionList.SubscriptionNodeIterator subscriptionIter = _subscriptionList.iterator();
while (subscriptionIter.advance())
@@ -1188,8 +1300,8 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
}
}
- _bindings.deregister();
_virtualHost.getQueueRegistry().unregisterQueue(_name);
+ getConfigStore().removeConfiguredObject(this);
List<QueueEntry> entries = getMessagesOnTheQueue(new QueueEntryFilter()
{
@@ -1214,7 +1326,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
for(final QueueEntry entry : entries)
{
adapter.setEntry(entry);
- final List<AMQQueue> rerouteQueues = _alternateExchange.route(adapter);
+ final List<? extends BaseQueue> rerouteQueues = _alternateExchange.route(adapter);
final ServerMessage message = entry.getMessage();
if(rerouteQueues != null & rerouteQueues.size() != 0)
{
@@ -1226,9 +1338,9 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
{
try
{
- for(AMQQueue queue : rerouteQueues)
+ for(BaseQueue queue : rerouteQueues)
{
- QueueEntry entry = queue.enqueue(message);
+ queue.enqueue(message);
}
}
catch (AMQException e)
@@ -1479,7 +1591,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
// next entry they are interested in yet. This would lead to holding on to references to expired messages, etc
// which would give us memory "leak".
- if (!isExclusiveSubscriber())
+ if (!hasExclusiveSubscriber())
{
advanceAllSubscriptions();
}
@@ -1820,7 +1932,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
public void setFlowResumeCapacity(long flowResumeCapacity)
{
_flowResumeCapacity = flowResumeCapacity;
-
+
checkCapacity();
}
@@ -1919,9 +2031,50 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
}
+ public ConfigStore getConfigStore()
+ {
+ return getVirtualHost().getConfigStore();
+ }
+
+ public long getMessageDequeueCount()
+ {
+ return _dequeueCount.get();
+ }
+
+ public long getTotalEnqueueSize()
+ {
+ return _enqueueSize.get();
+ }
+
+ public long getTotalDequeueSize()
+ {
+ return _dequeueSize.get();
+ }
+
+ public long getPersistentByteEnqueues()
+ {
+ return _persistentMessageEnqueueSize.get();
+ }
+
+ public long getPersistentByteDequeues()
+ {
+ return _persistentMessageDequeueSize.get();
+ }
+
+ public long getPersistentMsgEnqueues()
+ {
+ return _persistentMessageEnqueueCount.get();
+ }
+
+ public long getPersistentMsgDequeues()
+ {
+ return _persistentMessageDequeueCount.get();
+ }
+
+
@Override
public String toString()
{
- return String.valueOf(getName());
+ return String.valueOf(getNameShortString());
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java b/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java
index d27a5ed234..8721da0f78 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java
@@ -61,11 +61,9 @@ public class SimpleQueueEntryList implements QueueEntryList
{
_deletes.incrementAndGet();
QueueEntryImpl head = _head.nextNode();
- boolean deleted = head.isDeleted();
while(head._next != null && head.isDeleted())
{
- deleted = true;
final QueueEntryImpl newhead = head.nextNode();
if(newhead != null)
{
@@ -77,11 +75,6 @@ public class SimpleQueueEntryList implements QueueEntryList
head = _head.nextNode();
}
- if(!deleted)
- {
- deleted = true;
- }
-
if(_deletes.get() > 1000L)
{
_deletes.set(0L);
@@ -135,7 +128,7 @@ public class SimpleQueueEntryList implements QueueEntryList
public QueueEntry add(ServerMessage message)
{
- QueueEntryImpl node = new QueueEntryImpl(this, message);
+ QueueEntryImpl node = createQueueEntry(message);
for (;;)
{
QueueEntryImpl tail = _tail;
@@ -160,6 +153,11 @@ public class SimpleQueueEntryList implements QueueEntryList
}
}
+ protected QueueEntryImpl createQueueEntry(ServerMessage message)
+ {
+ return new QueueEntryImpl(this, message);
+ }
+
public QueueEntry next(QueueEntry node)
{
return ((QueueEntryImpl)node).getNext();
diff --git a/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
index 5cb379f10d..2c4c0a0570 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
@@ -20,24 +20,33 @@
*/
package org.apache.qpid.server.registry;
-import java.net.InetSocketAddress;
-import java.util.HashMap;
-import java.util.Map;
-
import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
+
+import org.apache.qpid.qmf.QMFService;
+import org.apache.qpid.server.configuration.BrokerConfig;
+import org.apache.qpid.server.configuration.ConfigStore;
import org.apache.qpid.server.configuration.ServerConfiguration;
+import org.apache.qpid.server.configuration.SystemConfig;
+import org.apache.qpid.server.configuration.SystemConfigImpl;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
+import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.messages.BrokerMessages;
import org.apache.qpid.server.management.ManagedObjectRegistry;
import org.apache.qpid.server.plugins.PluginManager;
import org.apache.qpid.server.security.access.ACLManager;
import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.transport.QpidAcceptor;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.virtualhost.VirtualHostImpl;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-import org.apache.qpid.server.logging.RootMessageLogger;
-import org.apache.qpid.server.logging.messages.BrokerMessages;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.transport.QpidAcceptor;
+
+import java.net.InetSocketAddress;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
/**
* An abstract application registry that provides access to configuration information and handles the
@@ -75,6 +84,14 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
protected RootMessageLogger _rootMessageLogger;
+ protected UUID _brokerId = UUID.randomUUID();
+
+ protected QMFService _qmfService;
+
+ private BrokerConfig _broker;
+
+ private ConfigStore _configStore;
+
static
{
Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownService()));
@@ -100,6 +117,16 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
_logger.info("Initialising Application Registry:" + instanceID);
_instanceMap.put(instanceID, instance);
+ final ConfigStore store = ConfigStore.newInstance();
+ store.setRoot(new SystemConfigImpl(store));
+ instance.setConfigStore(store);
+
+ BrokerConfig broker = new BrokerConfigAdapter(instance, instanceID);
+
+ SystemConfig system = (SystemConfig) store.getRoot();
+ system.addBroker(broker);
+ instance.setBroker(broker);
+
try
{
instance.initialise(instanceID);
@@ -107,7 +134,14 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
catch (Exception e)
{
_instanceMap.remove(instanceID);
- throw e;
+ try
+ {
+ system.removeBroker(broker);
+ }
+ finally
+ {
+ throw e;
+ }
}
}
else
@@ -116,6 +150,16 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
}
}
+ public ConfigStore getConfigStore()
+ {
+ return _configStore;
+ }
+
+ public void setConfigStore(final ConfigStore configStore)
+ {
+ _configStore = configStore;
+ }
+
public static boolean isConfigured()
{
return isConfigured(DEFAULT_INSTANCE);
@@ -151,6 +195,7 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
_logger.info("Shuting down ApplicationRegistry(" + instanceID + "):" + instance);
}
instance.close();
+ instance.getBroker().getSystem().removeBroker(instance.getBroker());
}
}
catch (Exception e)
@@ -316,5 +361,32 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
{
return _rootMessageLogger;
}
-
+
+ public UUID getBrokerId()
+ {
+ return _brokerId;
+ }
+
+ public QMFService getQMFService()
+ {
+ return _qmfService;
+ }
+
+ public BrokerConfig getBroker()
+ {
+ return _broker;
+ }
+
+ public void setBroker(final BrokerConfig broker)
+ {
+ _broker = broker;
+ }
+
+ public VirtualHost createVirtualHost(final VirtualHostConfiguration vhostConfig) throws Exception
+ {
+ VirtualHostImpl virtualHost = new VirtualHostImpl(this, vhostConfig);
+ _virtualHostRegistry.registerVirtualHost(virtualHost);
+ getBroker().addVirtualHost(virtualHost);
+ return virtualHost;
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java
new file mode 100644
index 0000000000..c3d1945550
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java
@@ -0,0 +1,163 @@
+/*
+ *
+ * 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.registry;
+
+import org.apache.qpid.server.configuration.*;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.common.QpidProperties;
+
+import java.util.UUID;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class BrokerConfigAdapter implements BrokerConfig
+{
+ private final IApplicationRegistry _instance;
+ private final int _instanceId;
+ private SystemConfig _system;
+
+ private final Map<UUID, VirtualHostConfig> _vhosts = new ConcurrentHashMap<UUID, VirtualHostConfig>();
+ private final long _createTime = System.currentTimeMillis();
+ private UUID _id;
+ private String _federationTag;
+
+ public BrokerConfigAdapter(final IApplicationRegistry instance, final int instanceID)
+ {
+ _instance = instance;
+ _instanceId = instanceID;
+ _id = instance.getConfigStore().createId();
+ _federationTag = UUID.randomUUID().toString();
+ }
+
+ public void setSystem(final SystemConfig system)
+ {
+ _system = system;
+ }
+
+ public SystemConfig getSystem()
+ {
+ return _system;
+ }
+
+ public Integer getPort()
+ {
+ List ports = _instance.getConfiguration().getPorts();
+ if(ports.size() > 0)
+ {
+ return Integer.valueOf(ports.get(0).toString());
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ public Integer getWorkerThreads()
+ {
+ return _instance.getConfiguration().getProcessors();
+ }
+
+ public Integer getMaxConnections()
+ {
+ return 0;
+ }
+
+ public Integer getConnectionBacklogLimit()
+ {
+ return 0;
+ }
+
+ public Long getStagingThreshold()
+ {
+ return 0L;
+ }
+
+ public Integer getManagementPublishInterval()
+ {
+ return 10;
+ }
+
+ public String getVersion()
+ {
+ return QpidProperties.getReleaseVersion() + " [Build: " + QpidProperties.getBuildVersion() + "]";
+ }
+
+ public String getDataDirectory()
+ {
+ return _instance.getConfiguration().getQpidWork();
+ }
+
+ public void addVirtualHost(final VirtualHostConfig virtualHost)
+ {
+ virtualHost.setBroker(this);
+ _vhosts.put(virtualHost.getId(), virtualHost);
+ getConfigStore().addConfiguredObject(virtualHost);
+
+ }
+
+ private ConfigStore getConfigStore()
+ {
+ return _instance.getConfigStore();
+ }
+
+ public long getCreateTime()
+ {
+ return _createTime;
+ }
+
+ public void createBrokerConnection(final String transport,
+ final String host,
+ final int port,
+ final boolean durable,
+ final String authMechanism,
+ final String username,
+ final String password)
+ {
+ VirtualHost vhost = _instance.getVirtualHostRegistry().getDefaultVirtualHost();
+ vhost.createBrokerConnection(transport, host, port, "", durable, authMechanism, username, password);
+ }
+
+ public UUID getId()
+ {
+ return _id;
+ }
+
+ public BrokerConfigType getConfigType()
+ {
+ return BrokerConfigType.getInstance();
+ }
+
+ public ConfiguredObject getParent()
+ {
+ return _system;
+ }
+
+ public boolean isDurable()
+ {
+ return false;
+ }
+
+ public String getFederationTag()
+ {
+ return _federationTag;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java
index f325b53dfb..e1cc1bf1dd 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java
@@ -21,13 +21,15 @@
package org.apache.qpid.server.registry;
import org.apache.commons.configuration.ConfigurationException;
+
import org.apache.qpid.AMQException;
import org.apache.qpid.common.QpidProperties;
+import org.apache.qpid.qmf.QMFService;
import org.apache.qpid.server.configuration.ServerConfiguration;
import org.apache.qpid.server.logging.RootMessageLoggerImpl;
-import org.apache.qpid.server.logging.messages.BrokerMessages;
-import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.actors.BrokerActor;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.messages.BrokerMessages;
import org.apache.qpid.server.logging.rawloggers.Log4jMessageLogger;
import org.apache.qpid.server.management.JMXManagedObjectRegistry;
import org.apache.qpid.server.management.NoopManagedObjectRegistry;
@@ -36,7 +38,6 @@ import org.apache.qpid.server.security.access.ACLManager;
import org.apache.qpid.server.security.auth.database.ConfigurationFilePrincipalDatabaseManager;
import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-import org.apache.qpid.server.virtualhost.VirtualHostImpl;
import java.io.File;
@@ -51,6 +52,9 @@ public class ConfigurationFileApplicationRegistry extends ApplicationRegistry
public void initialise(int instanceID) throws Exception
{
+ _qmfService = new QMFService(getConfigStore(), this);
+
+
_rootMessageLogger = new RootMessageLoggerImpl(_configuration,
new Log4jMessageLogger());
@@ -75,6 +79,7 @@ public class ConfigurationFileApplicationRegistry extends ApplicationRegistry
_databaseManager.initialiseManagement(_configuration);
+
_managedObjectRegistry.start();
initialiseVirtualHosts();
@@ -91,6 +96,7 @@ public class ConfigurationFileApplicationRegistry extends ApplicationRegistry
try
{
super.close();
+ _qmfService.close();
}
finally
{
@@ -102,7 +108,7 @@ public class ConfigurationFileApplicationRegistry extends ApplicationRegistry
{
for (String name : _configuration.getVirtualHosts())
{
- _virtualHostRegistry.registerVirtualHost(new VirtualHostImpl(_configuration.getVirtualHostConfig(name)));
+ createVirtualHost(_configuration.getVirtualHostConfig(name));
}
getVirtualHostRegistry().setDefaultVirtualHostName(_configuration.getDefaultVirtualHost());
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java
index 92accb3499..f0226c7982 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java
@@ -7,9 +7,9 @@
* 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
@@ -20,22 +20,25 @@
*/
package org.apache.qpid.server.registry;
-import java.util.Collection;
-import java.net.InetSocketAddress;
-
-import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
+
+import org.apache.qpid.qmf.QMFService;
+import org.apache.qpid.server.configuration.BrokerConfig;
+import org.apache.qpid.server.configuration.ConfigStore;
import org.apache.qpid.server.configuration.ServerConfiguration;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
+import org.apache.qpid.server.logging.RootMessageLogger;
import org.apache.qpid.server.management.ManagedObjectRegistry;
import org.apache.qpid.server.plugins.PluginManager;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
-import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager;
import org.apache.qpid.server.security.access.ACLManager;
-import org.apache.qpid.server.security.access.ACLPlugin;
-import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
import org.apache.qpid.server.transport.QpidAcceptor;
-import org.apache.mina.common.IoAcceptor;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
+
+import java.net.InetSocketAddress;
+import java.util.UUID;
public interface IApplicationRegistry
{
@@ -81,4 +84,17 @@ public interface IApplicationRegistry
*/
void addAcceptor(InetSocketAddress bindAddress, QpidAcceptor acceptor);
+ public UUID getBrokerId();
+
+ QMFService getQMFService();
+
+ void setBroker(BrokerConfig broker);
+
+ BrokerConfig getBroker();
+
+ VirtualHost createVirtualHost(VirtualHostConfiguration vhostConfig) throws Exception;
+
+ ConfigStore getConfigStore();
+
+ void setConfigStore(ConfigStore store);
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalPermissions.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalPermissions.java
index a299907e42..e7fc8effaf 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalPermissions.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalPermissions.java
@@ -42,7 +42,7 @@ public class PrincipalPermissions
private static final Object CREATE_QUEUES_KEY = new Object();
private static final Object CREATE_EXCHANGES_KEY = new Object();
-
+
private static final Object CREATE_QUEUE_TEMPORARY_KEY = new Object();
private static final Object CREATE_QUEUE_QUEUES_KEY = new Object();
private static final Object CREATE_QUEUE_EXCHANGES_KEY = new Object();
@@ -64,9 +64,9 @@ public class PrincipalPermissions
}
/**
- *
+ *
* @param permission the type of permission to check
- *
+ *
* @param parameters vararg depending on what permission was passed in
* ACCESS: none
* BIND: none
@@ -113,7 +113,7 @@ public class PrincipalPermissions
{
_fullVHostAccess = true;
}
-
+
private void grantPublish(Permission permission, Object... parameters) {
Map publishRights = (Map) _permissions.get(permission);
@@ -344,9 +344,9 @@ public class PrincipalPermissions
}
/**
- *
+ *
* @param permission the type of permission to check
- *
+ *
* @param parameters vararg depending on what permission was passed in
* ACCESS: none
* BIND: QueueBindBody bindmethod, Exchange exchange, AMQQueue queue, AMQShortString routingKey
@@ -363,7 +363,7 @@ public class PrincipalPermissions
switch (permission)
{
- case ACCESS://No Parameters
+ case ACCESS://No Parameters
return AuthzResult.ALLOWED; // The existence of this user-specific PP infers some level of access is authorised
case BIND: // Parameters : QueueBindMethod , Exchange , AMQQueue, AMQShortString routingKey
return authoriseBind(parameters);
@@ -444,7 +444,7 @@ public class PrincipalPermissions
{
if ( new AMQShortString(queue.getPrincipalHolder().getPrincipal().getName()).equals(_user))
{
- return (queues.size() == 0 || queues.contains(queue.getName())) ? AuthzResult.ALLOWED : AuthzResult.DENIED;
+ return (queues.size() == 0 || queues.contains(queue.getNameShortString())) ? AuthzResult.ALLOWED : AuthzResult.DENIED;
}
else
{
@@ -453,7 +453,7 @@ public class PrincipalPermissions
}
// If we are
- return (queues.size() == 0 || queues.contains(queue.getName())) ? AuthzResult.ALLOWED : AuthzResult.DENIED;
+ return (queues.size() == 0 || queues.contains(queue.getNameShortString())) ? AuthzResult.ALLOWED : AuthzResult.DENIED;
}
}
@@ -486,7 +486,7 @@ public class PrincipalPermissions
// Otherwise exchange must be listed in the white list
// If the map doesn't have the exchange then it isn't allowed
- if (!exchanges.containsKey(((Exchange) parameters[0]).getName()))
+ if (!exchanges.containsKey(((Exchange) parameters[0]).getNameShortString()))
{
return AuthzResult.DENIED;
}
@@ -494,7 +494,7 @@ public class PrincipalPermissions
{
// Get valid routing keys
- HashSet routingKeys = (HashSet) exchanges.get(((Exchange)parameters[0]).getName());
+ HashSet routingKeys = (HashSet) exchanges.get(((Exchange)parameters[0]).getNameShortString());
// Having no routingKeys in the map then all are allowed.
if (routingKeys == null)
@@ -544,7 +544,7 @@ public class PrincipalPermissions
// check the valid exchanges
if (rights == null || rights.containsKey(exchangeName))
{
- return AuthzResult.ALLOWED;
+ return AuthzResult.ALLOWED;
}
else
{
@@ -587,13 +587,13 @@ public class PrincipalPermissions
// If there is a white list then check
if (create_queues_queues == null || create_queues_queues.containsKey(queueName))
{
- return AuthzResult.ALLOWED;
+ return AuthzResult.ALLOWED;
}
else
{
return AuthzResult.DENIED;
}
-
+
}
}
@@ -604,7 +604,7 @@ public class PrincipalPermissions
//user has been granted full access to the vhost
return AuthzResult.ALLOWED;
}
-
+
Exchange exchange = (Exchange) parameters[1];
AMQQueue bind_queueName = (AMQQueue) parameters[2];
@@ -631,7 +631,7 @@ public class PrincipalPermissions
}
// Check to see if we have a white list of routingkeys to check
- Map rkeys = (Map) exchangeDetails.get(exchange.getName());
+ Map rkeys = (Map) exchangeDetails.get(exchange.getNameShortString());
// if keys is null then any rkey is allowed on this exchange
if (rkeys == null)
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousInitialiser.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousInitialiser.java
new file mode 100644
index 0000000000..4a66b74783
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousInitialiser.java
@@ -0,0 +1,39 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.security.auth.sasl.anonymous;
+
+import javax.security.sasl.SaslServerFactory;
+
+import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser;
+import org.apache.qpid.server.security.auth.sasl.amqplain.AmqPlainSaslServerFactory;
+
+public class AnonymousInitialiser extends UsernamePasswordInitialiser
+{
+ public String getMechanismName()
+ {
+ return "ANONYMOUS";
+ }
+
+ public Class<? extends SaslServerFactory> getServerFactoryClassForJCARegistration()
+ {
+ return AnonymousSaslServerFactory.class;
+ }
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServer.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServer.java
new file mode 100644
index 0000000000..b4cce15d88
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServer.java
@@ -0,0 +1,88 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.security.auth.sasl.anonymous;
+
+import java.io.IOException;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.sasl.AuthorizeCallback;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+
+import org.apache.mina.common.ByteBuffer;
+import org.apache.qpid.framing.AMQFrameDecodingException;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.framing.FieldTableFactory;
+
+public class AnonymousSaslServer implements SaslServer
+{
+ public static final String MECHANISM = "ANONYMOUS";
+
+ private boolean _complete = false;
+
+ public AnonymousSaslServer()
+ {
+ }
+
+ public String getMechanismName()
+ {
+ return MECHANISM;
+ }
+
+ public byte[] evaluateResponse(byte[] response) throws SaslException
+ {
+ _complete = true;
+ return null;
+ }
+
+ public boolean isComplete()
+ {
+ return _complete;
+ }
+
+ public String getAuthorizationID()
+ {
+ return null;
+ }
+
+ public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException
+ {
+ throw new SaslException("Unsupported operation");
+ }
+
+ public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException
+ {
+ throw new SaslException("Unsupported operation");
+ }
+
+ public Object getNegotiatedProperty(String propName)
+ {
+ return null;
+ }
+
+ public void dispose() throws SaslException
+ {
+ }
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java
new file mode 100644
index 0000000000..6032255870
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java
@@ -0,0 +1,63 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.security.auth.sasl.anonymous;
+
+import org.apache.qpid.server.security.auth.sasl.amqplain.AmqPlainSaslServer;
+
+import java.util.Map;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+import javax.security.sasl.SaslServerFactory;
+
+public class AnonymousSaslServerFactory implements SaslServerFactory
+{
+ public SaslServer createSaslServer(String mechanism, String protocol, String serverName, Map props,
+ CallbackHandler cbh) throws SaslException
+ {
+ if (AnonymousSaslServer.MECHANISM.equals(mechanism))
+ {
+ return new AnonymousSaslServer();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public String[] getMechanismNames(Map props)
+ {
+ if (props.containsKey(Sasl.POLICY_NOPLAINTEXT) ||
+ props.containsKey(Sasl.POLICY_NODICTIONARY) ||
+ props.containsKey(Sasl.POLICY_NOACTIVE) ||
+ props.containsKey(Sasl.POLICY_NOANONYMOUS))
+ {
+ // returned array must be non null according to interface documentation
+ return new String[0];
+ }
+ else
+ {
+ return new String[]{AnonymousSaslServer.MECHANISM};
+ }
+ }
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/DerbyMessageStore.java b/java/broker/src/main/java/org/apache/qpid/server/store/DerbyMessageStore.java
index 5ca75aa9ae..31211d6b9e 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/store/DerbyMessageStore.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/store/DerbyMessageStore.java
@@ -20,22 +20,24 @@
*/
package org.apache.qpid.server.store;
+import org.apache.commons.configuration.Configuration;
import org.apache.log4j.Logger;
+
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.logging.LogSubject;
import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.messages.MessageStoreMessages;
import org.apache.qpid.server.logging.messages.ConfigStoreMessages;
+import org.apache.qpid.server.logging.messages.MessageStoreMessages;
import org.apache.qpid.server.logging.messages.TransactionLogMessages;
-import org.apache.qpid.server.logging.LogSubject;
import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.commons.configuration.Configuration;
-
import java.io.ByteArrayInputStream;
import java.io.File;
+import java.lang.ref.WeakReference;
+import java.nio.ByteBuffer;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.Driver;
@@ -49,8 +51,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
-import java.lang.ref.WeakReference;
-import java.nio.ByteBuffer;
public class DerbyMessageStore implements MessageStore
@@ -590,7 +590,10 @@ public class DerbyMessageStore implements MessageStore
conn = newConnection();
PreparedStatement stmt = conn.prepareStatement(FIND_EXCHANGE);
- stmt.setString(1, exchange.getName().toString());
+ stmt.setString(1, exchange.getNameShortString().toString());
+ stmt.execute();
+ stmt.close();
+ conn.commit();
ResultSet rs = stmt.executeQuery();
@@ -617,7 +620,7 @@ public class DerbyMessageStore implements MessageStore
}
catch (SQLException e)
{
- throw new AMQException("Error writing Exchange with name " + exchange.getName() + " to database: " + e, e);
+ throw new AMQException("Error writing Exchange with name " + exchange.getNameShortString() + " to database: " + e, e);
}
}
@@ -631,11 +634,11 @@ public class DerbyMessageStore implements MessageStore
{
conn = newConnection();
PreparedStatement stmt = conn.prepareStatement(DELETE_FROM_EXCHANGE);
- stmt.setString(1, exchange.getName().toString());
+ stmt.setString(1, exchange.getNameShortString().toString());
int results = stmt.executeUpdate();
if(results == 0)
{
- throw new AMQException("Exchange " + exchange.getName() + " not found");
+ throw new AMQException("Exchange " + exchange.getNameShortString() + " not found");
}
else
{
@@ -645,7 +648,7 @@ public class DerbyMessageStore implements MessageStore
}
catch (SQLException e)
{
- throw new AMQException("Error writing deleting with name " + exchange.getName() + " from database: " + e, e);
+ throw new AMQException("Error writing deleting with name " + exchange.getNameShortString() + " from database: " + e, e);
}
finally
{
@@ -677,8 +680,8 @@ public class DerbyMessageStore implements MessageStore
conn = newConnection();
PreparedStatement stmt = conn.prepareStatement(FIND_BINDING);
- stmt.setString(1, exchange.getName().toString() );
- stmt.setString(2, queue.getName().toString());
+ stmt.setString(1, exchange.getNameShortString().toString() );
+ stmt.setString(2, queue.getNameShortString().toString());
stmt.setString(3, routingKey == null ? null : routingKey.toString());
ResultSet rs = stmt.executeQuery();
@@ -687,8 +690,8 @@ public class DerbyMessageStore implements MessageStore
if (!rs.next())
{
stmt = conn.prepareStatement(INSERT_INTO_BINDINGS);
- stmt.setString(1, exchange.getName().toString() );
- stmt.setString(2, queue.getName().toString());
+ stmt.setString(1, exchange.getNameShortString().toString() );
+ stmt.setString(2, queue.getNameShortString().toString());
stmt.setString(3, routingKey == null ? null : routingKey.toString());
if(args != null)
{
@@ -713,8 +716,8 @@ public class DerbyMessageStore implements MessageStore
}
catch (SQLException e)
{
- throw new AMQException("Error writing binding for AMQQueue with name " + queue.getName() + " to exchange "
- + exchange.getName() + " to database: " + e, e);
+ throw new AMQException("Error writing binding for AMQQueue with name " + queue.getNameShortString() + " to exchange "
+ + exchange.getNameShortString() + " to database: " + e, e);
}
finally
{
@@ -748,23 +751,23 @@ public class DerbyMessageStore implements MessageStore
conn = newConnection();
// exchange_name varchar(255) not null, queue_name varchar(255) not null, binding_key varchar(255), arguments blob
PreparedStatement stmt = conn.prepareStatement(DELETE_FROM_BINDINGS);
- stmt.setString(1, exchange.getName().toString() );
- stmt.setString(2, queue.getName().toString());
+ stmt.setString(1, exchange.getNameShortString().toString() );
+ stmt.setString(2, queue.getNameShortString().toString());
stmt.setString(3, routingKey == null ? null : routingKey.toString());
if(stmt.executeUpdate() != 1)
{
- throw new AMQException("Queue binding for queue with name " + queue.getName() + " to exchange "
- + exchange.getName() + " not found");
+ throw new AMQException("Queue binding for queue with name " + queue.getNameShortString() + " to exchange "
+ + exchange.getNameShortString() + " not found");
}
conn.commit();
stmt.close();
}
catch (SQLException e)
{
- throw new AMQException("Error removing binding for AMQQueue with name " + queue.getName() + " to exchange "
- + exchange.getName() + " in database: " + e, e);
+ throw new AMQException("Error removing binding for AMQQueue with name " + queue.getNameShortString() + " to exchange "
+ + exchange.getNameShortString() + " in database: " + e, e);
}
finally
{
@@ -801,7 +804,7 @@ public class DerbyMessageStore implements MessageStore
Connection conn = newConnection();
PreparedStatement stmt = conn.prepareStatement(FIND_QUEUE);
- stmt.setString(1, queue.getName().toString());
+ stmt.setString(1, queue.getNameShortString().toString());
ResultSet rs = stmt.executeQuery();
@@ -816,7 +819,7 @@ public class DerbyMessageStore implements MessageStore
? null
: queue.getPrincipalHolder().getPrincipal().getName();
- stmt.setString(1, queue.getName().toString());
+ stmt.setString(1, queue.getNameShortString().toString());
stmt.setString(2, owner);
stmt.execute();
@@ -830,7 +833,7 @@ public class DerbyMessageStore implements MessageStore
}
catch (SQLException e)
{
- throw new AMQException("Error writing AMQQueue with name " + queue.getName() + " to database: " + e, e);
+ throw new AMQException("Error writing AMQQueue with name " + queue.getNameShortString() + " to database: " + e, e);
}
}
}
@@ -843,7 +846,7 @@ public class DerbyMessageStore implements MessageStore
public void removeQueue(final AMQQueue queue) throws AMQException
{
- AMQShortString name = queue.getName();
+ AMQShortString name = queue.getNameShortString();
_logger.debug("public void removeQueue(AMQShortString name = " + name + "): called");
Connection conn = null;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java b/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java
index cfbacd28c8..a50e8e99b4 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java
@@ -31,6 +31,11 @@ import org.apache.commons.configuration.Configuration;
public interface DurableConfigurationStore
{
+ public static interface Source
+ {
+ DurableConfigurationStore getDurableConfigurationStore();
+ }
+
/**
* Called after instantiation in order to configure the message store. A particular implementation can define
* whatever parameters it wants.
diff --git a/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java b/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java
index 684d3c2e74..b0ea0ef506 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java
@@ -20,41 +20,49 @@
*/
package org.apache.qpid.server.subscription;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.Map;
-
import org.apache.log4j.Logger;
+
import org.apache.qpid.AMQException;
import org.apache.qpid.common.AMQPFilterTypes;
import org.apache.qpid.common.ClientProperties;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.AMQChannel;
-import org.apache.qpid.server.message.AMQMessage;
-import org.apache.qpid.server.output.ProtocolOutputConverter;
+import org.apache.qpid.server.configuration.ConfigStore;
+import org.apache.qpid.server.configuration.ConfiguredObject;
+import org.apache.qpid.server.configuration.SessionConfig;
+import org.apache.qpid.server.configuration.SubscriptionConfig;
+import org.apache.qpid.server.configuration.SubscriptionConfigType;
+import org.apache.qpid.server.filter.FilterManager;
+import org.apache.qpid.server.filter.FilterManagerFactory;
+import org.apache.qpid.server.flow.FlowCreditManager;
+import org.apache.qpid.server.logging.LogActor;
+import org.apache.qpid.server.logging.LogSubject;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.actors.SubscriptionActor;
import org.apache.qpid.server.logging.messages.SubscriptionMessages;
import org.apache.qpid.server.logging.subjects.SubscriptionLogSubject;
-import org.apache.qpid.server.logging.LogSubject;
-import org.apache.qpid.server.logging.LogActor;
-import org.apache.qpid.server.queue.QueueEntry;
-import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.flow.FlowCreditManager;
-import org.apache.qpid.server.filter.FilterManager;
-import org.apache.qpid.server.filter.FilterManagerFactory;
+import org.apache.qpid.server.message.AMQMessage;
+import org.apache.qpid.server.output.ProtocolOutputConverter;
import org.apache.qpid.server.protocol.AMQProtocolSession;
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.queue.QueueEntry;
+
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
/**
* Encapsulation of a supscription to a queue. <p/> Ties together the protocol session of a subscriber, the consumer tag
* that was given out by the broker and the channel id. <p/>
*/
-public abstract class SubscriptionImpl implements Subscription, FlowCreditManager.FlowCreditManagerListener
+public abstract class SubscriptionImpl implements Subscription, FlowCreditManager.FlowCreditManagerListener,
+ SubscriptionConfig
{
private StateListener _stateListener = new StateListener()
@@ -85,6 +93,7 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
private final long _subscriptionID = idGenerator.getAndIncrement();
private LogSubject _logSubject;
private LogActor _logActor;
+ private UUID _id;
static final class BrowserSubscription extends SubscriptionImpl
@@ -152,6 +161,12 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
return false;
}
+ @Override
+ public boolean isExplicitAcknowledge()
+ {
+ return false;
+ }
+
/**
* This method can be called by each of the publisher threads. As a result all changes to the channel object must be
* thread safe.
@@ -318,9 +333,12 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
_autoClose = false;
}
-
}
+ public ConfigStore getConfigStore()
+ {
+ return getQueue().getConfigStore();
+ }
public synchronized void setQueue(AMQQueue queue, boolean exclusive)
@@ -331,6 +349,9 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
}
_queue = queue;
+ _id = getConfigStore().createId();
+ getConfigStore().addConfiguredObject(this);
+
_logSubject = new SubscriptionLogSubject(this);
_logActor = new SubscriptionActor(CurrentActor.get().getRootMessageLogger(), this);
@@ -414,7 +435,7 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
public boolean hasInterest(QueueEntry entry)
{
-
+
//check that the message hasn't been rejected
@@ -505,7 +526,7 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
{
_stateChangeLock.unlock();
}
-
+ getConfigStore().removeConfiguredObject(this);
//Log Subscription closed
CurrentActor.get().message(_logSubject, SubscriptionMessages.SUB_CLOSE());
@@ -689,4 +710,60 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
}
abstract boolean isBrowser();
+
+ public String getCreditMode()
+ {
+ return "WINDOW";
+ }
+
+ public SessionConfig getSessionConfig()
+ {
+ return getChannel();
+ }
+
+ public boolean isBrowsing()
+ {
+ return isBrowser();
+ }
+
+ public boolean isExplicitAcknowledge()
+ {
+ return true;
+ }
+
+ public UUID getId()
+ {
+ return _id;
+ }
+
+ public boolean isDurable()
+ {
+ return false;
+ }
+
+ public SubscriptionConfigType getConfigType()
+ {
+ return SubscriptionConfigType.getInstance();
+ }
+
+ public boolean isExclusive()
+ {
+ return getQueue().hasExclusiveSubscriber();
+ }
+
+ public ConfiguredObject getParent()
+ {
+ return getSessionConfig();
+ }
+
+ public String getName()
+ {
+ return String.valueOf(_consumerTag);
+ }
+
+ public Map<String, Object> getArguments()
+ {
+ return null;
+ }
+
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java b/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java
index 5b3668ab64..54c294c76d 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java
@@ -36,11 +36,12 @@ import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.message.MessageTransferMessage;
import org.apache.qpid.server.message.AMQMessage;
import org.apache.qpid.server.transport.ServerSession;
+import org.apache.qpid.server.configuration.*;
+import org.apache.qpid.server.txn.ServerTransaction;
+import org.apache.qpid.server.txn.AutoCommitTransaction;
import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.ContentHeaderProperties;
import org.apache.qpid.framing.BasicContentHeaderProperties;
import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.framing.AMQTypedValue;
import org.apache.qpid.AMQException;
import org.apache.qpid.transport.*;
@@ -50,12 +51,10 @@ import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.HashMap;
+import java.util.*;
import java.nio.ByteBuffer;
-public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCreditManagerListener
+public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCreditManagerListener, SubscriptionConfig
{
private static final AtomicLong idGenerator = new AtomicLong(0);
@@ -98,6 +97,9 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
private LogSubject _logSubject;
private LogActor _logActor;
private Map<String, Object> _properties = new ConcurrentHashMap<String, Object>();
+ private UUID _id;
+ private String _traceExclude;
+ private String _trace;
public Subscription_0_10(ServerSession session, String destination, MessageAcceptMode acceptMode,
@@ -116,7 +118,6 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
_creditManager.addStateListener(this);
_state.set(_creditManager.hasCredit() ? State.ACTIVE : State.SUSPENDED);
-
}
public void setNoLocal(boolean noLocal)
@@ -146,6 +147,11 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
throw new IllegalStateException("Attempt to set queue for subscription " + this + " to " + queue + "when already set to " + getQueue());
}
_queue = queue;
+ Map<String, Object> arguments = queue.getArguments() == null ? Collections.EMPTY_MAP : queue.getArguments();
+ _traceExclude = (String) arguments.get("qpid.trace.exclude");
+ _trace = (String) arguments.get("qpid.trace.id");
+ _id = getConfigStore().createId();
+ getConfigStore().addConfiguredObject(this);
_logSubject = new SubscriptionLogSubject(this);
_logActor = new SubscriptionActor(CurrentActor.get().getRootMessageLogger(), this);
@@ -235,6 +241,7 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
}
}
_creditManager.removeListener(this);
+ getConfigStore().removeConfiguredObject(this);
}
finally
{
@@ -245,6 +252,11 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
}
+ public ConfigStore getConfigStore()
+ {
+ return getQueue().getConfigStore();
+ }
+
public void creditStateChanged(boolean hasCredit)
{
@@ -290,6 +302,9 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
MessageTransfer xfr;
+ DeliveryProperties deliveryProps;
+ MessageProperties messageProps = null;
+
if(serverMsg instanceof MessageTransferMessage)
{
@@ -316,11 +331,15 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
}
else
{
+ if(header instanceof MessageProperties)
+ {
+ messageProps = (MessageProperties) header;
+ }
newHeaders.add(header);
}
}
- DeliveryProperties deliveryProps = new DeliveryProperties();
+ deliveryProps = new DeliveryProperties();
if(origDeliveryProps != null)
{
if(origDeliveryProps.hasDeliveryMode())
@@ -343,21 +362,33 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
{
deliveryProps.setRoutingKey(origDeliveryProps.getRoutingKey());
}
+ if(origDeliveryProps.hasTimestamp())
+ {
+ deliveryProps.setTimestamp(origDeliveryProps.getTimestamp());
+ }
+
}
deliveryProps.setRedelivered(entry.isRedelivered());
newHeaders.add(deliveryProps);
+
+ if(_trace != null && messageProps == null)
+ {
+ messageProps = new MessageProperties();
+ newHeaders.add(messageProps);
+ }
+
Header header = new Header(newHeaders);
xfr = new MessageTransfer(_destination,_acceptMode,_acquireMode,header,msg.getBody());
}
- else
+ else if(serverMsg instanceof AMQMessage)
{
AMQMessage message_0_8 = (AMQMessage) serverMsg;
- DeliveryProperties deliveryProps = new DeliveryProperties();
- MessageProperties messageProps = new MessageProperties();
+ deliveryProps = new DeliveryProperties();
+ messageProps = new MessageProperties();
int size = (int) message_0_8.getSize();
ByteBuffer body = ByteBuffer.allocate(size);
@@ -399,9 +430,52 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
messageProps.setUserId(properties.getUserId().getBytes());
}
+ FieldTable fieldTable = properties.getHeaders();
+
+ final Map<String, Object> appHeaders = FieldTable.convertToMap(fieldTable);
+
+
+ messageProps.setApplicationHeaders(appHeaders);
+
+ Header header = new Header(headers);
+ xfr = new MessageTransfer(_destination,_acceptMode,_acquireMode,header, body);
+ }
+ else
+ {
+
+ deliveryProps = new DeliveryProperties();
+ messageProps = new MessageProperties();
+
+ int size = (int) serverMsg.getSize();
+ ByteBuffer body = ByteBuffer.allocate(size);
+ serverMsg.getContent(body, 0);
+ body.flip();
+
+ Struct[] headers = new Struct[] { deliveryProps, messageProps };
+
+
+ deliveryProps.setExpiration(serverMsg.getExpiration());
+ deliveryProps.setImmediate(serverMsg.isImmediate());
+ deliveryProps.setPriority(MessageDeliveryPriority.get(serverMsg.getMessageHeader().getPriority()));
+ deliveryProps.setRedelivered(entry.isRedelivered());
+ deliveryProps.setRoutingKey(serverMsg.getRoutingKey());
+ deliveryProps.setTimestamp(serverMsg.getMessageHeader().getTimestamp());
+
+ messageProps.setContentEncoding(serverMsg.getMessageHeader().getEncoding());
+ messageProps.setContentLength(size);
+ messageProps.setContentType(serverMsg.getMessageHeader().getMimeType());
+ if(serverMsg.getMessageHeader().getCorrelationId() != null)
+ {
+ messageProps.setCorrelationId(serverMsg.getMessageHeader().getCorrelationId().getBytes());
+ }
+
+
+ // TODO - ReplyTo
+
+
final Map<String, Object> appHeaders = new HashMap<String, Object>();
- properties.getHeaders().processOverElements(
+ /*properties.getHeaders().processOverElements(
new FieldTable.FieldTableElementProcessor()
{
@@ -424,39 +498,98 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
messageProps.setApplicationHeaders(appHeaders);
-
+*/
Header header = new Header(headers);
xfr = new MessageTransfer(_destination,_acceptMode,_acquireMode,header, body);
}
- if(_acceptMode == MessageAcceptMode.NONE)
+ boolean excludeDueToFederation = false;
+
+ if(_trace != null)
{
- xfr.setCompletionListener(new MessageAcceptCompletionListener(this, _session, entry, _flowMode == MessageFlowMode.WINDOW));
+ if(!messageProps.hasApplicationHeaders())
+ {
+ messageProps.setApplicationHeaders(new HashMap<String,Object>());
+ }
+ Map<String,Object> appHeaders = messageProps.getApplicationHeaders();
+ String trace = (String) appHeaders.get("x-qpid.trace");
+ if(trace == null)
+ {
+ trace = _trace;
+ }
+ else
+ {
+ if(_traceExclude != null)
+ {
+ excludeDueToFederation = Arrays.asList(trace.split(",")).contains(_traceExclude);
+ }
+ trace+=","+_trace;
+ }
+ appHeaders.put("x-qpid.trace",trace);
}
- else if(_flowMode == MessageFlowMode.WINDOW)
+
+ if(!excludeDueToFederation)
{
- xfr.setCompletionListener(new Method.CompletionListener()
- {
- public void onComplete(Method method)
+ if(_acceptMode == MessageAcceptMode.NONE)
+ {
+ xfr.setCompletionListener(new MessageAcceptCompletionListener(this, _session, entry, _flowMode == MessageFlowMode.WINDOW));
+ }
+ else if(_flowMode == MessageFlowMode.WINDOW)
+ {
+ xfr.setCompletionListener(new Method.CompletionListener()
{
- restoreCredit(entry);
- }
- });
- }
+ public void onComplete(Method method)
+ {
+ restoreCredit(entry);
+ }
+ });
+ }
- _postIdSettingAction._xfr = xfr;
- if(_acceptMode == MessageAcceptMode.EXPLICIT)
- {
- _postIdSettingAction._action = new ExplicitAcceptDispositionChangeListener(entry, this);
+ _postIdSettingAction._xfr = xfr;
+ if(_acceptMode == MessageAcceptMode.EXPLICIT)
+ {
+ _postIdSettingAction._action = new ExplicitAcceptDispositionChangeListener(entry, this);
+ }
+ else
+ {
+ _postIdSettingAction._action = new ImplicitAcceptDispositionChangeListener(entry, this);
+ }
+
+ _session.sendMessage(xfr, _postIdSettingAction);
+
+ if(_acceptMode == MessageAcceptMode.NONE && _acquireMode == MessageAcquireMode.PRE_ACQUIRED)
+ {
+ forceDequeue(entry, false);
+ }
}
else
{
- _postIdSettingAction._action = new ImplicitAcceptDispositionChangeListener(entry, this);
+ forceDequeue(entry, _flowMode == MessageFlowMode.WINDOW);
+
}
+ }
+
+ private void forceDequeue(final QueueEntry entry, final boolean restoreCredit)
+ {
+ ServerTransaction txn = new AutoCommitTransaction(getQueue().getVirtualHost().getTransactionLog());
+ txn.dequeue(entry.getQueue(),entry.getMessage(),
+ new ServerTransaction.Action()
+ {
+ public void postCommit()
+ {
+ if(restoreCredit)
+ {
+ restoreCredit(entry);
+ }
+ entry.discard();
+ }
- _session.sendMessage(xfr, _postIdSettingAction);
+ public void onRollback()
+ {
+ }
+ });
}
void reject(QueueEntry entry)
@@ -660,4 +793,59 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
}
+ public SessionConfig getSessionConfig()
+ {
+ return getSession();
+ }
+
+ public boolean isBrowsing()
+ {
+ return _acquireMode == MessageAcquireMode.NOT_ACQUIRED;
+ }
+
+ public boolean isExclusive()
+ {
+ return getQueue().hasExclusiveSubscriber();
+ }
+
+ public ConfiguredObject getParent()
+ {
+ return getSessionConfig();
+ }
+
+ public boolean isDurable()
+ {
+ return false;
+ }
+
+ public SubscriptionConfigType getConfigType()
+ {
+ return SubscriptionConfigType.getInstance();
+ }
+
+ public boolean isExplicitAcknowledge()
+ {
+ return _acceptMode == MessageAcceptMode.EXPLICIT;
+ }
+
+ public String getCreditMode()
+ {
+ return _flowMode.toString();
+ }
+
+ public UUID getId()
+ {
+ return _id;
+ }
+
+ public String getName()
+ {
+ return _destination;
+ }
+
+ public Map<String, Object> getArguments()
+ {
+ //TODO
+ return Collections.EMPTY_MAP;
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java
index 2a8b99ddac..1aff1eec86 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java
@@ -20,12 +20,20 @@
*/
package org.apache.qpid.server.transport;
+import org.apache.qpid.server.configuration.ConnectionConfig;
+import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.transport.Connection;
import org.apache.qpid.transport.Method;
-import org.apache.qpid.server.virtualhost.VirtualHost;
public class ServerConnection extends Connection
{
+ private ConnectionConfig _config;
+ private Runnable _onOpenTask;
+
+ public ServerConnection()
+ {
+ }
+
@Override
protected void invoke(Method method)
{
@@ -36,6 +44,10 @@ public class ServerConnection extends Connection
protected void setState(State state)
{
super.setState(state);
+ if(state == State.OPEN && _onOpenTask != null)
+ {
+ _onOpenTask.run();
+ }
}
@Override
@@ -61,4 +73,19 @@ public class ServerConnection extends Connection
{
_virtualHost = virtualHost;
}
+
+ public void setConnectionConfig(final ConnectionConfig config)
+ {
+ _config = config;
+ }
+
+ public ConnectionConfig getConfig()
+ {
+ return _config;
+ }
+
+ public void onOpen(final Runnable task)
+ {
+ _onOpenTask = task;
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java
index cfc5bb3a72..4cfcafa533 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java
@@ -40,7 +40,7 @@ public class ServerConnectionDelegate extends ServerDelegate
public ServerConnectionDelegate(IApplicationRegistry appRegistry,
String localFQDN)
{
- this(Collections.EMPTY_MAP, Collections.singletonList((Object)"en_US"), appRegistry, localFQDN);
+ this(new HashMap<String,Object>(Collections.singletonMap("qpid.federation_tag",appRegistry.getBroker().getFederationTag())), Collections.singletonList((Object)"en_US"), appRegistry, localFQDN);
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
index 77dfbc0376..3e48ac2619 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
@@ -20,32 +20,55 @@
*/
package org.apache.qpid.server.transport;
-import org.apache.qpid.transport.*;
+import com.sun.security.auth.UserPrincipal;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.server.configuration.ConfigStore;
+import org.apache.qpid.server.configuration.ConfiguredObject;
+import org.apache.qpid.server.configuration.ConnectionConfig;
+import org.apache.qpid.server.configuration.SessionConfig;
+import org.apache.qpid.server.configuration.SessionConfigType;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.queue.QueueEntry;
+import org.apache.qpid.server.security.PrincipalHolder;
+import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.subscription.Subscription_0_10;
-import org.apache.qpid.server.txn.ServerTransaction;
import org.apache.qpid.server.txn.AutoCommitTransaction;
import org.apache.qpid.server.txn.LocalTransaction;
-import org.apache.qpid.server.security.PrincipalHolder;
-import org.apache.qpid.server.store.MessageStore;
-import org.apache.qpid.AMQException;
+import org.apache.qpid.server.txn.ServerTransaction;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.transport.Binary;
+import org.apache.qpid.transport.Connection;
+import org.apache.qpid.transport.MessageTransfer;
+import org.apache.qpid.transport.Method;
+import org.apache.qpid.transport.Range;
+import org.apache.qpid.transport.RangeSet;
+import org.apache.qpid.transport.Session;
+import org.apache.qpid.transport.SessionDelegate;
+import static org.apache.qpid.util.Serial.gt;
-import java.util.*;
+import java.lang.ref.WeakReference;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.ConcurrentHashMap;
-import java.security.Principal;
-import java.lang.ref.WeakReference;
-import static org.apache.qpid.util.Serial.*;
-import com.sun.security.auth.UserPrincipal;
-
-public class ServerSession extends Session implements PrincipalHolder
+public class ServerSession extends Session implements PrincipalHolder, SessionConfig
{
private static final String NULL_DESTINTATION = UUID.randomUUID().toString();
+ private final UUID _id;
+ private ConnectionConfig _connectionConfig;
+
public static interface MessageDispositionChangeListener
{
public void onAccept();
@@ -78,37 +101,41 @@ public class ServerSession extends Session implements PrincipalHolder
private final WeakReference<Session> _reference;
-
- ServerSession(Connection connection, Binary name, long expiry)
+ ServerSession(Connection connection, SessionDelegate delegate, Binary name, long expiry)
{
- super(connection, name, expiry);
-
- _transaction = new AutoCommitTransaction(this.getMessageStore());
- _principal = new UserPrincipal(connection.getAuthorizationID());
- _reference = new WeakReference(this);
+ this(connection, delegate, name, expiry, ((ServerConnection)connection).getConfig());
}
- ServerSession(Connection connection, SessionDelegate delegate, Binary name, long expiry)
+ public ServerSession(Connection connection, SessionDelegate delegate, Binary name, long expiry, ConnectionConfig connConfig)
{
super(connection, delegate, name, expiry);
+ _connectionConfig = connConfig;
_transaction = new AutoCommitTransaction(this.getMessageStore());
_principal = new UserPrincipal(connection.getAuthorizationID());
_reference = new WeakReference(this);
+ _id = getConfigStore().createId();
+ getConfigStore().addConfiguredObject(this);
+ }
+
+ private ConfigStore getConfigStore()
+ {
+ return getConnectionConfig().getConfigStore();
}
+
@Override
protected boolean isFull(int id)
{
return isCommandsFull(id);
}
- public void enqueue(final ServerMessage message, final ArrayList<AMQQueue> queues)
+ public void enqueue(final ServerMessage message, final ArrayList<? extends BaseQueue> queues)
{
_transaction.enqueue(queues,message, new ServerTransaction.Action()
{
- AMQQueue[] _queues = queues.toArray(new AMQQueue[queues.size()]);
+ BaseQueue[] _queues = queues.toArray(new BaseQueue[queues.size()]);
public void postCommit()
{
@@ -243,7 +270,7 @@ public class ServerSession extends Session implements PrincipalHolder
Iterator<Integer> unacceptedMessages = _messageDispositionListenerMap.keySet().iterator();
Iterator<Range> rangeIter = ranges.iterator();
- if(rangeIter.hasNext())
+ if(rangeIter.hasNext())
{
Range range = rangeIter.next();
@@ -290,6 +317,8 @@ public class ServerSession extends Session implements PrincipalHolder
}
_messageDispositionListenerMap.clear();
+ getConfigStore().removeConfiguredObject(this);
+
for (Task task : _taskList)
{
task.doTask(this);
@@ -391,8 +420,61 @@ public class ServerSession extends Session implements PrincipalHolder
public MessageStore getMessageStore()
{
- return ((ServerConnection)getConnection()).getVirtualHost().getMessageStore();
+ return getVirtualHost().getMessageStore();
}
+ public VirtualHost getVirtualHost()
+ {
+ return (VirtualHost) _connectionConfig.getVirtualHost();
+ }
+
+ public UUID getId()
+ {
+ return _id;
+ }
+
+ public SessionConfigType getConfigType()
+ {
+ return SessionConfigType.getInstance();
+ }
+ public ConfiguredObject getParent()
+ {
+ return getVirtualHost();
+ }
+
+ public boolean isDurable()
+ {
+ return false;
+ }
+
+ public boolean isAttached()
+ {
+ return true;
+ }
+
+ public long getDetachedLifespan()
+ {
+ return 0;
+ }
+
+ public Long getExpiryTime()
+ {
+ return null;
+ }
+
+ public Long getMaxClientRate()
+ {
+ return null;
+ }
+
+ public ConnectionConfig getConnectionConfig()
+ {
+ return _connectionConfig;
+ }
+
+ public String getSessionName()
+ {
+ return getName().toString();
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java
index 4ade799c59..3b0f990377 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java
@@ -28,6 +28,7 @@ import org.apache.qpid.server.exchange.*;
import org.apache.qpid.server.queue.QueueRegistry;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.AMQQueueFactory;
+import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.message.MessageTransferMessage;
import org.apache.qpid.server.message.MessageMetaData_0_10;
import org.apache.qpid.server.subscription.Subscription_0_10;
@@ -42,6 +43,7 @@ import org.apache.qpid.framing.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
+import java.nio.ByteBuffer;
public class ServerSessionDelegate extends SessionDelegate
{
@@ -218,11 +220,15 @@ public class ServerSessionDelegate extends SessionDelegate
MessageMetaData_0_10 messageMetaData = new MessageMetaData_0_10(xfr);
final MessageStore store = getVirtualHost(ssn).getMessageStore();
StoredMessage<MessageMetaData_0_10> storeMessage = store.addMessage(messageMetaData);
- storeMessage.addContent(0,xfr.getBody());
+ ByteBuffer body = xfr.getBody();
+ if(body != null)
+ {
+ storeMessage.addContent(0, body);
+ }
storeMessage.flushToStore();
MessageTransferMessage message = new MessageTransferMessage(storeMessage, ((ServerSession)ssn).getReference());
- ArrayList<AMQQueue> queues = exchange.route(message);
+ ArrayList<? extends BaseQueue> queues = exchange.route(message);
@@ -355,7 +361,7 @@ public class ServerSessionDelegate extends SessionDelegate
else
{
// TODO - check exchange has same properties
- if(!exchange.getType().toString().equals(method.getType()))
+ if(!exchange.getTypeShortString().toString().equals(method.getType()))
{
exception(session, method, ExecutionErrorCode.NOT_ALLOWED, "Cannot redeclare with a different exchange type");
}
@@ -419,7 +425,7 @@ public class ServerSessionDelegate extends SessionDelegate
}
else
{
- if(!exchange.getType().toString().equals(method.getType()))
+ if(!exchange.getTypeShortString().toString().equals(method.getType()))
{
exception(session, method, ExecutionErrorCode.NOT_ALLOWED, "Cannot redeclare with a different exchange type");
}
@@ -525,7 +531,7 @@ public class ServerSessionDelegate extends SessionDelegate
if(exchange != null)
{
result.setDurable(exchange.isDurable());
- result.setType(exchange.getType().toString());
+ result.setType(exchange.getTypeShortString().toString());
result.setNotFound(false);
}
else
@@ -582,30 +588,23 @@ public class ServerSessionDelegate extends SessionDelegate
+ "' to Queue: '" + method.getQueue()
+ "' not allowed");
}
- else if(exchange.getType().equals(HeadersExchange.TYPE.getName()) && (!method.hasArguments() || method.getArguments() == null || !method.getArguments().containsKey("x-match")))
+ else if(exchange.getTypeShortString().equals(HeadersExchange.TYPE.getName()) && (!method.hasArguments() || method.getArguments() == null || !method.getArguments().containsKey("x-match")))
{
exception(session, method, ExecutionErrorCode.INTERNAL_ERROR, "Bindings to an exchange of type " + HeadersExchange.TYPE.getName() + " require an x-match header");
}
else
{
- try
- {
- AMQShortString routingKey = new AMQShortString(method.getBindingKey());
- FieldTable fieldTable = FieldTable.convertToFieldTable(method.getArguments());
+ AMQShortString routingKey = new AMQShortString(method.getBindingKey());
+ FieldTable fieldTable = FieldTable.convertToFieldTable(method.getArguments());
- if (!exchange.isBound(routingKey, fieldTable, queue))
- {
- queue.bind(exchange, routingKey, fieldTable);
+ if (!exchange.isBound(routingKey, fieldTable, queue))
+ {
+ virtualHost.getBindingFactory().addBinding(method.getBindingKey(), queue, exchange, method.getArguments());
- }
- else
- {
- // todo
- }
}
- catch (AMQException e)
+ else
{
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ // todo
}
}
@@ -649,14 +648,7 @@ public class ServerSessionDelegate extends SessionDelegate
}
else
{
- try
- {
- queue.unBind(exchange, new AMQShortString(method.getBindingKey()), null);
- }
- catch (AMQException e)
- {
- throw new RuntimeException(e);
- }
+ virtualHost.getBindingFactory().removeBinding(method.getBindingKey(), queue, exchange, null);
}
}
@@ -827,7 +819,7 @@ public class ServerSessionDelegate extends SessionDelegate
{
queue.setDeleteOnNoConsumers(true);
}
-
+
final String alternateExchangeName = method.getAlternateExchange();
if(alternateExchangeName != null && alternateExchangeName.length() != 0)
{
@@ -870,11 +862,12 @@ public class ServerSessionDelegate extends SessionDelegate
if (autoRegister)
{
+
ExchangeRegistry exchangeRegistry = getExchangeRegistry(session);
Exchange defaultExchange = exchangeRegistry.getDefaultExchange();
- queue.bind(defaultExchange, new AMQShortString(queueName), null);
+ virtualHost.getBindingFactory().addBinding(queueName, queue, defaultExchange, null);
}
@@ -1114,7 +1107,7 @@ public class ServerSessionDelegate extends SessionDelegate
if(queue != null)
{
- result.setQueue(queue.getName().toString());
+ result.setQueue(queue.getNameShortString().toString());
result.setDurable(queue.isDurable());
result.setExclusive(queue.isExclusive());
result.setAutoDelete(queue.isAutoDelete());
diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java b/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java
index 7b29106ba6..f674741057 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java
@@ -22,6 +22,7 @@ package org.apache.qpid.server.txn;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.QueueEntry;
+import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.message.EnqueableMessage;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.store.TransactionLog;
@@ -46,7 +47,7 @@ public class AutoCommitTransaction implements ServerTransaction
postCommitAction.postCommit();
}
- public void dequeue(AMQQueue queue, EnqueableMessage message, Action postCommitAction)
+ public void dequeue(BaseQueue queue, EnqueableMessage message, Action postCommitAction)
{
try
@@ -105,7 +106,7 @@ public class AutoCommitTransaction implements ServerTransaction
}
- public void enqueue(AMQQueue queue, EnqueableMessage message, Action postCommitAction)
+ public void enqueue(BaseQueue queue, EnqueableMessage message, Action postCommitAction)
{
try
{
@@ -128,7 +129,7 @@ public class AutoCommitTransaction implements ServerTransaction
}
- public void enqueue(List<AMQQueue> queues, EnqueableMessage message, Action postCommitAction)
+ public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postCommitAction)
{
try
{
@@ -137,7 +138,7 @@ public class AutoCommitTransaction implements ServerTransaction
{
TransactionLog.Transaction txn = _transactionLog.newTransaction();
Long id = message.getMessageNumber();
- for(AMQQueue q : queues)
+ for(BaseQueue q : queues)
{
if(q.isDurable())
{
diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java b/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java
index 9997fbe767..1124b0e812 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java
@@ -2,6 +2,7 @@ package org.apache.qpid.server.txn;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.QueueEntry;
+import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.message.EnqueableMessage;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.store.TransactionLog;
@@ -28,7 +29,7 @@ public class LocalTransaction implements ServerTransaction
_postCommitActions.add(postCommitAction);
}
- public void dequeue(AMQQueue queue, EnqueableMessage message, Action postCommitAction)
+ public void dequeue(BaseQueue queue, EnqueableMessage message, Action postCommitAction)
{
if(message.isPersistent() && queue.isDurable())
{
@@ -113,7 +114,7 @@ public class LocalTransaction implements ServerTransaction
}
}
- public void enqueue(AMQQueue queue, EnqueableMessage message, Action postCommitAction)
+ public void enqueue(BaseQueue queue, EnqueableMessage message, Action postCommitAction)
{
if(message.isPersistent() && queue.isDurable())
{
@@ -132,7 +133,7 @@ public class LocalTransaction implements ServerTransaction
}
- public void enqueue(List<AMQQueue> queues, EnqueableMessage message, Action postCommitAction)
+ public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postCommitAction)
{
@@ -140,7 +141,7 @@ public class LocalTransaction implements ServerTransaction
{
if(_transaction == null)
{
- for(AMQQueue queue : queues)
+ for(BaseQueue queue : queues)
{
if(queue.isDurable())
{
@@ -155,7 +156,7 @@ public class LocalTransaction implements ServerTransaction
try
{
- for(AMQQueue queue : queues)
+ for(BaseQueue queue : queues)
{
if(queue.isDurable())
{
diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java b/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java
index 88bdc363c4..f3ef6569f3 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java
@@ -20,15 +20,12 @@
*/
package org.apache.qpid.server.txn;
-import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.queue.QueueEntry;
-import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.message.EnqueableMessage;
-import org.apache.qpid.server.AMQChannel;
+import org.apache.qpid.server.queue.BaseQueue;
+import org.apache.qpid.server.queue.QueueEntry;
-import java.util.List;
-import java.util.SortedSet;
import java.util.Collection;
+import java.util.List;
public interface ServerTransaction
{
@@ -45,13 +42,13 @@ public interface ServerTransaction
public void onRollback();
}
- void dequeue(AMQQueue queue, EnqueableMessage message, Action postCommitAction);
+ void dequeue(BaseQueue queue, EnqueableMessage message, Action postCommitAction);
void dequeue(Collection<QueueEntry> ackedMessages, Action postCommitAction);
- void enqueue(AMQQueue queue, EnqueableMessage message, Action postCommitAction);
+ void enqueue(BaseQueue queue, EnqueableMessage message, Action postCommitAction);
- void enqueue(List<AMQQueue> queues, EnqueableMessage message, Action postCommitAction);
+ void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postCommitAction);
void commit();
diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
index e4a382d275..c140e4a144 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
@@ -21,7 +21,10 @@
package org.apache.qpid.server.virtualhost;
import org.apache.qpid.server.connection.IConnectionRegistry;
+import org.apache.qpid.server.federation.BrokerLink;
import org.apache.qpid.server.configuration.VirtualHostConfiguration;
+import org.apache.qpid.server.configuration.VirtualHostConfig;
+import org.apache.qpid.server.configuration.ConfigStore;
import org.apache.qpid.server.queue.QueueRegistry;
import org.apache.qpid.server.exchange.ExchangeRegistry;
import org.apache.qpid.server.exchange.ExchangeFactory;
@@ -31,8 +34,13 @@ import org.apache.qpid.server.store.DurableConfigurationStore;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
import org.apache.qpid.server.security.access.ACLManager;
import org.apache.qpid.server.management.ManagedObject;
+import org.apache.qpid.server.registry.IApplicationRegistry;
+import org.apache.qpid.server.binding.BindingFactory;
-public interface VirtualHost
+import java.util.UUID;
+import java.util.TimerTask;
+
+public interface VirtualHost extends DurableConfigurationStore.Source, VirtualHostConfig
{
IConnectionRegistry getConnectionRegistry();
@@ -59,4 +67,24 @@ public interface VirtualHost
void close() throws Exception;
ManagedObject getManagedObject();
+
+ UUID getBrokerId();
+
+ void scheduleTask(long period, TimerTask task);
+
+
+ IApplicationRegistry getApplicationRegistry();
+
+ BindingFactory getBindingFactory();
+
+ void createBrokerConnection(String transport,
+ String host,
+ int port,
+ String vhost,
+ boolean durable,
+ String authMechanism, String username, String password);
+
+ ConfigStore getConfigStore();
+
+ void removeBrokerConnection(BrokerLink brokerLink);
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java
index c543531210..221ec0b639 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java
@@ -34,10 +34,10 @@ import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.logging.subjects.MessageStoreLogSubject;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.messages.TransactionLogMessages;
-import org.apache.qpid.server.logging.messages.MessageStoreMessages;
import org.apache.qpid.server.message.AMQMessage;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.message.MessageTransferMessage;
+import org.apache.qpid.server.binding.BindingFactory;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.AMQException;
@@ -215,7 +215,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
if (queue == null)
{
_logger.error("Unkown queue: " + queueName + " cannot be bound to exchange: "
- + exchange.getName());
+ + exchange.getNameShortString());
}
else
{
@@ -227,10 +227,18 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
argumentsFT = new FieldTable(org.apache.mina.common.ByteBuffer.wrap(buf),buf.limit());
}
- _logger.info("Restoring binding: (Exchange: " + exchange.getName() + ", Queue: " + queueName
- + ", Routing Key: " + bindingKey + ", Arguments: " + argumentsFT + ")");
+ BindingFactory bf = _virtualHost.getBindingFactory();
- queue.bind(exchange, bindingKey == null ? null : new AMQShortString(bindingKey), argumentsFT);
+ Map<String, Object> argumentMap = FieldTable.convertToMap(argumentsFT);
+
+ if(bf.getBinding(bindingKey, queue, exchange, argumentMap) == null)
+ {
+
+ _logger.info("Restoring binding: (Exchange: " + exchange.getNameShortString() + ", Queue: " + queueName
+ + ", Routing Key: " + bindingKey + ", Arguments: " + argumentsFT + ")");
+
+ bf.restoreBinding(bindingKey, queue, exchange, argumentMap);
+ }
}
}
@@ -271,7 +279,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
if (_logger.isDebugEnabled())
{
- _logger.debug("On recovery, delivering " + message.getMessageNumber() + " to " + queue.getName());
+ _logger.debug("On recovery, delivering " + message.getMessageNumber() + " to " + queue.getNameShortString());
}
Integer count = _queueRecoveries.get(queueName);
@@ -286,7 +294,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
}
else
{
- _logger.warn("Message id " + messageId + " referenced in log as enqueue in queue " + queue.getName() + " is unknwon, entry will be discarded");
+ _logger.warn("Message id " + messageId + " referenced in log as enqueue in queue " + queue.getNameShortString() + " is unknwon, entry will be discarded");
TransactionLog.Transaction txn = _transactionLog.newTransaction();
txn.dequeueMessage(queue, messageId);
txn.commitTranAsync();
@@ -333,7 +341,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
CurrentActor.get().message(_logSubject, TransactionLogMessages.TXN_1005(entry.getValue(), entry.getKey()));
CurrentActor.get().message(_logSubject, TransactionLogMessages.TXN_1006(entry.getKey(), true));
- }
+ }
CurrentActor.get().message(_logSubject, TransactionLogMessages.TXN_1006(null, false));
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java
index 2f1528eb43..b208872a5a 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java
@@ -20,19 +20,21 @@
*/
package org.apache.qpid.server.virtualhost;
-import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
+
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.AMQBrokerManagerMBean;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.messages.VirtualHostMessages;
-import org.apache.qpid.server.logging.subjects.MessageStoreLogSubject;
-import org.apache.qpid.server.logging.LogSubject;
+import org.apache.qpid.server.binding.BindingFactory;
+import org.apache.qpid.server.configuration.BrokerConfig;
+import org.apache.qpid.server.configuration.ConfigStore;
+import org.apache.qpid.server.configuration.ConfiguredObject;
import org.apache.qpid.server.configuration.ExchangeConfiguration;
import org.apache.qpid.server.configuration.QueueConfiguration;
+import org.apache.qpid.server.configuration.VirtualHostConfigType;
import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.connection.ConnectionRegistry;
import org.apache.qpid.server.connection.IConnectionRegistry;
@@ -41,6 +43,11 @@ import org.apache.qpid.server.exchange.DefaultExchangeRegistry;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.exchange.ExchangeFactory;
import org.apache.qpid.server.exchange.ExchangeRegistry;
+import org.apache.qpid.server.federation.BrokerLink;
+import org.apache.qpid.server.logging.LogSubject;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.messages.VirtualHostMessages;
+import org.apache.qpid.server.logging.subjects.MessageStoreLogSubject;
import org.apache.qpid.server.management.AMQManagedObject;
import org.apache.qpid.server.management.ManagedObject;
import org.apache.qpid.server.queue.AMQQueue;
@@ -48,14 +55,15 @@ import org.apache.qpid.server.queue.AMQQueueFactory;
import org.apache.qpid.server.queue.DefaultQueueRegistry;
import org.apache.qpid.server.queue.QueueRegistry;
import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.registry.IApplicationRegistry;
import org.apache.qpid.server.security.access.ACLManager;
import org.apache.qpid.server.security.access.Accessable;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
-import org.apache.qpid.server.store.MessageStore;
+import org.apache.qpid.server.store.ConfigurationRecoveryHandler;
import org.apache.qpid.server.store.DurableConfigurationStore;
+import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.store.TransactionLog;
-import org.apache.qpid.server.store.ConfigurationRecoveryHandler;
import javax.management.NotCompliantMBeanException;
import java.util.Collections;
@@ -63,6 +71,9 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
public class VirtualHostImpl implements Accessable, VirtualHost
{
@@ -88,9 +99,17 @@ public class VirtualHostImpl implements Accessable, VirtualHost
private ACLManager _accessManager;
- private final Timer _houseKeepingTimer;
+ private final Timer _timer;
+ private final IApplicationRegistry _appRegistry;
private VirtualHostConfiguration _configuration;
private DurableConfigurationStore _durableConfigurationStore;
+ private BindingFactory _bindingFactory;
+ private BrokerConfig _broker;
+ private UUID _id;
+
+
+ private final long _createTime = System.currentTimeMillis();
+ private final ConcurrentHashMap<BrokerLink,BrokerLink> _links = new ConcurrentHashMap<BrokerLink, BrokerLink>();
public void setAccessableName(String name)
{
@@ -113,6 +132,26 @@ public class VirtualHostImpl implements Accessable, VirtualHost
return _configuration;
}
+ public UUID getId()
+ {
+ return _id; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public VirtualHostConfigType getConfigType()
+ {
+ return VirtualHostConfigType.getInstance();
+ }
+
+ public ConfiguredObject getParent()
+ {
+ return getBroker();
+ }
+
+ public boolean isDurable()
+ {
+ return false;
+ }
+
/**
* Abstract MBean class. This has some of the methods implemented from management intrerface for exchanges. Any
* implementaion of an Exchange MBean should extend this class.
@@ -141,23 +180,28 @@ public class VirtualHostImpl implements Accessable, VirtualHost
} // End of MBean class
- /**
- * Normal Constructor
- *
- * @param hostConfig
- *
- * @throws Exception
- */
- public VirtualHostImpl(VirtualHostConfiguration hostConfig) throws Exception
+
+
+ public VirtualHostImpl(IApplicationRegistry appRegistry, VirtualHostConfiguration hostConfig) throws Exception
{
- this(hostConfig, null);
+ this(appRegistry, hostConfig, null);
}
+
public VirtualHostImpl(VirtualHostConfiguration hostConfig, MessageStore store) throws Exception
{
+ this(ApplicationRegistry.getInstance(),hostConfig,store);
+ }
+
+ private VirtualHostImpl(IApplicationRegistry appRegistry, VirtualHostConfiguration hostConfig, MessageStore store) throws Exception
+ {
+ _appRegistry = appRegistry;
+ _broker = appRegistry.getBroker();
_configuration = hostConfig;
_name = hostConfig.getName();
+ _id = appRegistry.getConfigStore().createId();
+
CurrentActor.get().message(VirtualHostMessages.VHT_CREATED(_name));
if (_name == null || _name.length() == 0)
@@ -169,7 +213,7 @@ public class VirtualHostImpl implements Accessable, VirtualHost
_connectionRegistry = new ConnectionRegistry(this);
- _houseKeepingTimer = new Timer("Queue-housekeeping-" + _name, true);
+ _timer = new Timer("TimerThread-" + _name + ":", true);
_queueRegistry = new DefaultQueueRegistry(this);
@@ -178,6 +222,7 @@ public class VirtualHostImpl implements Accessable, VirtualHost
_exchangeRegistry = new DefaultExchangeRegistry(this);
+
//Create a temporary RT to store the durable entries from the config file
// so we can replay them in to the real _RT after it has been loaded.
/// This should be removed after the _RT has been fully split from the the TL
@@ -189,6 +234,8 @@ public class VirtualHostImpl implements Accessable, VirtualHost
// This needs to be after the RT has been defined as it creates the default durable exchanges.
_exchangeRegistry.initialise();
+ _bindingFactory = new BindingFactory(this);
+
initialiseModel(hostConfig);
if (store != null)
@@ -205,9 +252,11 @@ public class VirtualHostImpl implements Accessable, VirtualHost
initialiseMessageStore(hostConfig);
}
+
+
//Now that the RT has been initialised loop through the persistent queues/exchanges created from the config
// file and write them in to the new routing Table.
- for (StartupRoutingTable.CreateQueueTuple cqt : configFileRT.queue)
+/* for (StartupRoutingTable.CreateQueueTuple cqt : configFileRT.queue)
{
getDurableConfigurationStore().createQueue(cqt.queue, cqt.arguments);
}
@@ -220,7 +269,7 @@ public class VirtualHostImpl implements Accessable, VirtualHost
for (StartupRoutingTable.CreateBindingTuple cbt : configFileRT.bindings)
{
getDurableConfigurationStore().bindQueue(cbt.exchange, cbt.routingKey, cbt.queue, cbt.arguments);
- }
+ }*/
_authenticationManager = new PrincipalDatabaseAuthenticationManager(_name, hostConfig);
@@ -250,7 +299,7 @@ public class VirtualHostImpl implements Accessable, VirtualHost
}
catch (Exception e)
{
- _logger.error("Exception in housekeeping for queue: " + q.getName().toString(), e);
+ _logger.error("Exception in housekeeping for queue: " + q.getNameShortString().toString(), e);
//Don't throw exceptions as this will stop the
// house keeping task from running.
}
@@ -258,9 +307,8 @@ public class VirtualHostImpl implements Accessable, VirtualHost
}
}
- _houseKeepingTimer.scheduleAtFixedRate(new RemoveExpiredMessagesTask(),
- period / 2,
- period);
+ final TimerTask expiredMessagesTask = new RemoveExpiredMessagesTask();
+ scheduleTask(period, expiredMessagesTask);
class ForceChannelClosuresTask extends TimerTask
{
@@ -272,6 +320,12 @@ public class VirtualHostImpl implements Accessable, VirtualHost
}
}
+ public void scheduleTask(final long period, final TimerTask task)
+ {
+ _timer.scheduleAtFixedRate(task, period / 2, period);
+ }
+
+
private void initialiseMessageStore(VirtualHostConfiguration hostConfig) throws Exception
{
String messageStoreClass = hostConfig.getMessageStoreClass();
@@ -377,7 +431,7 @@ public class VirtualHostImpl implements Accessable, VirtualHost
List routingKeys = queueConfiguration.getRoutingKeys();
if (routingKeys == null || routingKeys.isEmpty())
{
- routingKeys = Collections.singletonList(queue.getName());
+ routingKeys = Collections.singletonList(queue.getNameShortString());
}
for (Object routingKeyNameObj : routingKeys)
@@ -387,12 +441,12 @@ public class VirtualHostImpl implements Accessable, VirtualHost
{
_logger.info("Binding queue:" + queue + " with routing key '" + routingKey + "' to exchange:" + this);
}
- queue.bind(exchange, routingKey, null);
+ _bindingFactory.addBinding(routingKey.toString(), queue, exchange, null);
}
if (exchange != _exchangeRegistry.getDefaultExchange())
{
- queue.bind(_exchangeRegistry.getDefaultExchange(), queue.getName(), null);
+ _bindingFactory.addBinding(queue.getNameShortString().toString(), queue, exchange, null);
}
}
@@ -401,6 +455,26 @@ public class VirtualHostImpl implements Accessable, VirtualHost
return _name;
}
+ public BrokerConfig getBroker()
+ {
+ return _broker;
+ }
+
+ public String getFederationTag()
+ {
+ return _broker.getFederationTag();
+ }
+
+ public void setBroker(final BrokerConfig broker)
+ {
+ _broker = broker;
+ }
+
+ public long getCreateTime()
+ {
+ return _createTime;
+ }
+
public QueueRegistry getQueueRegistry()
{
return _queueRegistry;
@@ -457,9 +531,9 @@ public class VirtualHostImpl implements Accessable, VirtualHost
}
//Stop Housekeeping
- if (_houseKeepingTimer != null)
+ if (_timer != null)
{
- _houseKeepingTimer.cancel();
+ _timer.cancel();
}
//Close MessageStore
@@ -481,6 +555,59 @@ public class VirtualHostImpl implements Accessable, VirtualHost
return _virtualHostMBean;
}
+ public UUID getBrokerId()
+ {
+ return _appRegistry.getBrokerId();
+ }
+
+ public IApplicationRegistry getApplicationRegistry()
+ {
+ return _appRegistry;
+ }
+
+ public BindingFactory getBindingFactory()
+ {
+ return _bindingFactory;
+ }
+
+ public void createBrokerConnection(final String transport,
+ final String host,
+ final int port,
+ final String vhost,
+ final boolean durable,
+ final String authMechanism,
+ final String username,
+ final String password)
+ {
+ BrokerLink blink = new BrokerLink(this, transport, host, port, vhost, durable, authMechanism, username, password);
+ _links.putIfAbsent(blink,blink);
+ getConfigStore().addConfiguredObject(blink);
+ }
+
+ public void removeBrokerConnection(final String transport,
+ final String host,
+ final int port,
+ final String vhost)
+ {
+ removeBrokerConnection(new BrokerLink(this, transport, host, port, vhost, false, null,null,null));
+
+ }
+
+ public void removeBrokerConnection(BrokerLink blink)
+ {
+ blink = _links.get(blink);
+ if(blink != null)
+ {
+ blink.close();
+ getConfigStore().removeConfiguredObject(blink);
+ }
+ }
+
+ public ConfigStore getConfigStore()
+ {
+ return getApplicationRegistry().getConfigStore();
+ }
+
/**
* Temporary Startup RT class to record the creation of persistent queues / exchanges.
*
diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java
index b86e0d0baf..5975eeec3d 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java
@@ -21,6 +21,7 @@
package org.apache.qpid.server.virtualhost;
import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.configuration.ConfigStore;
import java.util.ArrayList;
import java.util.Collection;
@@ -52,7 +53,7 @@ public class VirtualHostRegistry
public VirtualHost getVirtualHost(String name)
{
- if(name == null || name.trim().length() == 0 )
+ if(name == null || name.trim().length() == 0 || "/".equals(name.trim()))
{
name = getDefaultVirtualHostName();
}
@@ -60,6 +61,11 @@ public class VirtualHostRegistry
return _registry.get(name);
}
+ public VirtualHost getDefaultVirtualHost()
+ {
+ return getVirtualHost(getDefaultVirtualHostName());
+ }
+
private String getDefaultVirtualHostName()
{
return _defaultVirtualHostName;
@@ -80,4 +86,9 @@ public class VirtualHostRegistry
{
return _applicationRegistry;
}
+
+ public ConfigStore getConfigStore()
+ {
+ return _applicationRegistry.getConfigStore();
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java
index faa7b85d58..f26611f0bc 100644
--- a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java
+++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java
@@ -219,7 +219,7 @@ public class MessageStoreTool
_console.println("");
- _console.println(BOILER_PLATE);
+ _console.println(BOILER_PLATE);
runCLI();
}
@@ -495,13 +495,13 @@ public class MessageStoreTool
if (_exchange != null)
{
status.append("[");
- status.append(_exchange.getName());
+ status.append(_exchange.getNameShortString());
status.append("]");
if (_queue != null)
{
status.append("->'");
- status.append(_queue.getName());
+ status.append(_queue.getNameShortString());
status.append("'");
if (_msgids != null)
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Copy.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Copy.java
index ef3599bdc8..348c95572d 100644
--- a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Copy.java
+++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Copy.java
@@ -52,7 +52,7 @@ public class Copy extends Move
protected void doCommand(AMQQueue fromQueue, long start, long end, AMQQueue toQueue)
{
ServerTransaction txn = new LocalTransaction(fromQueue.getVirtualHost().getTransactionLog());
- fromQueue.copyMessagesToAnotherQueue(start, end, toQueue.getName().toString(), txn);
+ fromQueue.copyMessagesToAnotherQueue(start, end, toQueue.getNameShortString().toString(), txn);
txn.commit();
}
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/List.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/List.java
index ab8e781df5..3c4a0c8fac 100644
--- a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/List.java
+++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/List.java
@@ -292,12 +292,12 @@ public class List extends AbstractCommand
{
if (exchange.isBound(queue))
{
- data.add(queue.getName().toString());
+ data.add(queue.getNameShortString().toString());
}
}
else
{
- data.add(queue.getName().toString());
+ data.add(queue.getNameShortString().toString());
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.java
index 6a5e2a6025..615f6ec1c2 100644
--- a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.java
+++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.java
@@ -196,7 +196,7 @@ public class Move extends AbstractCommand
protected void doCommand(AMQQueue fromQueue, long start, long id, AMQQueue toQueue)
{
ServerTransaction txn = new LocalTransaction(fromQueue.getVirtualHost().getTransactionLog());
- fromQueue.moveMessagesToAnotherQueue(start, id, toQueue.getName().toString(), txn);
+ fromQueue.moveMessagesToAnotherQueue(start, id, toQueue.getNameShortString().toString(), txn);
txn.commit();
}
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
index 89b825b270..e478f0f1f3 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
@@ -20,20 +20,11 @@
*/
package org.apache.qpid.server.configuration;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Collections;
-
import junit.framework.TestCase;
-
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
+
import org.apache.qpid.server.protocol.AMQProtocolEngine;
import org.apache.qpid.server.protocol.AMQProtocolSession;
import org.apache.qpid.server.registry.ApplicationRegistry;
@@ -42,6 +33,14 @@ import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
import org.apache.qpid.transport.TestNetworkDriver;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+
public class ServerConfigurationTest extends TestCase
{
@@ -51,7 +50,7 @@ public class ServerConfigurationTest extends TestCase
public void setUp()
{
//Highlight that this test will cause a new AR to be created
- ApplicationRegistry.getInstance();
+// ApplicationRegistry.getInstance();
_config = new XMLConfiguration();
}
@@ -60,7 +59,7 @@ public class ServerConfigurationTest extends TestCase
public void tearDown() throws Exception
{
//Correctly Close the AR we created
- ApplicationRegistry.remove();
+// ApplicationRegistry.remove();
}
public void testSetJMXManagementPort() throws ConfigurationException
@@ -765,21 +764,28 @@ public class ServerConfigurationTest extends TestCase
// Load config
ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg, 1);
+ try
+ {
+ ApplicationRegistry.initialise(reg, 1);
- // Test config
- VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry();
- VirtualHost virtualHost = virtualHostRegistry.getVirtualHost("test");
+ // Test config
+ VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry();
+ VirtualHost virtualHost = virtualHostRegistry.getVirtualHost("test");
- TestNetworkDriver testDriver = new TestNetworkDriver();
- testDriver.setRemoteAddress("127.0.0.1");
+ TestNetworkDriver testDriver = new TestNetworkDriver();
+ testDriver.setRemoteAddress("127.0.0.1");
- AMQProtocolEngine session = new AMQProtocolEngine(virtualHostRegistry, testDriver);
- assertFalse(reg.getAccessManager().authoriseConnect(session, virtualHost));
+ AMQProtocolEngine session = new AMQProtocolEngine(virtualHostRegistry, testDriver);
+ assertFalse(reg.getAccessManager().authoriseConnect(session, virtualHost));
- testDriver.setRemoteAddress("127.1.2.3");
- session = new AMQProtocolEngine(virtualHostRegistry, testDriver);
- assertTrue(reg.getAccessManager().authoriseConnect(session, virtualHost));
+ testDriver.setRemoteAddress("127.1.2.3");
+ session = new AMQProtocolEngine(virtualHostRegistry, testDriver);
+ assertTrue(reg.getAccessManager().authoriseConnect(session, virtualHost));
+ }
+ finally
+ {
+ ApplicationRegistry.remove(1);
+ }
}
public void testCombinedConfigurationFirewall() throws Exception
@@ -839,48 +845,61 @@ public class ServerConfigurationTest extends TestCase
// Load config
ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg, 1);
+ try
+ {
+ ApplicationRegistry.initialise(reg, 1);
- // Test config
- VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry();
- VirtualHost virtualHost = virtualHostRegistry.getVirtualHost("test");
+ // Test config
+ VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry();
+ VirtualHost virtualHost = virtualHostRegistry.getVirtualHost("test");
- TestNetworkDriver testDriver = new TestNetworkDriver();
- testDriver.setRemoteAddress("127.0.0.1");
+ TestNetworkDriver testDriver = new TestNetworkDriver();
+ testDriver.setRemoteAddress("127.0.0.1");
- AMQProtocolEngine session = new AMQProtocolEngine(virtualHostRegistry, testDriver);
- session.setNetworkDriver(testDriver);
- assertFalse(reg.getAccessManager().authoriseConnect(session, virtualHost));
+ AMQProtocolEngine session = new AMQProtocolEngine(virtualHostRegistry, testDriver);
+ session.setNetworkDriver(testDriver);
+ assertFalse(reg.getAccessManager().authoriseConnect(session, virtualHost));
+ }
+ finally
+ {
+ ApplicationRegistry.remove(1);
+ }
}
-
+
public void testConfigurationFirewallReload() throws Exception
{
// Write out config
File mainFile = File.createTempFile(getClass().getName(), null);
- mainFile.deleteOnExit();
+ mainFile.deleteOnExit();
writeConfigFile(mainFile, false);
// Load config
ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg, 1);
-
- // Test config
- TestNetworkDriver testDriver = new TestNetworkDriver();
- testDriver.setRemoteAddress("127.0.0.1");
- VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry();
- VirtualHost virtualHost = virtualHostRegistry.getVirtualHost("test");
- AMQProtocolSession session = new AMQProtocolEngine(virtualHostRegistry, testDriver);
-
- assertFalse(reg.getAccessManager().authoriseConnect(session, virtualHost));
-
- // Switch to deny the connection
- writeConfigFile(mainFile, true);
-
- reg.getConfiguration().reparseConfigFileSecuritySections();
-
- assertTrue(reg.getAccessManager().authoriseConnect(session, virtualHost));
+ try
+ {
+ ApplicationRegistry.initialise(reg, 1);
+
+ // Test config
+ TestNetworkDriver testDriver = new TestNetworkDriver();
+ testDriver.setRemoteAddress("127.0.0.1");
+ VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry();
+ VirtualHost virtualHost = virtualHostRegistry.getVirtualHost("test");
+ AMQProtocolSession session = new AMQProtocolEngine(virtualHostRegistry, testDriver);
+
+ assertFalse(reg.getAccessManager().authoriseConnect(session, virtualHost));
+ // Switch to deny the connection
+ writeConfigFile(mainFile, true);
+
+ reg.getConfiguration().reparseConfigFileSecuritySections();
+
+ assertTrue(reg.getAccessManager().authoriseConnect(session, virtualHost));
+ }
+ finally
+ {
+ ApplicationRegistry.remove(1);
+ }
}
private void writeConfigFile(File mainFile, boolean allow) throws IOException {
@@ -974,45 +993,52 @@ public class ServerConfigurationTest extends TestCase
// Load config
ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg, 1);
+ try
+ {
+ ApplicationRegistry.initialise(reg, 1);
- // Test config
- TestNetworkDriver testDriver = new TestNetworkDriver();
- testDriver.setRemoteAddress("127.0.0.1");
- VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry();
- VirtualHost virtualHost = virtualHostRegistry.getVirtualHost("test");
- AMQProtocolSession session = new AMQProtocolEngine(virtualHostRegistry, testDriver);
- assertFalse(reg.getAccessManager().authoriseConnect(session, virtualHost));
+ // Test config
+ TestNetworkDriver testDriver = new TestNetworkDriver();
+ testDriver.setRemoteAddress("127.0.0.1");
+ VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry();
+ VirtualHost virtualHost = virtualHostRegistry.getVirtualHost("test");
+ AMQProtocolSession session = new AMQProtocolEngine(virtualHostRegistry, testDriver);
+ assertFalse(reg.getAccessManager().authoriseConnect(session, virtualHost));
- RandomAccessFile fileBRandom = new RandomAccessFile(fileB, "rw");
- fileBRandom.setLength(0);
- fileBRandom.seek(0);
- fileBRandom.close();
+ RandomAccessFile fileBRandom = new RandomAccessFile(fileB, "rw");
+ fileBRandom.setLength(0);
+ fileBRandom.seek(0);
+ fileBRandom.close();
- out = new FileWriter(fileB);
- out.write("<firewall>\n");
- out.write("\t<rule access=\"allow\" network=\"127.0.0.1\"/>");
- out.write("</firewall>\n");
- out.close();
+ out = new FileWriter(fileB);
+ out.write("<firewall>\n");
+ out.write("\t<rule access=\"allow\" network=\"127.0.0.1\"/>");
+ out.write("</firewall>\n");
+ out.close();
- reg.getConfiguration().reparseConfigFileSecuritySections();
+ reg.getConfiguration().reparseConfigFileSecuritySections();
- assertTrue(reg.getAccessManager().authoriseConnect(session, virtualHost));
+ assertTrue(reg.getAccessManager().authoriseConnect(session, virtualHost));
- fileBRandom = new RandomAccessFile(fileB, "rw");
- fileBRandom.setLength(0);
- fileBRandom.seek(0);
- fileBRandom.close();
+ fileBRandom = new RandomAccessFile(fileB, "rw");
+ fileBRandom.setLength(0);
+ fileBRandom.seek(0);
+ fileBRandom.close();
- out = new FileWriter(fileB);
- out.write("<firewall>\n");
- out.write("\t<rule access=\"deny\" network=\"127.0.0.1\"/>");
- out.write("</firewall>\n");
- out.close();
+ out = new FileWriter(fileB);
+ out.write("<firewall>\n");
+ out.write("\t<rule access=\"deny\" network=\"127.0.0.1\"/>");
+ out.write("</firewall>\n");
+ out.close();
- reg.getConfiguration().reparseConfigFileSecuritySections();
+ reg.getConfiguration().reparseConfigFileSecuritySections();
- assertFalse(reg.getAccessManager().authoriseConnect(session, virtualHost));
+ assertFalse(reg.getAccessManager().authoriseConnect(session, virtualHost));
+ }
+ finally
+ {
+ ApplicationRegistry.remove(1);
+ }
}
public void testnewParserOutputVsOldParserOutput() throws ConfigurationException
@@ -1038,11 +1064,18 @@ public class ServerConfigurationTest extends TestCase
File configFile = new File(System.getProperty("QPID_HOME")+"/etc/config.xml");
assertTrue(configFile.exists());
- ApplicationRegistry.initialise(new ConfigurationFileApplicationRegistry(configFile), REGISTRY);
+ try
+ {
+ ApplicationRegistry.initialise(new ConfigurationFileApplicationRegistry(configFile), REGISTRY);
- VirtualHostRegistry virtualHostRegistry = ApplicationRegistry.getInstance(REGISTRY).getVirtualHostRegistry();
+ VirtualHostRegistry virtualHostRegistry = ApplicationRegistry.getInstance(REGISTRY).getVirtualHostRegistry();
- assertEquals("Incorrect virtualhost count", 3 , virtualHostRegistry.getVirtualHosts().size());
+ assertEquals("Incorrect virtualhost count", 3 , virtualHostRegistry.getVirtualHosts().size());
+ }
+ finally
+ {
+ ApplicationRegistry.remove(REGISTRY);
+ }
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java
index b65020395c..683343aa14 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java
@@ -22,12 +22,12 @@ package org.apache.qpid.server.configuration;
import junit.framework.TestCase;
import org.apache.commons.configuration.XMLConfiguration;
+
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.queue.AMQPriorityQueue;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.virtualhost.VirtualHostImpl;
public class VirtualHostConfigurationTest extends TestCase
{
@@ -39,8 +39,6 @@ public class VirtualHostConfigurationTest extends TestCase
protected void setUp() throws Exception
{
super.setUp();
- //Highlight that this test will cause a new AR to be created
- ApplicationRegistry.getInstance();
// Fill config file with stuff
configXml = new XMLConfiguration();
configXml.setRootElementName("virtualhosts");
@@ -49,39 +47,37 @@ public class VirtualHostConfigurationTest extends TestCase
public void tearDown() throws Exception
{
- //Correctly close the AR we created
- ApplicationRegistry.remove();
-
super.tearDown();
}
public void testQueuePriority() throws Exception
{
+ configXml.addProperty("virtualhost.testQueuePriority.name", "testQueuePriority");
// Set up queue with 5 priorities
- configXml.addProperty("virtualhost.test.queues(-1).queue(-1).name(-1)",
+ configXml.addProperty("virtualhost.testQueuePriority.queues(-1).queue(-1).name(-1)",
"atest");
- configXml.addProperty("virtualhost.test.queues.queue.atest(-1).exchange",
+ configXml.addProperty("virtualhost.testQueuePriority.queues.queue.atest(-1).exchange",
"amq.direct");
- configXml.addProperty("virtualhost.test.queues.queue.atest.priorities",
+ configXml.addProperty("virtualhost.testQueuePriority.queues.queue.atest.priorities",
"5");
// Set up queue with JMS style priorities
- configXml.addProperty("virtualhost.test.queues(-1).queue(-1).name(-1)",
+ configXml.addProperty("virtualhost.testQueuePriority.queues(-1).queue(-1).name(-1)",
"ptest");
- configXml.addProperty("virtualhost.test.queues.queue.ptest(-1).exchange",
+ configXml.addProperty("virtualhost.testQueuePriority.queues.queue.ptest(-1).exchange",
"amq.direct");
- configXml.addProperty("virtualhost.test.queues.queue.ptest.priority",
+ configXml.addProperty("virtualhost.testQueuePriority.queues.queue.ptest.priority",
"true");
// Set up queue with no priorities
- configXml.addProperty("virtualhost.test.queues(-1).queue(-1).name(-1)",
+ configXml.addProperty("virtualhost.testQueuePriority.queues(-1).queue(-1).name(-1)",
"ntest");
- configXml.addProperty("virtualhost.test.queues.queue.ntest(-1).exchange",
+ configXml.addProperty("virtualhost.testQueuePriority.queues.queue.ntest(-1).exchange",
"amq.direct");
- configXml.addProperty("virtualhost.test.queues.queue.ntest.priority",
+ configXml.addProperty("virtualhost.testQueuePriority.queues.queue.ntest.priority",
"false");
- VirtualHost vhost = new VirtualHostImpl(new VirtualHostConfiguration("test", configXml.subset("virtualhost.test")));
+ VirtualHost vhost = ApplicationRegistry.getInstance().createVirtualHost(new VirtualHostConfiguration("testQueuePriority", configXml.subset("virtualhost.testQueuePriority")));
// Check that atest was a priority queue with 5 priorities
AMQQueue atest = vhost.getQueueRegistry().getQueue(new AMQShortString("atest"));
@@ -96,25 +92,29 @@ public class VirtualHostConfigurationTest extends TestCase
// Check that ntest wasn't a priority queue
AMQQueue ntest = vhost.getQueueRegistry().getQueue(new AMQShortString("ntest"));
assertFalse(ntest instanceof AMQPriorityQueue);
+
+ ApplicationRegistry.remove();
+
}
public void testQueueAlerts() throws Exception
{
+ configXml.addProperty("virtualhost.testQueueAlerts.name", "testQueueAlerts");
// Set up queue with 5 priorities
- configXml.addProperty("virtualhost.test.queues.exchange", "amq.topic");
- configXml.addProperty("virtualhost.test.queues.maximumQueueDepth", "1");
- configXml.addProperty("virtualhost.test.queues.maximumMessageSize", "2");
- configXml.addProperty("virtualhost.test.queues.maximumMessageAge", "3");
+ configXml.addProperty("virtualhost.testQueueAlerts.queues.exchange", "amq.topic");
+ configXml.addProperty("virtualhost.testQueueAlerts.queues.maximumQueueDepth", "1");
+ configXml.addProperty("virtualhost.testQueueAlerts.queues.maximumMessageSize", "2");
+ configXml.addProperty("virtualhost.testQueueAlerts.queues.maximumMessageAge", "3");
- configXml.addProperty("virtualhost.test.queues(-1).queue(1).name(1)", "atest");
- configXml.addProperty("virtualhost.test.queues.queue.atest(-1).exchange", "amq.direct");
- configXml.addProperty("virtualhost.test.queues.queue.atest(-1).maximumQueueDepth", "4");
- configXml.addProperty("virtualhost.test.queues.queue.atest(-1).maximumMessageSize", "5");
- configXml.addProperty("virtualhost.test.queues.queue.atest(-1).maximumMessageAge", "6");
+ configXml.addProperty("virtualhost.testQueueAlerts.queues(-1).queue(1).name(1)", "atest");
+ configXml.addProperty("virtualhost.testQueueAlerts.queues.queue.atest(-1).exchange", "amq.direct");
+ configXml.addProperty("virtualhost.testQueueAlerts.queues.queue.atest(-1).maximumQueueDepth", "4");
+ configXml.addProperty("virtualhost.testQueueAlerts.queues.queue.atest(-1).maximumMessageSize", "5");
+ configXml.addProperty("virtualhost.testQueueAlerts.queues.queue.atest(-1).maximumMessageAge", "6");
- configXml.addProperty("virtualhost.test.queues(-1).queue(-1).name(-1)", "btest");
+ configXml.addProperty("virtualhost.testQueueAlerts.queues(-1).queue(-1).name(-1)", "btest");
- VirtualHost vhost = new VirtualHostImpl(new VirtualHostConfiguration("test", configXml.subset("virtualhost.test")));
+ VirtualHost vhost = ApplicationRegistry.getInstance().createVirtualHost(new VirtualHostConfiguration("testQueueAlerts", configXml.subset("virtualhost.testQueueAlerts")));
// Check specifically configured values
AMQQueue aTest = vhost.getQueueRegistry().getQueue(new AMQShortString("atest"));
@@ -128,6 +128,9 @@ public class VirtualHostConfigurationTest extends TestCase
assertEquals(2, bTest.getMaximumMessageSize());
assertEquals(3, bTest.getMaximumMessageAge());
+ ApplicationRegistry.remove();
+
+
}
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java b/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java
index e26b5b048c..06d5d80ac1 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java
@@ -21,23 +21,41 @@
package org.apache.qpid.server.exchange;
import junit.framework.TestCase;
+import org.apache.log4j.Logger;
+
import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.*;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.BasicContentHeaderProperties;
+import org.apache.qpid.framing.ContentBody;
+import org.apache.qpid.framing.ContentHeaderBody;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.framing.FieldTableFactory;
import org.apache.qpid.framing.abstraction.MessagePublishInfo;
-import org.apache.qpid.server.queue.*;
+import org.apache.qpid.server.binding.BindingFactory;
+import org.apache.qpid.server.message.AMQMessage;
+import org.apache.qpid.server.message.AMQMessageHeader;
+import org.apache.qpid.server.message.MessageMetaData;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.server.protocol.AMQProtocolSession;
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.queue.BaseQueue;
+import org.apache.qpid.server.queue.IncomingMessage;
+import org.apache.qpid.server.queue.MockStoredMessage;
+import org.apache.qpid.server.queue.QueueEntry;
+import org.apache.qpid.server.queue.SimpleAMQQueue;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.store.MessageStore;
+import org.apache.qpid.server.store.DurableConfigurationStore;
import org.apache.qpid.server.store.MemoryMessageStore;
+import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.store.StoredMessage;
-import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.server.message.AMQMessageHeader;
-import org.apache.qpid.server.message.AMQMessage;
-import org.apache.qpid.server.message.MessageMetaData;
import org.apache.qpid.server.subscription.Subscription;
-import org.apache.qpid.server.protocol.AMQProtocolSession;
-import org.apache.log4j.Logger;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
public class AbstractHeadersExchangeTestBase extends TestCase
@@ -47,11 +65,24 @@ public class AbstractHeadersExchangeTestBase extends TestCase
private final HeadersExchange exchange = new HeadersExchange();
protected final Set<TestQueue> queues = new HashSet<TestQueue>();
+
+
/**
* Not used in this test, just there to stub out the routing calls
*/
private MessageStore _store = new MemoryMessageStore();
+
+ BindingFactory bindingFactory = new BindingFactory(new DurableConfigurationStore.Source()
+ {
+
+ public DurableConfigurationStore getDurableConfigurationStore()
+ {
+ return _store;
+ }
+ },
+ exchange);
+
private int count;
public void testDoNothing()
@@ -93,7 +124,7 @@ public class AbstractHeadersExchangeTestBase extends TestCase
m.route(exchange);
if(m.getIncomingMessage().allContentReceived())
{
- for(AMQQueue q : m.getIncomingMessage().getDestinationQueues())
+ for(BaseQueue q : m.getIncomingMessage().getDestinationQueues())
{
q.enqueue(m);
}
@@ -241,15 +272,17 @@ public class AbstractHeadersExchangeTestBase extends TestCase
public String toString()
{
- return getName().toString();
+ return getNameShortString().toString();
}
public TestQueue(AMQShortString name) throws AMQException
{
- super(name, false, new AMQShortString("test"), true, ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test"));
+ super(name, false, new AMQShortString("test"), true, ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test"),Collections.EMPTY_MAP);
ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test").getQueueRegistry().registerQueue(this);
}
+
+
/**
* We override this method so that the default behaviour, which attempts to use a delivery manager, is
* not invoked. It is unnecessary since for this test we only care to know whether the message was
@@ -258,10 +291,10 @@ public class AbstractHeadersExchangeTestBase extends TestCase
* @throws AMQException
*/
@Override
- public QueueEntry enqueue(ServerMessage msg) throws AMQException
+ public void enqueue(ServerMessage msg, PostEnqueueAction action) throws AMQException
{
messages.add( new HeadersExchangeTest.Message((AMQMessage) msg));
- return new QueueEntry()
+ final QueueEntry queueEntry = new QueueEntry()
{
public AMQQueue getQueue()
@@ -289,6 +322,11 @@ public class AbstractHeadersExchangeTestBase extends TestCase
return false; //To change body of implemented methods use File | Settings | File Templates.
}
+ public boolean isAvailable()
+ {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
public boolean isAcquired()
{
return false; //To change body of implemented methods use File | Settings | File Templates.
@@ -439,6 +477,12 @@ public class AbstractHeadersExchangeTestBase extends TestCase
return 0; //To change body of implemented methods use File | Settings | File Templates.
}
};
+
+ if(action != null)
+ {
+ action.onEnqueue(queueEntry);
+ }
+
}
boolean isInQueue(Message msg)
diff --git a/java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java b/java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java
index 016f7eacbe..b26c71a524 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java
@@ -29,7 +29,6 @@ import org.apache.qpid.server.queue.AMQQueueFactory;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.registry.IApplicationRegistry;
import org.apache.qpid.server.management.ManagedObject;
-import org.apache.qpid.server.virtualhost.VirtualHostImpl;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
@@ -58,8 +57,8 @@ public class ExchangeMBeanTest extends TestCase
ManagedObject managedObj = exchange.getManagedObject();
ManagedExchange mbean = (ManagedExchange)managedObj;
- mbean.createNewBinding(_queue.getName().toString(), "binding1");
- mbean.createNewBinding(_queue.getName().toString(), "binding2");
+ mbean.createNewBinding(_queue.getNameShortString().toString(), "binding1");
+ mbean.createNewBinding(_queue.getNameShortString().toString(), "binding2");
TabularData data = mbean.bindings();
ArrayList<Object> list = new ArrayList<Object>(data.values());
@@ -85,8 +84,8 @@ public class ExchangeMBeanTest extends TestCase
ManagedObject managedObj = exchange.getManagedObject();
ManagedExchange mbean = (ManagedExchange)managedObj;
- mbean.createNewBinding(_queue.getName().toString(), "binding1");
- mbean.createNewBinding(_queue.getName().toString(), "binding2");
+ mbean.createNewBinding(_queue.getNameShortString().toString(), "binding1");
+ mbean.createNewBinding(_queue.getNameShortString().toString(), "binding2");
TabularData data = mbean.bindings();
ArrayList<Object> list = new ArrayList<Object>(data.values());
@@ -112,8 +111,8 @@ public class ExchangeMBeanTest extends TestCase
ManagedObject managedObj = exchange.getManagedObject();
ManagedExchange mbean = (ManagedExchange)managedObj;
- mbean.createNewBinding(_queue.getName().toString(), "key1=binding1,key2=binding2");
- mbean.createNewBinding(_queue.getName().toString(), "key3=binding3");
+ mbean.createNewBinding(_queue.getNameShortString().toString(), "key1=binding1,key2=binding2");
+ mbean.createNewBinding(_queue.getNameShortString().toString(), "key3=binding3");
TabularData data = mbean.bindings();
ArrayList<Object> list = new ArrayList<Object>(data.values());
diff --git a/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersBindingTest.java b/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersBindingTest.java
index dc47951548..1e56a32383 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersBindingTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersBindingTest.java
@@ -83,6 +83,16 @@ public class HeadersBindingTest extends TestCase
return null;
}
+ public String getReplyToExchange()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public String getReplyToRoutingKey()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
public Object getHeader(String name)
{
return _headers.get(name);
diff --git a/java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java b/java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java
index 9d7a323b6d..daa0377e0a 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java
@@ -67,11 +67,8 @@ public class TopicExchangeTest extends TestCase
_exchange.registerQueue(new AMQShortString("a.*.#.b"), queue, null);
- MessagePublishInfo info = new PublishInfo(new AMQShortString("a.b"));
-
- IncomingMessage message = new IncomingMessage(info);
-
- message.enqueue(_exchange.route(message));
+ IncomingMessage message = createMessage("a.b");
+ routeMessage(message);
Assert.assertEquals(0, queue.getMessageCount());
}
@@ -357,7 +354,7 @@ public class TopicExchangeTest extends TestCase
message.enqueue(_exchange.route(message));
AMQMessage msg = new AMQMessage(message.getStoredMessage());
- for(AMQQueue q : message.getDestinationQueues())
+ for(BaseQueue q : message.getDestinationQueues())
{
q.enqueue(msg);
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ExchangeMessagesTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ExchangeMessagesTest.java
index 072f671fec..174576b473 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ExchangeMessagesTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ExchangeMessagesTest.java
@@ -37,8 +37,8 @@ public class ExchangeMessagesTest extends AbstractTestMessages
getVirtualHostRegistry().getVirtualHost("test").
getExchangeRegistry().getDefaultExchange();
- String type = exchange.getType().toString();
- String name = exchange.getName().toString();
+ String type = exchange.getTypeShortString().toString();
+ String name = exchange.getNameShortString().toString();
_logMessage = ExchangeMessages.EXH_CREATED(type, name, false);
List<Object> log = performLog();
@@ -55,8 +55,8 @@ public class ExchangeMessagesTest extends AbstractTestMessages
getVirtualHostRegistry().getVirtualHost("test").
getExchangeRegistry().getDefaultExchange();
- String type = exchange.getType().toString();
- String name = exchange.getName().toString();
+ String type = exchange.getTypeShortString().toString();
+ String name = exchange.getNameShortString().toString();
_logMessage = ExchangeMessages.EXH_CREATED(type, name, true);
List<Object> log = performLog();
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/AbstractTestLogSubject.java b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/AbstractTestLogSubject.java
index 905d63ea09..4d75a899be 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/AbstractTestLogSubject.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/AbstractTestLogSubject.java
@@ -50,7 +50,7 @@ import java.util.List;
* validate this class then performs a log statement with logging enabled and
* logging disabled.
*
- * The resulting log file is then validated.
+ * The resulting log file is then validated.
*
*/
public abstract class AbstractTestLogSubject extends TestCase
@@ -177,7 +177,7 @@ public abstract class AbstractTestLogSubject extends TestCase
assertNotNull("Queue not found:" + message, queueSlice);
assertEquals("Queue name not correct",
- queue.getName().toString(), queueSlice);
+ queue.getNameShortString().toString(), queueSlice);
}
/**
@@ -199,10 +199,10 @@ public abstract class AbstractTestLogSubject extends TestCase
exchangeParts.length);
assertEquals("Exchange type not correct",
- exchange.getType().toString(), exchangeParts[0]);
+ exchange.getTypeShortString().toString(), exchangeParts[0]);
assertEquals("Exchange name not correct",
- exchange.getName().toString(), exchangeParts[1]);
+ exchange.getNameShortString().toString(), exchangeParts[1]);
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/BindingLogSubjectTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/BindingLogSubjectTest.java
index 6319238841..279628501c 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/BindingLogSubjectTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/BindingLogSubjectTest.java
@@ -50,7 +50,7 @@ public class BindingLogSubjectTest extends AbstractTestLogSubject
_queue = new MockAMQQueue("BindingLogSubjectTest");
((MockAMQQueue) _queue).setVirtualHost(_testVhost);
- _subject = new BindingLogSubject(_routingKey, _exchange, _queue);
+ _subject = new BindingLogSubject(String.valueOf(_routingKey), _exchange, _queue);
}
/**
diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java
index 4e5ba0213a..ea89d026ff 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java
@@ -302,7 +302,7 @@ public class AMQQueueMBeanTest extends TestCase
});
AMQMessage m = new AMQMessage(msg.getStoredMessage());
- for(AMQQueue q : msg.getDestinationQueues())
+ for(BaseQueue q : msg.getDestinationQueues())
{
q.enqueue(m);
}
@@ -463,7 +463,7 @@ public class AMQQueueMBeanTest extends TestCase
MESSAGE_SIZE)));
AMQMessage m = new AMQMessage(currentMessage.getStoredMessage());
- for(AMQQueue q : currentMessage.getDestinationQueues())
+ for(BaseQueue q : currentMessage.getDestinationQueues())
{
q.enqueue(m);
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java b/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java
index a487b160e1..10a828d07c 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java
@@ -22,7 +22,7 @@ package org.apache.qpid.server.queue;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.server.configuration.QueueConfiguration;
+import org.apache.qpid.server.configuration.*;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.virtualhost.VirtualHost;
@@ -30,12 +30,14 @@ import org.apache.qpid.server.management.ManagedObject;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.security.PrincipalHolder;
import org.apache.qpid.server.AMQChannel;
+import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.txn.ServerTransaction;
import org.apache.qpid.AMQException;
import java.util.List;
import java.util.Set;
import java.util.Map;
+import java.util.UUID;
public class MockAMQQueue implements AMQQueue
{
@@ -58,17 +60,107 @@ public class MockAMQQueue implements AMQQueue
}
public void setDeleteOnNoConsumers(boolean b)
- {
+ {
+ }
+
+ public void addBinding(final Binding binding)
+ {
+
+ }
+
+ public void removeBinding(final Binding binding)
+ {
+
+ }
+
+ public List<Binding> getBindings()
+ {
+ return null;
+ }
+
+ public int getBindingCount()
+ {
+ return 0;
+ }
+
+ public ConfigStore getConfigStore()
+ {
+ return getVirtualHost().getConfigStore();
+ }
+
+ public long getMessageDequeueCount()
+ {
+ return 0;
+ }
+
+ public long getTotalEnqueueSize()
+ {
+ return 0;
}
- public AMQShortString getName()
+ public long getTotalDequeueSize()
+ {
+ return 0;
+ }
+
+ public int getBindingCountHigh()
+ {
+ return 0;
+ }
+
+ public long getPersistentByteEnqueues()
+ {
+ return 0;
+ }
+
+ public long getPersistentByteDequeues()
+ {
+ return 0;
+ }
+
+ public long getPersistentMsgEnqueues()
+ {
+ return 0;
+ }
+
+ public long getPersistentMsgDequeues()
+ {
+ return 0;
+ }
+
+ public void purge(final long request)
+ {
+
+ }
+
+ public long getCreateTime()
+ {
+ return 0;
+ }
+
+ public AMQShortString getNameShortString()
{
return _name;
}
public void setNoLocal(boolean b)
{
-
+
+ }
+
+ public UUID getId()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public QueueConfigType getConfigType()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public ConfiguredObject getParent()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
}
public boolean isDurable()
@@ -96,6 +188,11 @@ public class MockAMQQueue implements AMQQueue
return _virtualhost;
}
+ public String getName()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
public void bind(Exchange exchange, AMQShortString routingKey, FieldTable arguments) throws AMQException
{
//To change body of implemented methods use File | Settings | File Templates.
@@ -106,10 +203,6 @@ public class MockAMQQueue implements AMQQueue
//To change body of implemented methods use File | Settings | File Templates.
}
- public List<ExchangeBinding> getExchangeBindings()
- {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
public void registerSubscription(Subscription subscription, boolean exclusive) throws AMQException
{
@@ -131,6 +224,11 @@ public class MockAMQQueue implements AMQQueue
return 0; //To change body of implemented methods use File | Settings | File Templates.
}
+ public boolean hasExclusiveSubscriber()
+ {
+ return false;
+ }
+
public boolean isUnused()
{
return false; //To change body of implemented methods use File | Settings | File Templates.
@@ -176,11 +274,15 @@ public class MockAMQQueue implements AMQQueue
return 0; //To change body of implemented methods use File | Settings | File Templates.
}
- public QueueEntry enqueue(ServerMessage message) throws AMQException
+ public void enqueue(ServerMessage message) throws AMQException
+ {
+ }
+
+ public void enqueue(ServerMessage message, PostEnqueueAction action) throws AMQException
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
}
+
public void requeue(QueueEntry entry)
{
//To change body of implemented methods use File | Settings | File Templates.
@@ -206,6 +308,11 @@ public class MockAMQQueue implements AMQQueue
//To change body of implemented methods use File | Settings | File Templates.
}
+ public void removeQueueDeleteTask(final Task task)
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
public List<QueueEntry> getMessagesOnTheQueue()
{
return null; //To change body of implemented methods use File | Settings | File Templates.
diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/MockQueueEntry.java b/java/broker/src/test/java/org/apache/qpid/server/queue/MockQueueEntry.java
index 3f74cb973b..8b894c9629 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/queue/MockQueueEntry.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/queue/MockQueueEntry.java
@@ -85,6 +85,11 @@ public class MockQueueEntry implements QueueEntry
return false;
}
+ public boolean isAvailable()
+ {
+ return false;
+ }
+
public Subscription getDeliveredSubscription()
{
return null;
diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java
index 408893870b..2abeb7ed30 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java
@@ -21,12 +21,9 @@ package org.apache.qpid.server.queue;
*/
-import java.util.ArrayList;
-import java.util.List;
-
import junit.framework.TestCase;
-
import org.apache.commons.configuration.PropertiesConfiguration;
+
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.BasicContentHeaderProperties;
@@ -35,17 +32,21 @@ import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.framing.abstraction.MessagePublishInfo;
import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.exchange.DirectExchange;
+import org.apache.qpid.server.message.AMQMessage;
+import org.apache.qpid.server.message.MessageMetaData;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.store.TestableMemoryMessageStore;
import org.apache.qpid.server.store.StoredMessage;
+import org.apache.qpid.server.store.TestableMemoryMessageStore;
import org.apache.qpid.server.subscription.MockSubscription;
import org.apache.qpid.server.subscription.Subscription;
-import org.apache.qpid.server.virtualhost.VirtualHostImpl;
-import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.txn.AutoCommitTransaction;
import org.apache.qpid.server.txn.ServerTransaction;
-import org.apache.qpid.server.message.AMQMessage;
-import org.apache.qpid.server.message.MessageMetaData;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.virtualhost.VirtualHostImpl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
public class SimpleAMQQueueTest extends TestCase
{
@@ -124,7 +125,7 @@ public class SimpleAMQQueueTest extends TestCase
}
try {
- _queue = new SimpleAMQQueue(_qname, false, _owner, false, null);
+ _queue = new SimpleAMQQueue(_qname, false, _owner, false, null,Collections.EMPTY_MAP);
assertNull("Queue was created", _queue);
}
catch (IllegalArgumentException e)
@@ -145,31 +146,23 @@ public class SimpleAMQQueueTest extends TestCase
public void testBinding()
{
- try
- {
- _queue.bind(_exchange, _routingKey, null);
- assertTrue("Routing key was not bound",
- _exchange.getBindings().containsKey(_routingKey));
- assertEquals("Queue was not bound to key",
- _exchange.getBindings().get(_routingKey).get(0),
- _queue);
- assertEquals("Exchange binding count", 1,
- _queue.getExchangeBindings().size());
- assertEquals("Wrong exchange bound", _routingKey,
- _queue.getExchangeBindings().get(0).getRoutingKey());
- assertEquals("Wrong exchange bound", _exchange,
- _queue.getExchangeBindings().get(0).getExchange());
-
- _queue.unBind(_exchange, _routingKey, null);
- assertFalse("Routing key was still bound",
- _exchange.getBindings().containsKey(_routingKey));
- assertNull("Routing key was not empty",
- _exchange.getBindings().get(_routingKey));
- }
- catch (AMQException e)
- {
- assertNull("Unexpected exception", e);
- }
+ _virtualHost.getBindingFactory().addBinding(String.valueOf(_routingKey), _queue, _exchange, Collections.EMPTY_MAP);
+
+ assertTrue("Routing key was not bound",
+ _exchange.isBound(_routingKey));
+ assertTrue("Queue was not bound to key",
+ _exchange.isBound(_routingKey,_queue));
+ assertEquals("Exchange binding count", 1,
+ _queue.getBindings().size());
+ assertEquals("Wrong exchange bound", String.valueOf(_routingKey),
+ _queue.getBindings().get(0).getBindingKey());
+ assertEquals("Wrong exchange bound", _exchange,
+ _queue.getBindings().get(0).getExchange());
+
+ _virtualHost.getBindingFactory().removeBinding(String.valueOf(_routingKey), _queue, _exchange, Collections.EMPTY_MAP);
+ assertFalse("Routing key was still bound",
+ _exchange.isBound(_routingKey));
+
}
public void testSubscription() throws AMQException
@@ -258,7 +251,7 @@ public class SimpleAMQQueueTest extends TestCase
public void testAutoDeleteQueue() throws Exception
{
_queue.stop();
- _queue = new SimpleAMQQueue(_qname, false, null, true, _virtualHost);
+ _queue = new SimpleAMQQueue(_qname, false, null, true, _virtualHost, Collections.EMPTY_MAP);
_queue.setDeleteOnNoConsumers(true);
_queue.registerSubscription(_subscription, false);
AMQMessage message = createMessage(new Long(25));
@@ -409,7 +402,7 @@ public class SimpleAMQQueueTest extends TestCase
((BasicContentHeaderProperties) contentHeaderBody.properties).setDeliveryMode((byte) 2);
msg.setContentHeaderBody(contentHeaderBody);
- final ArrayList<AMQQueue> qs = new ArrayList<AMQQueue>();
+ final ArrayList<BaseQueue> qs = new ArrayList<BaseQueue>();
// Send persistent message
diff --git a/java/broker/src/test/java/org/apache/qpid/server/registry/ApplicationRegistryShutdownTest.java b/java/broker/src/test/java/org/apache/qpid/server/registry/ApplicationRegistryShutdownTest.java
index 4c8ff01be0..cadde1288b 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/registry/ApplicationRegistryShutdownTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/registry/ApplicationRegistryShutdownTest.java
@@ -50,7 +50,7 @@ public class ApplicationRegistryShutdownTest extends TestCase
@Override
public void tearDown() throws Exception
{
- // Correctly Close the AR we created
+ // Correctly Close the AR we created
ApplicationRegistry.remove();
}
@@ -58,22 +58,15 @@ public class ApplicationRegistryShutdownTest extends TestCase
/**
* QPID-1399 : Ensure that the Authentiction manager unregisters any SASL providers created during
* ApplicationRegistry initialisation.
- *
+ *
*/
- public void testAuthenticationMangerCleansUp()
+ public void testAuthenticationMangerCleansUp() throws Exception
{
// Get default providers
Provider[] defaultProviders = Security.getProviders();
// Register new providers
- try
- {
- _registry.initialise(ApplicationRegistry.DEFAULT_INSTANCE);
- }
- catch (Exception e)
- {
- fail(e.getMessage());
- }
+ ApplicationRegistry.initialise(_registry, ApplicationRegistry.DEFAULT_INSTANCE);
// Get the providers after initialisation
Provider[] providersAfterInitialisation = Security.getProviders();
@@ -103,16 +96,9 @@ public class ApplicationRegistryShutdownTest extends TestCase
assertTrue("No new SASL mechanisms added by initialisation.", additions.size() != 0 );
//Close the registry which will perform the close the AuthenticationManager
- try
- {
- _registry.close();
- }
- catch (Exception e)
- {
- fail(e.getMessage());
- }
+ _registry.close();
- //Validate that the SASL plugins have been removed.
+ //Validate that the SASL plugFins have been removed.
Provider[] providersAfterClose = Security.getProviders();
assertTrue("No providers unregistered", providersAfterInitialisation.length > providersAfterClose.length);
diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java
index 73e9dac775..df466380b9 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java
@@ -23,19 +23,16 @@ package org.apache.qpid.server.security.access;
import junit.framework.TestCase;
-import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.framing.amqp_0_9.ExchangeDeclareBodyImpl;
import org.apache.qpid.framing.amqp_8_0.QueueBindBodyImpl;
-import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.exchange.DirectExchange;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.AMQQueueFactory;
+import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.security.access.ACLPlugin.AuthzResult;
-import org.apache.qpid.server.virtualhost.VirtualHostImpl;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.registry.ApplicationRegistry;
public class PrincipalPermissionsTest extends TestCase
{
@@ -74,8 +71,7 @@ public class PrincipalPermissionsTest extends TestCase
_perms = new PrincipalPermissions(_user);
try
{
- PropertiesConfiguration env = new PropertiesConfiguration();
- _virtualHost = new VirtualHostImpl(new VirtualHostConfiguration("test", env));
+ _virtualHost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test");
_exchange = DirectExchange.TYPE.newInstance(_virtualHost, _exchangeName, _durable, _ticket, _autoDelete);
_queue = AMQQueueFactory.createAMQQueueImpl(_queueName, false, _owner , false, _virtualHost, _arguments);
_temporaryQueue = AMQQueueFactory.createAMQQueueImpl(_tempQueueName, false, _owner , true, _virtualHost, _arguments);
@@ -106,7 +102,7 @@ public class PrincipalPermissionsTest extends TestCase
{
QueueBindBodyImpl bind = new QueueBindBodyImpl(_ticket, _queueName, _exchangeName, _routingKey, _nowait, _arguments);
Object[] args = new Object[]{bind, _exchange, _queue, _routingKey};
-
+
assertEquals(AuthzResult.DENIED, _perms.authorise(Permission.BIND, args));
_perms.grant(Permission.BIND, (Object[]) null);
assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.BIND, args));
@@ -116,7 +112,7 @@ public class PrincipalPermissionsTest extends TestCase
{
Object[] grantArgs = new Object[]{_temporary , _queueName, _exchangeName, _routingKey};
Object[] authArgs = new Object[]{_autoDelete, _queueName};
-
+
assertEquals(AuthzResult.DENIED, _perms.authorise(Permission.CREATEQUEUE, authArgs));
_perms.grant(Permission.CREATEQUEUE, grantArgs);
assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.CREATEQUEUE, authArgs));
@@ -157,12 +153,12 @@ public class PrincipalPermissionsTest extends TestCase
_perms.grant(Permission.CONSUME, grantArgs);
assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.CONSUME, authArgs));
}
-
+
public void testPublish()
{
Object[] authArgs = new Object[]{_exchange, _routingKey};
- Object[] grantArgs = new Object[]{_exchange.getName(), _routingKey};
-
+ Object[] grantArgs = new Object[]{_exchange.getNameShortString(), _routingKey};
+
assertEquals(AuthzResult.DENIED, _perms.authorise(Permission.PUBLISH, authArgs));
_perms.grant(Permission.PUBLISH, grantArgs);
assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.PUBLISH, authArgs));
@@ -171,28 +167,28 @@ public class PrincipalPermissionsTest extends TestCase
public void testVhostAccess()
{
//Tests that granting a user Virtualhost level access allows all authorisation requests
- //where previously they would be denied
-
+ //where previously they would be denied
+
//QPID-2133 createExchange rights currently allow all exchange creation unless rights for creating some
//specific exchanges are granted. Grant a specific exchange creation to cause all others to be denied.
Object[] createArgsCreateExchange = new Object[]{new AMQShortString("madeup"), _exchangeType};
Object[] authArgsCreateExchange = new Object[]{_exchangeName,_exchangeType};
assertEquals("Exchange creation was not allowed", AuthzResult.ALLOWED, _perms.authorise(Permission.CREATEEXCHANGE, authArgsCreateExchange));
_perms.grant(Permission.CREATEEXCHANGE, createArgsCreateExchange);
-
- Object[] authArgsPublish = new Object[]{_exchange, _routingKey};
+
+ Object[] authArgsPublish = new Object[]{_exchange, _routingKey};
Object[] authArgsConsume = new Object[]{_queue};
Object[] authArgsCreateQueue = new Object[]{_autoDelete, _queueName};
QueueBindBodyImpl bind = new QueueBindBodyImpl(_ticket, _queueName, _exchangeName, _routingKey, _nowait, _arguments);
Object[] authArgsBind = new Object[]{bind, _exchange, _queue, _routingKey};
-
+
assertEquals("Exchange creation was not denied", AuthzResult.DENIED, _perms.authorise(Permission.CREATEEXCHANGE, authArgsCreateExchange));
assertEquals("Publish was not denied", AuthzResult.DENIED, _perms.authorise(Permission.PUBLISH, authArgsPublish));
assertEquals("Consume creation was not denied", AuthzResult.DENIED, _perms.authorise(Permission.CONSUME, authArgsConsume));
assertEquals("Queue creation was not denied", AuthzResult.DENIED, _perms.authorise(Permission.CREATEQUEUE, authArgsCreateQueue));
//BIND pre-grant authorise check disabled due to QPID-1597
//assertEquals("Binding creation was not denied", AuthzResult.DENIED, _perms.authorise(Permission.BIND, authArgsBind));
-
+
_perms.grant(Permission.ACCESS);
assertEquals("Exchange creation was not allowed", AuthzResult.ALLOWED, _perms.authorise(Permission.CREATEEXCHANGE, authArgsCreateExchange));
diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/access/QueueDenier.java b/java/broker/src/test/java/org/apache/qpid/server/security/access/QueueDenier.java
index 5b76bf7532..3f9c776aa2 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/security/access/QueueDenier.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/access/QueueDenier.java
@@ -49,7 +49,7 @@ public class QueueDenier extends AllowAll
@Override
public AuthzResult authoriseDelete(PrincipalHolder session, AMQQueue queue)
{
- if (!(queue.getName().toString().equals(_queueName)))
+ if (!(queue.getNameShortString().toString().equals(_queueName)))
{
return AuthzResult.ALLOWED;
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java b/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java
index e011301f06..2427e28e70 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java
@@ -21,33 +21,39 @@
package org.apache.qpid.server.store;
import junit.framework.TestCase;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.common.AMQPFilterTypes;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.BasicContentHeaderProperties;
+import org.apache.qpid.framing.ContentHeaderBody;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.framing.abstraction.MessagePublishInfo;
+import org.apache.qpid.framing.amqp_8_0.BasicConsumeBodyImpl;
+import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.exchange.DirectExchange;
import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.exchange.ExchangeRegistry;
import org.apache.qpid.server.exchange.ExchangeType;
import org.apache.qpid.server.exchange.TopicExchange;
-import org.apache.qpid.server.exchange.ExchangeRegistry;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.virtualhost.VirtualHostImpl;
-import org.apache.qpid.server.queue.*;
-import org.apache.qpid.server.txn.ServerTransaction;
-import org.apache.qpid.server.txn.AutoCommitTransaction;
-import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.message.AMQMessage;
import org.apache.qpid.server.message.MessageMetaData;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.framing.ContentHeaderBody;
-import org.apache.qpid.framing.BasicContentHeaderProperties;
-import org.apache.qpid.framing.amqp_8_0.BasicConsumeBodyImpl;
-import org.apache.qpid.framing.abstraction.MessagePublishInfo;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.common.AMQPFilterTypes;
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.PropertiesConfiguration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.qpid.server.queue.AMQPriorityQueue;
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.queue.AMQQueueFactory;
+import org.apache.qpid.server.queue.BaseQueue;
+import org.apache.qpid.server.queue.IncomingMessage;
+import org.apache.qpid.server.queue.QueueRegistry;
+import org.apache.qpid.server.queue.SimpleAMQQueue;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.txn.AutoCommitTransaction;
+import org.apache.qpid.server.txn.ServerTransaction;
+import org.apache.qpid.server.virtualhost.VirtualHost;
import java.io.File;
import java.util.List;
@@ -99,8 +105,7 @@ public class MessageStoreTest extends TestCase
try
{
- _virtualHost = new VirtualHostImpl(new VirtualHostConfiguration(getClass().getName(), configuration));
- ApplicationRegistry.getInstance().getVirtualHostRegistry().registerVirtualHost(_virtualHost);
+ _virtualHost = ApplicationRegistry.getInstance().createVirtualHost(new VirtualHostConfiguration(getClass().getName(), configuration));
}
catch (Exception e)
{
@@ -244,10 +249,10 @@ public class MessageStoreTest extends TestCase
{
QueueRegistry queueRegistry = _virtualHost.getQueueRegistry();
- validateBindingProperties(queueRegistry.getQueue(durablePriorityQueueName).getExchangeBindings(), false);
- validateBindingProperties(queueRegistry.getQueue(durablePriorityTopicQueueName).getExchangeBindings(), true);
- validateBindingProperties(queueRegistry.getQueue(durableQueueName).getExchangeBindings(), false);
- validateBindingProperties(queueRegistry.getQueue(durableTopicQueueName).getExchangeBindings(), true);
+ validateBindingProperties(queueRegistry.getQueue(durablePriorityQueueName).getBindings(), false);
+ validateBindingProperties(queueRegistry.getQueue(durablePriorityTopicQueueName).getBindings(), true);
+ validateBindingProperties(queueRegistry.getQueue(durableQueueName).getBindings(), false);
+ validateBindingProperties(queueRegistry.getQueue(durableTopicQueueName).getBindings(), true);
}
/**
@@ -256,16 +261,16 @@ public class MessageStoreTest extends TestCase
* @param bindings the set of bindings to validate
* @param useSelectors if set validate that the binding has a JMS_SELECTOR argument
*/
- private void validateBindingProperties(List<ExchangeBinding> bindings, boolean useSelectors)
+ private void validateBindingProperties(List<Binding> bindings, boolean useSelectors)
{
assertEquals("Each queue should only be bound once.", 1, bindings.size());
- ExchangeBinding binding = bindings.get(0);
+ Binding binding = bindings.get(0);
if (useSelectors)
{
assertTrue("Binding does not contain a Selector argument.",
- binding.getArguments().containsKey(AMQPFilterTypes.JMS_SELECTOR.getValue()));
+ binding.getArguments().containsKey(AMQPFilterTypes.JMS_SELECTOR.toString()));
}
}
@@ -376,7 +381,7 @@ public class MessageStoreTest extends TestCase
{
// TODO Deliver to queues
ServerTransaction trans = new AutoCommitTransaction(_virtualHost.getMessageStore());
- final List<AMQQueue> destinationQueues = currentMessage.getDestinationQueues();
+ final List<? extends BaseQueue> destinationQueues = currentMessage.getDestinationQueues();
trans.enqueue(currentMessage.getDestinationQueues(), currentMessage, new ServerTransaction.Action() {
public void postCommit()
{
@@ -384,9 +389,9 @@ public class MessageStoreTest extends TestCase
{
AMQMessage message = new AMQMessage(currentMessage.getStoredMessage());
- for(AMQQueue queue : destinationQueues)
+ for(BaseQueue queue : destinationQueues)
{
- QueueEntry entry = queue.enqueue(message);
+ queue.enqueue(message);
}
}
catch (AMQException e)
@@ -525,14 +530,7 @@ public class MessageStoreTest extends TestCase
protected void bindQueueToExchange(Exchange exchange, AMQShortString routingKey, AMQQueue queue, boolean useSelector, FieldTable queueArguments)
{
- try
- {
- exchange.registerQueue(queueName, queue, queueArguments);
- }
- catch (AMQException e)
- {
- fail(e.getMessage());
- }
+
FieldTable bindArguments = null;
@@ -544,9 +542,9 @@ public class MessageStoreTest extends TestCase
try
{
- queue.bind(exchange, routingKey, bindArguments);
+ _virtualHost.getBindingFactory().addBinding(String.valueOf(routingKey), queue, exchange, FieldTable.convertToMap(bindArguments));
}
- catch (AMQException e)
+ catch (Exception e)
{
fail(e.getMessage());
}
@@ -609,7 +607,7 @@ public class MessageStoreTest extends TestCase
public AMQShortString getExchange()
{
- return _exchange.getName();
+ return _exchange.getNameShortString();
}
public void setExchange(AMQShortString exchange)
diff --git a/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java b/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java
index 906c769f9c..85412cf74e 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java
@@ -74,7 +74,7 @@ public class InternalBrokerBaseCase extends TestCase
Exchange defaultExchange = _virtualHost.getExchangeRegistry().getDefaultExchange();
- _queue.bind(defaultExchange, QUEUE_NAME, null);
+ _virtualHost.getBindingFactory().addBinding(QUEUE_NAME.toString(), _queue, defaultExchange, null);
_session = new InternalTestProtocolSession(_virtualHost);
CurrentActor.set(_session.getLogActor());
diff --git a/java/broker/src/test/java/org/apache/qpid/server/util/NullApplicationRegistry.java b/java/broker/src/test/java/org/apache/qpid/server/util/NullApplicationRegistry.java
index 3d37412376..d927bbe732 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/util/NullApplicationRegistry.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/util/NullApplicationRegistry.java
@@ -22,12 +22,14 @@ package org.apache.qpid.server.util;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
+
+import org.apache.qpid.qmf.QMFService;
import org.apache.qpid.server.configuration.ServerConfiguration;
import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.logging.RootMessageLoggerImpl;
+import org.apache.qpid.server.logging.actors.BrokerActor;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.actors.TestLogActor;
-import org.apache.qpid.server.logging.actors.BrokerActor;
import org.apache.qpid.server.logging.rawloggers.Log4jMessageLogger;
import org.apache.qpid.server.management.NoopManagedObjectRegistry;
import org.apache.qpid.server.plugins.PluginManager;
@@ -36,14 +38,13 @@ import org.apache.qpid.server.security.access.ACLManager;
import org.apache.qpid.server.security.access.plugins.AllowAll;
import org.apache.qpid.server.security.auth.database.PropertiesPrincipalDatabaseManager;
import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
-import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-import org.apache.qpid.server.virtualhost.VirtualHostImpl;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Properties;
import java.util.NoSuchElementException;
+import java.util.Properties;
public class NullApplicationRegistry extends ApplicationRegistry
{
@@ -75,10 +76,11 @@ public class NullApplicationRegistry extends ApplicationRegistry
_managedObjectRegistry = new NoopManagedObjectRegistry();
_virtualHostRegistry = new VirtualHostRegistry(this);
+ _qmfService = new QMFService(getConfigStore(),this);
+
PropertiesConfiguration vhostProps = new PropertiesConfiguration();
VirtualHostConfiguration hostConfig = new VirtualHostConfiguration("test", vhostProps);
- VirtualHost dummyHost = new VirtualHostImpl(hostConfig);
- _virtualHostRegistry.registerVirtualHost(dummyHost);
+ VirtualHost dummyHost = ApplicationRegistry.getInstance().createVirtualHost(hostConfig);
_virtualHostRegistry.setDefaultVirtualHostName("test");
_pluginManager = new PluginManager("");
_startup = new Exception("NAR");
@@ -99,6 +101,7 @@ public class NullApplicationRegistry extends ApplicationRegistry
try
{
super.close();
+ _qmfService.close();
}
finally
{
diff --git a/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java b/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java
index bb338458f1..b5bbfde514 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java
@@ -22,10 +22,16 @@ package org.apache.qpid.server.util;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
+
+import org.apache.qpid.qmf.QMFService;
import org.apache.qpid.server.configuration.ServerConfiguration;
import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.exchange.ExchangeFactory;
import org.apache.qpid.server.exchange.ExchangeRegistry;
+import org.apache.qpid.server.logging.RootMessageLoggerImpl;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.actors.TestLogActor;
+import org.apache.qpid.server.logging.rawloggers.Log4jMessageLogger;
import org.apache.qpid.server.management.NoopManagedObjectRegistry;
import org.apache.qpid.server.queue.QueueRegistry;
import org.apache.qpid.server.registry.ApplicationRegistry;
@@ -35,17 +41,13 @@ import org.apache.qpid.server.security.auth.database.PropertiesPrincipalDatabase
import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.store.TestableMemoryMessageStore;
-import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-import org.apache.qpid.server.virtualhost.VirtualHostImpl;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.logging.RootMessageLoggerImpl;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.actors.TestLogActor;
-import org.apache.qpid.server.logging.rawloggers.Log4jMessageLogger;
+import org.apache.qpid.server.virtualhost.VirtualHostImpl;
+import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Properties;
-import java.util.Arrays;
public class TestApplicationRegistry extends ApplicationRegistry
{
@@ -97,6 +99,8 @@ public class TestApplicationRegistry extends ApplicationRegistry
_messageStore = new TestableMemoryMessageStore();
_virtualHostRegistry = new VirtualHostRegistry(this);
+ _qmfService = new QMFService(getConfigStore(),this);
+
PropertiesConfiguration vhostProps = new PropertiesConfiguration();
VirtualHostConfiguration hostConfig = new VirtualHostConfiguration("test", vhostProps);
@@ -147,6 +151,7 @@ public class TestApplicationRegistry extends ApplicationRegistry
try
{
super.close();
+ _qmfService.close();
}
finally
{
diff --git a/java/broker/src/xsl/qmf.xsl b/java/broker/src/xsl/qmf.xsl
new file mode 100644
index 0000000000..3133674de1
--- /dev/null
+++ b/java/broker/src/xsl/qmf.xsl
@@ -0,0 +1,842 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+<xsl:output omit-xml-declaration="yes" />
+<xsl:template match="/">
+/*
+ *
+ * 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.qmf.schema;
+
+import org.apache.qpid.qmf.*;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.transport.codec.BBEncoder;
+import org.apache.qpid.transport.codec.BBDecoder;
+
+import java.util.Arrays;
+import java.util.UUID;
+import java.util.Map;
+
+ <xsl:apply-templates select="descendant-or-self::node()[name()='schema']" mode="schema"/>
+
+</xsl:template>
+
+<xsl:template match="node()[name()='schema']" mode="schema">
+
+<xsl:variable name="schemaName"><xsl:call-template name="substringAfterLast"><xsl:with-param name="input" select="@package"/><xsl:with-param name="arg">.</xsl:with-param></xsl:call-template></xsl:variable>
+<xsl:variable name="ClassName"><xsl:call-template name="initCap"><xsl:with-param name="input" select="$schemaName"></xsl:with-param></xsl:call-template>Schema</xsl:variable>
+<xsl:variable name="classList"><xsl:apply-templates select="node()[name()='class']" mode="classList"/></xsl:variable>
+<xsl:variable name="eventList"><xsl:apply-templates select="node()[name()='event']" mode="eventList"/></xsl:variable>
+
+public class <xsl:value-of select="$ClassName"/> extends QMFPackage
+{
+ private static final byte QMF_VERSION = (byte) '2';
+
+ private static final BrokerSchema PACKAGE = new <xsl:value-of select="$ClassName"/>();
+ private static final String SCHEMA_NAME = "<xsl:value-of select="@package"/>";
+
+<xsl:text disable-output-escaping="yes">
+
+ protected abstract class QMFInfoCommand&lt;T extends QMFObject&gt; extends QMFCommand
+ {
+ private final T _object;
+ private final long _sampleTime;
+
+
+ protected QMFInfoCommand(QMFCommand trigger, QMFOperation op, T object, long sampleTime)
+ {
+ this(trigger.getHeader().getVersion(),
+ trigger.getHeader().getSeq(),
+ op,
+ object,
+ sampleTime);
+ }
+
+ protected QMFInfoCommand(QMFOperation op, T object, long sampleTime)
+ {
+ this(QMF_VERSION,0,op,object,sampleTime);
+ }
+
+ private QMFInfoCommand(final byte qmfVersion,
+ final int seq,
+ final QMFOperation op,
+ final T object,
+ final long sampleTime)
+ {
+ super(new QMFCommandHeader(qmfVersion, seq,op));
+ _object = object;
+ _sampleTime = sampleTime;
+ }
+
+ public T getObject()
+ {
+ return _object;
+ }
+
+ @Override
+ public void encode(final BBEncoder encoder)
+ {
+ super.encode(encoder);
+ encoder.writeStr8(SCHEMA_NAME);
+ encoder.writeStr8(_object.getQMFClass().getName());
+ encoder.writeBin128(new byte[16]);
+ encoder.writeUint64(_sampleTime * 1000000L);
+ encoder.writeUint64(_object.getCreateTime() * 1000000L);
+ encoder.writeUint64(_object.getDeleteTime() * 1000000L);
+ encoder.writeBin128(_object.getId());
+ }
+ }
+
+ protected abstract class QMFConfigInfoCommand&lt;T extends QMFObject&gt; extends QMFInfoCommand&lt;T&gt;
+ {
+ protected QMFConfigInfoCommand(T object, long sampleTime)
+ {
+ super(QMFOperation.CONFIG_INDICATION, object, sampleTime);
+ }
+ }
+
+ protected abstract class QMFInstrumentInfoCommand&lt;T extends QMFObject&gt; extends QMFInfoCommand&lt;T&gt;
+ {
+ protected QMFInstrumentInfoCommand(T object, long sampleTime)
+ {
+ super(QMFOperation.INSTRUMENTATION_INDICATION, object, sampleTime);
+ }
+ }
+
+ protected abstract class QMFGetQueryResponseCommand&lt;T extends QMFObject&gt; extends QMFInfoCommand&lt;T&gt;
+ {
+ protected QMFGetQueryResponseCommand(T object, QMFGetQueryCommand cmd, long sampleTime)
+ {
+ super(cmd, QMFOperation.GET_QUERY_RESPONSE, object, sampleTime);
+ }
+ }
+
+
+</xsl:text>
+
+ <xsl:apply-templates select="node()[name()='class']" mode="class"/>
+
+ <xsl:apply-templates select="node()[name()='event']" mode="event"/>
+
+ private <xsl:value-of select="$ClassName"/>()
+ {
+ super(SCHEMA_NAME);
+ setClasses( Arrays.asList( new QMFClass[] { <xsl:value-of select="$classList"/>, <xsl:value-of select="$eventList"/> } ) );
+ }
+<xsl:text disable-output-escaping="yes">
+ public &lt;T extends QMFClass&gt; T getQMFClassInstance(Class&lt;T&gt; clazz)
+ {
+ for(QMFClass c : getClasses())
+ {
+ if(clazz.isInstance(c))
+ {
+ return (T) c;
+ }
+ }
+ return null;
+ }
+</xsl:text>
+
+
+ public static BrokerSchema getPackage()
+ {
+ return PACKAGE;
+ }
+
+}
+</xsl:template>
+
+
+<xsl:template match="node()[name()='class']" mode="class">
+ <xsl:variable name="ClassName"><xsl:value-of select="@name"/>Class</xsl:variable>
+ <xsl:variable name="name"><xsl:call-template name="initLower"><xsl:with-param name="input" select="@name"/></xsl:call-template></xsl:variable>
+ <xsl:variable name="propertyList"><xsl:apply-templates select="node()[name()='property']" mode="propertyList"/></xsl:variable>
+ <xsl:variable name="statisticList"><xsl:apply-templates select="node()[name()='statistic']" mode="statisticList"/></xsl:variable>
+ <xsl:variable name="methodList"><xsl:apply-templates select="node()[name()='method']" mode="methodList"/></xsl:variable>
+
+ public class <xsl:value-of select="$ClassName"/> extends QMFObjectClass<xsl:text disable-output-escaping="yes">&lt;</xsl:text><xsl:value-of select="@name"/>Object, <xsl:value-of select="@name"/>Delegate<xsl:text disable-output-escaping="yes">&gt;</xsl:text>
+ {
+ <xsl:apply-templates select="node()[name()='property']" mode="property"/>
+
+ <xsl:apply-templates select="node()[name()='statistic']" mode="statistic"/>
+
+ <xsl:apply-templates select="node()[name()='method']" mode="method"><xsl:with-param name="qmfClass" select="@name"/></xsl:apply-templates>
+
+ private <xsl:value-of select="$ClassName"/>()
+ {
+ super("<xsl:value-of select="$name"/>",
+ new byte[16]);
+
+ setProperties( Arrays.asList( new QMFProperty[] { <xsl:value-of select="$propertyList"/> } ) );
+ setStatistics( Arrays.asList( new QMFStatistic[] { <xsl:value-of select="$statisticList"/> } ) );
+ setMethods( Arrays.asList( new QMFMethod[] { <xsl:value-of select="$methodList"/> } ) );
+ }
+
+ public <xsl:value-of select="@name"/>Object newInstance(final <xsl:value-of select="@name"/>Delegate delegate)
+ {
+ return new <xsl:value-of select="@name"/>Object(delegate);
+ }
+
+ }
+
+ private final <xsl:value-of select="$ClassName"/> _<xsl:value-of select="$name"/>Class = new <xsl:value-of select="$ClassName"/>();
+
+ public interface <xsl:value-of select="@name"/>Delegate extends QMFObject.Delegate
+ {<xsl:apply-templates select="node()[name()='property']" mode="propertyGetter"/>
+ <xsl:apply-templates select="node()[name()='statistic']" mode="propertyGetter"/>
+ <xsl:apply-templates select="node()[name()='method']" mode="methodDefinition"><xsl:with-param name="qmfClass" select="@name"/><xsl:with-param name="delegate">Y</xsl:with-param></xsl:apply-templates>
+ }
+
+ public final class <xsl:value-of select="@name"/>Object extends QMFObject<xsl:text disable-output-escaping="yes">&lt;</xsl:text><xsl:value-of select="$ClassName"/>, <xsl:value-of select="@name"/>Delegate<xsl:text disable-output-escaping="yes">&gt;</xsl:text>
+ {
+ protected <xsl:value-of select="@name"/>Object(<xsl:value-of select="@name"/>Delegate delegate)
+ {
+ super(delegate);
+ }
+
+ public <xsl:value-of select="@name"/>Class getQMFClass()
+ {
+ return _<xsl:value-of select="$name"/>Class;
+ }
+
+ public QMFCommand asConfigInfoCmd(long sampleTime)
+ {
+ return new QMF<xsl:value-of select="@name"/>ConfigInfoCommand(this,sampleTime);
+ }
+
+ public QMFCommand asInstrumentInfoCmd(long sampleTime)
+ {
+ return new QMF<xsl:value-of select="@name"/>InstrumentInfoCommand(this,sampleTime);
+ }
+
+ public QMFCommand asGetQueryResponseCmd(QMFGetQueryCommand queryCommand, long sampleTime)
+ {
+ return new QMF<xsl:value-of select="@name"/>GetQueryResponseCommand(this,queryCommand,sampleTime);
+ }
+
+
+ <xsl:apply-templates select="node()[name()='method']" mode="methodDefinition"><xsl:with-param name="qmfClass" select="@name"/></xsl:apply-templates>
+
+ <xsl:apply-templates select="node()[name()='property']" mode="propertyDelegation"/>
+ <xsl:apply-templates select="node()[name()='statistic']" mode="propertyDelegation"/>
+ }
+
+ public final class QMF<xsl:value-of select="@name"/>ConfigInfoCommand extends QMFConfigInfoCommand<xsl:text disable-output-escaping="yes">&lt;</xsl:text><xsl:value-of select="@name"/>Object<xsl:text disable-output-escaping="yes">&gt;</xsl:text>
+ {
+
+ protected QMF<xsl:value-of select="@name"/>ConfigInfoCommand(<xsl:value-of select="@name"/>Object object, long sampleTime)
+ {
+ super(object, sampleTime);
+ }
+
+ @Override
+ public void encode(final BBEncoder encoder)
+ {
+ super.encode(encoder);
+ <xsl:apply-templates select="node()[name()='property']" mode="optionalPropertyPresence"/>
+ <xsl:apply-templates select="node()[name()='property']" mode="encodeProperty"/>
+ }
+ }
+
+ public final class QMF<xsl:value-of select="@name"/>InstrumentInfoCommand extends QMFInstrumentInfoCommand<xsl:text disable-output-escaping="yes">&lt;</xsl:text><xsl:value-of select="@name"/>Object<xsl:text disable-output-escaping="yes">&gt;</xsl:text>
+ {
+
+ protected QMF<xsl:value-of select="@name"/>InstrumentInfoCommand(<xsl:value-of select="@name"/>Object object, long sampleTime)
+ {
+ super(object, sampleTime);
+ }
+
+ @Override
+ public void encode(final BBEncoder encoder)
+ {
+ super.encode(encoder);
+ <xsl:apply-templates select="node()[name()='statistic']" mode="optionalPropertyPresence"><xsl:with-param name="type">statistic</xsl:with-param></xsl:apply-templates>
+ <xsl:apply-templates select="node()[name()='statistic']" mode="encodeProperty"/>
+ }
+ }
+
+ public final class QMF<xsl:value-of select="@name"/>GetQueryResponseCommand extends QMFGetQueryResponseCommand<xsl:text disable-output-escaping="yes">&lt;</xsl:text><xsl:value-of select="@name"/>Object<xsl:text disable-output-escaping="yes">&gt;</xsl:text>
+ {
+
+ protected QMF<xsl:value-of select="@name"/>GetQueryResponseCommand(<xsl:value-of select="@name"/>Object object, QMFGetQueryCommand cmd, long sampleTime)
+ {
+ super(object, cmd, sampleTime);
+ }
+
+ @Override
+ public void encode(final BBEncoder encoder)
+ {
+ super.encode(encoder);
+ <xsl:apply-templates select="node()[name()='property' or name()='statistic']" mode="optionalPropertyPresence"/>
+ <xsl:apply-templates select="node()[name()='property' or name()='statistic']" mode="encodeProperty"/>
+ }
+ }
+
+
+
+
+</xsl:template>
+
+ <xsl:template match="node()[attribute::optional]" mode="optionalPropertyPresence">
+ <xsl:param name="type">property</xsl:param>
+ <xsl:variable name="var">presence<xsl:value-of select="floor(count(preceding-sibling::node()[name()=$type and attribute::optional]) div 8)"/></xsl:variable>
+ <xsl:if test="count(preceding-sibling::node()[name()=$type and attribute::optional]) mod 8 = 0">
+ byte <xsl:value-of select="$var"/> = (byte) 0;
+ </xsl:if>
+ if( getObject().get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>() != null )
+ {
+ <xsl:value-of select="$var"/> |= (1 <xsl:text disable-output-escaping="yes">&lt;&lt;</xsl:text> <xsl:value-of select="count(preceding-sibling::node()[name()=$type and attribute::optional])"/>);
+ }
+ <xsl:if test="count(preceding-sibling::node()[name()=$type and attribute::optional]) mod 8 = 7 or count(following-sibling::node()[name()=$type and attribute::optional]) = 0">
+ encoder.writeUint8( <xsl:value-of select="$var"/> );
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template match="node()" mode="propertyGetter"><xsl:text>
+ </xsl:text><xsl:choose>
+
+ <xsl:when test="@type='hilo32'">
+ <xsl:call-template name="javaType"><xsl:with-param name="type">count32</xsl:with-param><xsl:with-param name="referenceType" select="@references"/></xsl:call-template> get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>();<xsl:text>
+ </xsl:text><xsl:call-template name="javaType"><xsl:with-param name="type">count32</xsl:with-param><xsl:with-param name="referenceType" select="@references"/></xsl:call-template> get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>High();<xsl:text>
+ </xsl:text><xsl:call-template name="javaType"><xsl:with-param name="type">count32</xsl:with-param><xsl:with-param name="referenceType" select="@references"/></xsl:call-template> get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>Low();</xsl:when>
+
+ <xsl:when test="@type='mmaTime'">
+ <xsl:call-template name="javaType"><xsl:with-param name="type">deltaTime</xsl:with-param><xsl:with-param name="referenceType" select="@references"/></xsl:call-template> get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>Samples();<xsl:text>
+ </xsl:text><xsl:call-template name="javaType"><xsl:with-param name="type">deltaTime</xsl:with-param><xsl:with-param name="referenceType" select="@references"/></xsl:call-template> get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>Min();<xsl:text>
+ </xsl:text><xsl:call-template name="javaType"><xsl:with-param name="type">deltaTime</xsl:with-param><xsl:with-param name="referenceType" select="@references"/></xsl:call-template> get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>Max();<xsl:text>
+ </xsl:text><xsl:call-template name="javaType"><xsl:with-param name="type">deltaTime</xsl:with-param><xsl:with-param name="referenceType" select="@references"/></xsl:call-template> get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>Average();</xsl:when>
+
+ <xsl:otherwise><xsl:call-template name="javaType"><xsl:with-param name="type" select="@type"/><xsl:with-param name="referenceType" select="@references"/></xsl:call-template> get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>();</xsl:otherwise>
+ </xsl:choose></xsl:template>
+
+
+ <xsl:template match="node()" mode="propertyDelegation"><xsl:text>
+ </xsl:text><xsl:choose>
+ <xsl:when test="@type='hilo32'">
+ public <xsl:call-template name="javaType"><xsl:with-param name="type">count32</xsl:with-param><xsl:with-param name="referenceType" select="@references"/></xsl:call-template> get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>()
+ {
+ return getDelegate().get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>();
+ }
+
+ public <xsl:call-template name="javaType"><xsl:with-param name="type">count32</xsl:with-param><xsl:with-param name="referenceType" select="@references"/></xsl:call-template> get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/>High</xsl:with-param></xsl:call-template>()
+ {
+ return getDelegate().get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/>High</xsl:with-param></xsl:call-template>();
+ }
+
+ public <xsl:call-template name="javaType"><xsl:with-param name="type">count32</xsl:with-param><xsl:with-param name="referenceType" select="@references"/></xsl:call-template> get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/>Low</xsl:with-param></xsl:call-template>()
+ {
+ return getDelegate().get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/>Low</xsl:with-param></xsl:call-template>();
+ }
+
+ </xsl:when>
+ <xsl:when test="@type='mmaTime'">
+ public <xsl:call-template name="javaType"><xsl:with-param name="type">deltaTime</xsl:with-param><xsl:with-param name="referenceType" select="@references"/></xsl:call-template> get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/>Samples</xsl:with-param></xsl:call-template>()
+ {
+ return getDelegate().get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/>Samples</xsl:with-param></xsl:call-template>();
+ }
+
+ public <xsl:call-template name="javaType"><xsl:with-param name="type">deltaTime</xsl:with-param><xsl:with-param name="referenceType" select="@references"/></xsl:call-template> get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/>Min</xsl:with-param></xsl:call-template>()
+ {
+ return getDelegate().get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/>Min</xsl:with-param></xsl:call-template>();
+ }
+
+ public <xsl:call-template name="javaType"><xsl:with-param name="type">deltaTime</xsl:with-param><xsl:with-param name="referenceType" select="@references"/></xsl:call-template> get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/>Max</xsl:with-param></xsl:call-template>()
+ {
+ return getDelegate().get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/>Max</xsl:with-param></xsl:call-template>();
+ }
+
+ public <xsl:call-template name="javaType"><xsl:with-param name="type">deltaTime</xsl:with-param><xsl:with-param name="referenceType" select="@references"/></xsl:call-template> get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/>Average</xsl:with-param></xsl:call-template>()
+ {
+ return getDelegate().get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/>Average</xsl:with-param></xsl:call-template>();
+ }
+
+ </xsl:when>
+ <xsl:otherwise>
+ public <xsl:call-template name="javaType"><xsl:with-param name="type" select="@type"/><xsl:with-param name="referenceType" select="@references"/></xsl:call-template> get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>()
+ {
+ return getDelegate().get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>();
+ }
+
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="node()" mode="encodeProperty">
+ <xsl:variable name="prop">getObject().get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>()</xsl:variable>
+ <xsl:choose>
+ <xsl:when test="@optional">
+ if(<xsl:value-of select="$prop"/> != null)
+ {
+ encoder.<xsl:call-template name="encoderWrite"><xsl:with-param name="var" select="$prop"/><xsl:with-param name="type" select="@type"/></xsl:call-template>;
+ }
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test="@type='hilo32'"><xsl:text>
+ </xsl:text>encoder.<xsl:call-template name="encoderWrite"><xsl:with-param name="var" select="$prop"/><xsl:with-param name="type">count32</xsl:with-param></xsl:call-template>;<xsl:text>
+ </xsl:text>encoder.<xsl:call-template name="encoderWrite"><xsl:with-param name="var">getObject().get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>High()</xsl:with-param><xsl:with-param name="type">count32</xsl:with-param></xsl:call-template>;<xsl:text>
+ </xsl:text>encoder.<xsl:call-template name="encoderWrite"><xsl:with-param name="var">getObject().get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>Low()</xsl:with-param><xsl:with-param name="type">count32</xsl:with-param></xsl:call-template>;
+ </xsl:when>
+
+ <xsl:when test="@type='mmaTime'"><xsl:text>
+ </xsl:text>encoder.<xsl:call-template name="encoderWrite"><xsl:with-param name="var">getObject().get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>Samples()</xsl:with-param><xsl:with-param name="type">deltaTime</xsl:with-param></xsl:call-template>;<xsl:text>
+ </xsl:text>encoder.<xsl:call-template name="encoderWrite"><xsl:with-param name="var">getObject().get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>Min()</xsl:with-param><xsl:with-param name="type">deltaTime</xsl:with-param></xsl:call-template>;<xsl:text>
+ </xsl:text>encoder.<xsl:call-template name="encoderWrite"><xsl:with-param name="var">getObject().get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>Max()</xsl:with-param><xsl:with-param name="type">deltaTime</xsl:with-param></xsl:call-template>;<xsl:text>
+ </xsl:text>encoder.<xsl:call-template name="encoderWrite"><xsl:with-param name="var">getObject().get<xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>Average()</xsl:with-param><xsl:with-param name="type">deltaTime</xsl:with-param></xsl:call-template>;
+ </xsl:when>
+
+ <xsl:otherwise><xsl:text>
+ </xsl:text>encoder.<xsl:call-template name="encoderWrite"><xsl:with-param name="var" select="$prop"/><xsl:with-param name="type" select="@type"/></xsl:call-template>;
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+
+
+ </xsl:template>
+
+ <xsl:template match="node()[name()='property']" mode="property">
+ <xsl:variable name="ClassName"><xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>Property</xsl:variable>
+ public class <xsl:value-of select="$ClassName"/> extends QMFProperty
+ {
+
+ private <xsl:value-of select="$ClassName"/>()
+ {
+ super( "<xsl:value-of select="@name"/>",
+ QMFType.<xsl:call-template name="qmfType"><xsl:with-param name="type" select="@type"></xsl:with-param></xsl:call-template>,
+ QMFProperty.AccessCode.<xsl:call-template name="toUpper"><xsl:with-param name="input" select="@access"></xsl:with-param></xsl:call-template>,
+ <xsl:choose><xsl:when test="@index='y'">true</xsl:when><xsl:otherwise>false</xsl:otherwise></xsl:choose>,
+ <xsl:choose><xsl:when test="@optional='y'">true</xsl:when><xsl:otherwise>false</xsl:otherwise></xsl:choose>);
+<xsl:if test="@desc">
+ setDescription("<xsl:value-of select="@desc"/>");
+</xsl:if>
+<xsl:if test="@min">
+ setMin(<xsl:value-of select="@min"/>);
+</xsl:if>
+<xsl:if test="@max">
+ setMin(<xsl:value-of select="@max"/>);
+</xsl:if>
+<xsl:if test="@references">
+ setReferencedClass("<xsl:call-template name="initLower"><xsl:with-param name="input"><xsl:value-of select="@references"/></xsl:with-param></xsl:call-template>");
+</xsl:if>
+
+ <xsl:if test="@unit">
+ setUnit("<xsl:value-of select="@unit"/>");
+ </xsl:if>
+ }
+ }
+
+ private final <xsl:value-of select="$ClassName"/> _<xsl:call-template name="initLower"><xsl:with-param name="input" select="@name"/></xsl:call-template>Property = new <xsl:value-of select="$ClassName"/>();
+ </xsl:template>
+
+ <xsl:template match="node()[name()='statistic']" mode="statistic">
+ <xsl:choose>
+ <xsl:when test="@type='hilo32'">
+ <xsl:call-template name="statdef"><xsl:with-param name="name" select="@name"/><xsl:with-param name="type">uint32</xsl:with-param><xsl:with-param name="unit" select="@unit"/><xsl:with-param name="desc" select="@desc"/></xsl:call-template>
+ <xsl:call-template name="statdef"><xsl:with-param name="name"><xsl:value-of select="@name"/>High</xsl:with-param><xsl:with-param name="type">uint32</xsl:with-param><xsl:with-param name="unit" select="@unit"/><xsl:with-param name="desc"><xsl:value-of select="@desc"/> (High)</xsl:with-param></xsl:call-template>
+ <xsl:call-template name="statdef"><xsl:with-param name="name"><xsl:value-of select="@name"/>Low</xsl:with-param><xsl:with-param name="type">uint32</xsl:with-param><xsl:with-param name="unit" select="@unit"/><xsl:with-param name="desc"><xsl:value-of select="@desc"/> (Low)</xsl:with-param></xsl:call-template>
+ </xsl:when>
+ <xsl:when test="@type='mmaTime'">
+ <xsl:call-template name="statdef"><xsl:with-param name="name"><xsl:value-of select="@name"/>Samples</xsl:with-param><xsl:with-param name="type">deltaTime</xsl:with-param><xsl:with-param name="unit" select="@unit"/><xsl:with-param name="desc"><xsl:value-of select="@desc"/> (Samples)</xsl:with-param></xsl:call-template>
+ <xsl:call-template name="statdef"><xsl:with-param name="name"><xsl:value-of select="@name"/>Max</xsl:with-param><xsl:with-param name="type">deltaTime</xsl:with-param><xsl:with-param name="unit" select="@unit"/><xsl:with-param name="desc"><xsl:value-of select="@desc"/> (Max)</xsl:with-param></xsl:call-template>
+ <xsl:call-template name="statdef"><xsl:with-param name="name"><xsl:value-of select="@name"/>Min</xsl:with-param><xsl:with-param name="type">deltaTime</xsl:with-param><xsl:with-param name="unit" select="@unit"/><xsl:with-param name="desc"><xsl:value-of select="@desc"/> (Min)</xsl:with-param></xsl:call-template>
+ <xsl:call-template name="statdef"><xsl:with-param name="name"><xsl:value-of select="@name"/>Average</xsl:with-param><xsl:with-param name="type">deltaTime</xsl:with-param><xsl:with-param name="unit" select="@unit"/><xsl:with-param name="desc"><xsl:value-of select="@desc"/> (Average)</xsl:with-param></xsl:call-template>
+ </xsl:when>
+
+ <xsl:otherwise><xsl:call-template name="statdef"><xsl:with-param name="name" select="@name"/><xsl:with-param name="type" select="@type"/><xsl:with-param name="unit" select="@unit"/><xsl:with-param name="desc" select="@desc"/></xsl:call-template></xsl:otherwise>
+ </xsl:choose>
+
+ </xsl:template>
+
+ <xsl:template name="statdef">
+ <xsl:param name="name"/>
+ <xsl:param name="type"/>
+ <xsl:param name="unit"/>
+ <xsl:param name="desc"/>
+ <xsl:variable name="ClassName"><xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="$name"/></xsl:with-param></xsl:call-template>Statistic</xsl:variable>
+ public class <xsl:value-of select="$ClassName"/> extends QMFStatistic
+ {
+
+ private <xsl:value-of select="$ClassName"/>()
+ {
+ super( "<xsl:value-of select="$name"/>", QMFType.<xsl:call-template name="qmfType"><xsl:with-param name="type" select="$type"></xsl:with-param></xsl:call-template>, <xsl:choose>
+ <xsl:when test="$unit">"<xsl:value-of select="$unit"/>"</xsl:when>
+ <xsl:otherwise>null</xsl:otherwise>
+ </xsl:choose>, <xsl:choose>
+ <xsl:when test="$desc">"<xsl:value-of select="$desc"/>"</xsl:when>
+ <xsl:otherwise>null</xsl:otherwise>
+ </xsl:choose>);
+ }
+ }
+
+ private final <xsl:value-of select="$ClassName"/> _<xsl:call-template name="initLower"><xsl:with-param name="input" select="$name"/></xsl:call-template>Statistic = new <xsl:value-of select="$ClassName"/>();
+ </xsl:template>
+
+
+ <xsl:template match="node()[name()='method']" mode="method">
+ <xsl:param name="qmfClass"/>
+ <xsl:variable name="ClassName"><xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>Method</xsl:variable>
+ public class <xsl:value-of select="$ClassName"/> extends QMFMethod<xsl:text disable-output-escaping="yes">&lt;</xsl:text><xsl:value-of select="$qmfClass"/>Object<xsl:text disable-output-escaping="yes">&gt;</xsl:text>
+ {
+ private <xsl:value-of select="$ClassName"/>()
+ {
+ super( "<xsl:value-of select="@name"/>", <xsl:choose>
+ <xsl:when test="@desc">"<xsl:value-of select="@desc"/>"</xsl:when>
+ <xsl:otherwise>null</xsl:otherwise>
+</xsl:choose>);
+
+ <xsl:apply-templates select="node()[name()='arg']" mode="argument"/>
+
+ }
+
+
+ public <xsl:value-of select="$ClassName"/>Invocation parse(BBDecoder decoder)
+ {
+ <xsl:apply-templates select="node()[name()='arg' and ( @dir='I' or @dir='IO' ) ]" mode="decodeArg"/>
+ return new <xsl:value-of select="$ClassName"/>Invocation(<xsl:apply-templates select="node()[name()='arg' and ( @dir='I' or @dir='IO' ) ]" mode="methodArgList"/>);
+ }
+ }
+
+ private final <xsl:value-of select="$ClassName"/> _<xsl:call-template name="initLower"><xsl:with-param name="input" select="@name"/></xsl:call-template>Method = new <xsl:value-of select="$ClassName"/>();
+
+ private class <xsl:value-of select="$ClassName"/>Invocation implements QMFMethodInvocation<xsl:text disable-output-escaping="yes">&lt;</xsl:text><xsl:value-of select="$qmfClass"/>Object<xsl:text disable-output-escaping="yes">&gt;</xsl:text>
+ {
+ <xsl:apply-templates select="node()[name()='arg' and ( @dir='I' or @dir='IO' ) ]" mode="methodInputArgDecl"/>
+
+ private <xsl:value-of select="$ClassName"/>Invocation(<xsl:apply-templates select="node()[name()='arg' and ( @dir='I' or @dir='IO' ) ]" mode="methodArgList"><xsl:with-param name="includeType">yes</xsl:with-param></xsl:apply-templates>)
+ {
+ <xsl:apply-templates select="node()[name()='arg' and ( @dir='I' or @dir='IO' ) ]" mode="methodInputArgAssign"/>
+ }
+
+ public QMFMethodResponseCommand execute(<xsl:value-of select="$qmfClass"/>Object obj, QMFMethodRequestCommand cmd)
+ {
+ return obj.<xsl:value-of select="@name"/>( new <xsl:value-of select="$ClassName"/>ResponseCommandFactory(cmd)<xsl:if test="node()[name()='arg' and ( @dir='I' or @dir='IO' ) ]">, </xsl:if><xsl:apply-templates select="node()[name()='arg' and ( @dir='I' or @dir='IO' ) ]" mode="methodArgList"><xsl:with-param name="prefix">_</xsl:with-param></xsl:apply-templates> );
+ }
+ }
+
+ public final class <xsl:value-of select="$ClassName"/>ResponseCommandFactory
+ {
+ private final QMFMethodRequestCommand _requestCmd;
+ private <xsl:value-of select="$ClassName"/>ResponseCommandFactory(QMFMethodRequestCommand cmd)
+ {
+ _requestCmd = cmd;
+ }
+
+ public <xsl:value-of select="$ClassName"/>ResponseCommand createResponseCommand( <xsl:apply-templates select="node()[name()='arg' and ( @dir='O' or @dir='IO' ) ]" mode="methodArgList"><xsl:with-param name="includeType">yes</xsl:with-param><xsl:with-param name="direction">O</xsl:with-param></xsl:apply-templates> )
+ {
+ return new <xsl:value-of select="$ClassName"/>ResponseCommand(_requestCmd<xsl:if test="node()[name()='arg' and ( @dir='O' or @dir='IO' ) ]">, <xsl:apply-templates select="node()[name()='arg' and ( @dir='O' or @dir='IO' ) ]" mode="methodArgList"><xsl:with-param name="direction">O</xsl:with-param></xsl:apply-templates></xsl:if>);
+ }
+ }
+
+ public final class <xsl:value-of select="$ClassName"/>ResponseCommand extends QMFMethodResponseCommand
+ {
+ <xsl:apply-templates select="node()[name()='arg' and ( @dir='O' or @dir='IO' ) ]" mode="methodInputArgDecl"/>
+ private <xsl:value-of select="$ClassName"/>ResponseCommand(QMFMethodRequestCommand cmd<xsl:if test="node()[name()='arg' and ( @dir='O' or @dir='IO' ) ]">, <xsl:apply-templates select="node()[name()='arg' and ( @dir='O' or @dir='IO' ) ]" mode="methodArgList"><xsl:with-param name="includeType">yes</xsl:with-param><xsl:with-param name="direction">O</xsl:with-param></xsl:apply-templates></xsl:if>)
+ {
+ super(cmd);
+
+ <xsl:apply-templates select="node()[name()='arg' and ( @dir='O' or @dir='IO' ) ]" mode="methodInputArgAssign"/>
+ }
+
+ @Override
+ public void encode(final BBEncoder encoder)
+ {
+ super.encode(encoder);
+
+ <xsl:apply-templates select="node()[name()='arg' and ( @dir='O' or @dir='IO' ) ]" mode="encodeArg"/>
+ }
+ }
+
+ </xsl:template>
+ <xsl:template match="node()[name()='method']" mode="methodDefinition"><xsl:param name="qmfClass"/><xsl:param name="delegate">N</xsl:param>
+ <xsl:variable name="ClassName"><xsl:call-template name="initCap"><xsl:with-param name="input"><xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>Method</xsl:variable><xsl:text>
+ </xsl:text><xsl:if test="$delegate='N'">public </xsl:if><xsl:value-of select="$qmfClass"/>Class.<xsl:value-of select="$ClassName"/>ResponseCommand <xsl:call-template name="initLower"><xsl:with-param name="input" select="@name"/></xsl:call-template>(<xsl:value-of select="$qmfClass"/>Class.<xsl:value-of select="$ClassName"/>ResponseCommandFactory factory<xsl:if test="node()[name()='arg' and ( @dir='I' or @dir='IO' ) ]">, <xsl:apply-templates select="node()[name()='arg' and ( @dir='I' or @dir='IO' ) ]" mode="methodArgList"><xsl:with-param name="includeType">yes</xsl:with-param></xsl:apply-templates> </xsl:if>)<xsl:if test="$delegate='N'">
+ {
+ return getDelegate().<xsl:call-template name="initLower"><xsl:with-param name="input" select="@name"/></xsl:call-template>(factory<xsl:if test="node()[name()='arg' and ( @dir='I' or @dir='IO' ) ]">, <xsl:apply-templates select="node()[name()='arg' and ( @dir='I' or @dir='IO' ) ]" mode="methodArgList"/></xsl:if> );
+ }
+ </xsl:if><xsl:if test="$delegate='Y'">;</xsl:if>
+ </xsl:template>
+ <xsl:template match="node()[name()='arg']" mode="argument">
+ QMFMethod.Argument <xsl:value-of select="@name"/> = new QMFMethod.Argument("<xsl:value-of select="@name"/>", QMFType.<xsl:call-template name="qmfType"><xsl:with-param name="type" select="@type"/></xsl:call-template>);
+<xsl:if test="@desc">
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="@name"/>.setDescription("<xsl:value-of select="@desc" disable-output-escaping="yes"/>");
+</xsl:if>
+<xsl:if test="@dir">
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="@name"/>.setDirection(QMFMethod.Direction.<xsl:value-of select="@dir"/>); </xsl:if>
+ addArgument( <xsl:value-of select="@name"/> );
+ </xsl:template>
+ <xsl:template match="node()[name()='arg']" mode="decodeArg">
+ <xsl:call-template name="javaType"><xsl:with-param name="type" select="@type"></xsl:with-param></xsl:call-template><xsl:text> </xsl:text><xsl:value-of select="@name"/> = decoder.<xsl:call-template name="decoderRead"><xsl:with-param name="type" select="@type"/></xsl:call-template>;
+ </xsl:template>
+ <xsl:template match="node()[name()='arg']" mode="encodeArg">
+ encoder.<xsl:call-template name="encoderWrite"><xsl:with-param name="type" select="@type"/><xsl:with-param name="var">_<xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>;
+ </xsl:template>
+ <xsl:template match="node()[name()='arg']" mode="methodArgList"><xsl:param name="includeType"/><xsl:param name="direction">I</xsl:param><xsl:param name="prefix"></xsl:param>
+ <xsl:if test="$includeType"><xsl:call-template name="javaType"><xsl:with-param name="type" select="@type"/></xsl:call-template></xsl:if><xsl:text> </xsl:text><xsl:value-of select="$prefix"/><xsl:value-of select="@name"/><xsl:if test="following-sibling::node()[name()='arg' and ( @dir=$direction or @dir='IO' ) ]">, </xsl:if>
+ </xsl:template>
+ <xsl:template match="node()[name()='arg']" mode="methodInputArgDecl">
+ private final <xsl:call-template name="javaType"><xsl:with-param name="type" select="@type"/></xsl:call-template> _<xsl:value-of select="@name"/>;
+ </xsl:template>
+ <xsl:template match="node()[name()='arg']" mode="methodInputArgAssign">
+ _<xsl:value-of select="@name"/> = <xsl:value-of select="@name"/>;
+ </xsl:template>
+
+ <xsl:template match="node()[name()='class']" mode="classList">_<xsl:call-template name="initLower"><xsl:with-param name="input" select="@name"/></xsl:call-template>Class<xsl:if test="following-sibling::node()[name()='class']">, </xsl:if></xsl:template>
+ <xsl:template match="node()[name()='event']" mode="eventList">_<xsl:call-template name="initLower"><xsl:with-param name="input" select="@name"/></xsl:call-template>EventClass<xsl:if test="following-sibling::node()[name()='event']">, </xsl:if></xsl:template>
+ <xsl:template match="node()[name()='property']" mode="propertyList">_<xsl:call-template name="initLower"><xsl:with-param name="input" select="@name"/></xsl:call-template>Property<xsl:if test="following-sibling::node()[name()='property']">, </xsl:if></xsl:template>
+ <xsl:template match="node()[name()='statistic']" mode="statisticList"><xsl:variable name="field">_<xsl:call-template name="initLower"><xsl:with-param name="input" select="@name"/></xsl:call-template></xsl:variable><xsl:choose><xsl:when test="@type!='mmaTime'"><xsl:value-of select="$field"/>Statistic<xsl:if test="@type='hilo32'">, <xsl:value-of select="$field"/>HighStatistic, <xsl:value-of select="$field"/>LowStatistic</xsl:if></xsl:when><xsl:otherwise><xsl:value-of select="$field"/>SamplesStatistic, <xsl:value-of select="$field"/>MaxStatistic, <xsl:value-of select="$field"/>MinStatistic, <xsl:value-of select="$field"/>AverageStatistic</xsl:otherwise></xsl:choose><xsl:if test="following-sibling::node()[name()='statistic']">, </xsl:if></xsl:template>
+ <xsl:template match="node()[name()='method']" mode="methodList">_<xsl:call-template name="initLower"><xsl:with-param name="input" select="@name"/></xsl:call-template>Method<xsl:if test="following-sibling::node()[name()='method']">, </xsl:if></xsl:template>
+
+
+ <xsl:template match="node()[name()='event']" mode="event">
+ <xsl:variable name="ClassName"><xsl:call-template name="initCap"><xsl:with-param name="input" select="@name"/></xsl:call-template>EventClass</xsl:variable>
+ <xsl:variable name="cmdName"><xsl:call-template name="initCap"><xsl:with-param name="input" select="@name"/></xsl:call-template>Event</xsl:variable>
+ <xsl:variable name="name"><xsl:call-template name="initLower"><xsl:with-param name="input" select="@name"/></xsl:call-template></xsl:variable>
+
+ <xsl:variable name="argsList"><xsl:call-template name="argList"><xsl:with-param name="args" select="@args"></xsl:with-param></xsl:call-template></xsl:variable>
+
+ public class <xsl:value-of select="$ClassName"/> extends QMFEventClass
+ {
+<!-- <xsl:apply-templates select="node()[name()='property']" mode="property"/> -->
+
+ <xsl:apply-templates select="preceding-sibling::node()[name()='eventArguments']" mode="eventArg"><xsl:with-param name="args" select="@args"/></xsl:apply-templates>
+
+ private <xsl:value-of select="$ClassName"/>()
+ {
+ super("<xsl:value-of select="$name"/>",
+ new byte[16]);
+
+ setProperties( Arrays.asList( new QMFProperty[] { <xsl:value-of select="$argsList"/> } ) );
+ }
+
+ public QMFEventSeverity getSeverity()
+ {
+ return QMFEventSeverity.<xsl:call-template name="severity"><xsl:with-param name="severity" select="@sev"/></xsl:call-template>;
+ }
+
+ public QMFEventCommand<xsl:text disable-output-escaping="yes">&lt;</xsl:text><xsl:value-of select="$ClassName"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text> newEvent(<xsl:apply-templates select="preceding-sibling::node()[name()='eventArguments']" mode="eventArg"><xsl:with-param name="args" select="@args"/><xsl:with-param name="tmpl">argParamList</xsl:with-param><xsl:with-param name="separator">, </xsl:with-param></xsl:apply-templates>)
+ {
+ return new <xsl:value-of select="$cmdName"/>(<xsl:apply-templates select="preceding-sibling::node()[name()='eventArguments']" mode="eventArg"><xsl:with-param name="args" select="@args"/><xsl:with-param name="tmpl">argList</xsl:with-param><xsl:with-param name="separator">, </xsl:with-param></xsl:apply-templates>);
+ }
+
+
+
+ }
+
+ private final <xsl:value-of select="$ClassName"/> _<xsl:value-of select="$name"/>EventClass = new <xsl:value-of select="$ClassName"/>();
+
+ private final class <xsl:value-of select="$cmdName"/> extends QMFEventCommand<xsl:text disable-output-escaping="yes">&lt;</xsl:text><xsl:value-of select="$ClassName"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>
+ {
+ <xsl:apply-templates select="preceding-sibling::node()[name()='eventArguments']" mode="eventArg"><xsl:with-param name="args" select="@args"/><xsl:with-param name="tmpl">argMemberDef</xsl:with-param></xsl:apply-templates>
+
+ private <xsl:value-of select="$cmdName"/>(<xsl:apply-templates select="preceding-sibling::node()[name()='eventArguments']" mode="eventArg"><xsl:with-param name="args" select="@args"/><xsl:with-param name="tmpl">argParamList</xsl:with-param><xsl:with-param name="separator">, </xsl:with-param></xsl:apply-templates>)
+ {
+ <xsl:apply-templates select="preceding-sibling::node()[name()='eventArguments']" mode="eventArg"><xsl:with-param name="args" select="@args"/><xsl:with-param name="tmpl">argMemberAssign</xsl:with-param></xsl:apply-templates>
+ }
+
+ public <xsl:value-of select="$ClassName"/> getEventClass()
+ {
+ return _<xsl:value-of select="$name"/>EventClass;
+ }
+
+ public void encode(final BBEncoder encoder)
+ {
+ super.encode(encoder);
+ <xsl:apply-templates select="preceding-sibling::node()[name()='eventArguments']" mode="eventArg"><xsl:with-param name="args" select="@args"/><xsl:with-param name="tmpl">argEncode</xsl:with-param><xsl:with-param name="separator"><xsl:text>
+ </xsl:text></xsl:with-param></xsl:apply-templates>
+
+ }
+ }
+ </xsl:template>
+
+ <xsl:template name="eventArguments" mode="eventArg" match="node()[name()='eventArguments']">
+ <xsl:param name="args"></xsl:param>
+ <xsl:param name="tmpl">propertyClass</xsl:param>
+ <xsl:param name="separator"></xsl:param>
+ <xsl:variable name="arg"><xsl:choose>
+ <xsl:when test="contains($args,',')"><xsl:value-of select="normalize-space(substring-before($args,','))"/></xsl:when>
+ <xsl:otherwise><xsl:value-of select="$args"/></xsl:otherwise>
+ </xsl:choose></xsl:variable>
+ <xsl:variable name="tail" select="normalize-space(substring-after($args,','))"></xsl:variable>
+ <xsl:if test="string-length($arg)>0">
+ <xsl:apply-templates mode="eventArg" select="node()[name()='arg' and @name=$arg]"><xsl:with-param name="tmpl" select="$tmpl"/></xsl:apply-templates>
+ </xsl:if>
+ <xsl:if test="string-length($tail)>0"><xsl:value-of select="$separator"/><xsl:apply-templates select="." mode="eventArg"><xsl:with-param name="args" select="$tail"/><xsl:with-param name="tmpl" select="$tmpl"/><xsl:with-param name="separator" select="$separator"/></xsl:apply-templates></xsl:if>
+ </xsl:template>
+
+ <xsl:template mode="eventArg" match="node()[name()='arg']">
+ <xsl:param name="tmpl"/>
+ <xsl:choose>
+ <xsl:when test="$tmpl='propertyClass'"><xsl:apply-templates mode="propertyClass" select="."/></xsl:when>
+ </xsl:choose>
+ <xsl:choose>
+ <xsl:when test="$tmpl='argParamList'"><xsl:apply-templates mode="argParamList" select="."/></xsl:when>
+ </xsl:choose>
+ <xsl:choose>
+ <xsl:when test="$tmpl='argList'"><xsl:apply-templates mode="argList" select="."/></xsl:when>
+ </xsl:choose>
+ <xsl:choose>
+ <xsl:when test="$tmpl='argMemberDef'"><xsl:apply-templates mode="argMemberDef" select="."/></xsl:when>
+ </xsl:choose>
+ <xsl:choose>
+ <xsl:when test="$tmpl='argMemberAssign'"><xsl:apply-templates mode="argMemberAssign" select="."/></xsl:when>
+ </xsl:choose>
+ <xsl:choose>
+ <xsl:when test="$tmpl='argEncode'"><xsl:apply-templates mode="argEncode" select="."/></xsl:when>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="arg" mode="propertyClass" match="node()[name()='arg']">
+<xsl:variable name="propClassName"><xsl:call-template name="initCap"><xsl:with-param name="input" select="@name"/></xsl:call-template>Arg</xsl:variable>
+ public class <xsl:value-of select="$propClassName"/> extends QMFProperty
+ {
+ private <xsl:value-of select="$propClassName"/>()
+ {
+ super( "<xsl:value-of select="@name"/>",
+ QMFType.<xsl:call-template name="qmfType"><xsl:with-param name="type" select="@type"></xsl:with-param></xsl:call-template>,
+ QMFProperty.AccessCode.RO,false,false);
+
+ <xsl:if test="@desc">
+ setDescription("<xsl:value-of select="@desc"/>");
+ </xsl:if>
+ }
+ }
+
+ private final <xsl:value-of select="$propClassName"/> _<xsl:value-of select="@name"/>Arg = new <xsl:value-of select="$propClassName"/>();
+ </xsl:template>
+
+ <xsl:template mode="argMemberDef" match="node()[name()='arg']"><xsl:text>
+ private final </xsl:text><xsl:call-template name="javaType"><xsl:with-param name="type" select="@type"></xsl:with-param></xsl:call-template><xsl:text> _</xsl:text><xsl:value-of select="@name"/>;</xsl:template>
+ <xsl:template mode="argParamList" match="node()[name()='arg']"><xsl:call-template name="javaType"><xsl:with-param name="type" select="@type"/></xsl:call-template><xsl:text> </xsl:text><xsl:value-of select="@name"/></xsl:template>
+ <xsl:template mode="argList" match="node()[name()='arg']"><xsl:value-of select="@name"/></xsl:template>
+ <xsl:template mode="argMemberAssign" match="node()[name()='arg']"><xsl:text>
+ _</xsl:text><xsl:value-of select="@name"/> = <xsl:value-of select="@name"/>;</xsl:template>
+ <xsl:template mode="argEncode" match="node()[name()='arg']">encoder.<xsl:call-template name="encoderWrite"><xsl:with-param name="type" select="@type"/><xsl:with-param name="var">_<xsl:value-of select="@name"/></xsl:with-param></xsl:call-template>;</xsl:template>
+
+ <xsl:template name="argList">
+ <xsl:param name="args"/>
+ <xsl:variable name="arg"><xsl:choose>
+ <xsl:when test="contains($args,',')"><xsl:value-of select="normalize-space(substring-before($args,','))"/></xsl:when>
+ <xsl:otherwise><xsl:value-of select="$args"/></xsl:otherwise>
+ </xsl:choose></xsl:variable>
+ <xsl:variable name="tail" select="normalize-space(substring-after($args,','))"></xsl:variable>
+ <xsl:if test="string-length($arg)>0">_<xsl:value-of select="$arg"/>Arg</xsl:if>
+ <xsl:if test="string-length($tail)>0">, <xsl:call-template name="argList"><xsl:with-param name="args" select="$tail"/></xsl:call-template></xsl:if>
+ </xsl:template>
+
+
+ <xsl:template name="qmfType"><xsl:param name="type"/>
+<xsl:choose><xsl:when test="$type='absTime'">ABSTIME</xsl:when>
+<xsl:when test="$type='bool'">BOOLEAN</xsl:when>
+<xsl:when test="$type='map'">MAP</xsl:when>
+<xsl:when test="$type='objId'">OBJECTREFERENCE</xsl:when>
+<xsl:when test="$type='sstr'">STR8</xsl:when>
+<xsl:when test="$type='lstr'">STR16</xsl:when>
+<xsl:when test="$type='uint16'">UINT16</xsl:when>
+<xsl:when test="$type='uint32'">UINT32</xsl:when>
+<xsl:when test="$type='uuid'">UUID</xsl:when>
+<xsl:when test="$type='deltaTime'">DELTATIME</xsl:when>
+<xsl:when test="$type='count32'">UINT32</xsl:when>
+<xsl:when test="$type='count64'">UINT64</xsl:when>
+ <xsl:otherwise><xsl:value-of select="$type"/></xsl:otherwise>
+</xsl:choose>
+</xsl:template>
+
+
+ <xsl:template name="javaType"><xsl:param name="type"/><xsl:param name="referenceType">UUID</xsl:param>
+ <xsl:choose><xsl:when test="$type='absTime'">Long</xsl:when>
+ <xsl:when test="$type='bool'">Boolean</xsl:when>
+ <xsl:when test="$type='map'">Map</xsl:when>
+ <xsl:when test="$type='objId'"><xsl:value-of select="$referenceType"/>Object</xsl:when>
+ <xsl:when test="$type='sstr'">String</xsl:when>
+ <xsl:when test="$type='lstr'">String</xsl:when>
+ <xsl:when test="$type='uint16'">Integer</xsl:when>
+ <xsl:when test="$type='uint32'">Long</xsl:when>
+ <xsl:when test="$type='uuid'">UUID</xsl:when>
+ <xsl:when test="$type='deltaTime'">Long</xsl:when>
+ <xsl:when test="$type='count32'">Long</xsl:when>
+ <xsl:when test="$type='count64'">Long</xsl:when>
+ <xsl:otherwise><xsl:value-of select="$type"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="encoderWrite"><xsl:param name="type"/><xsl:param name="var"/>
+ <xsl:choose><xsl:when test="$type='absTime'">writeUint64( <xsl:value-of select="$var"/> )</xsl:when>
+ <xsl:when test="$type='bool'">writeInt8( <xsl:value-of select="$var"/> ? (byte) -1 : (byte) 0)</xsl:when>
+ <xsl:when test="$type='map'">writeMap( <xsl:value-of select="$var"/> )</xsl:when>
+ <xsl:when test="$type='objId'">writeBin128( <xsl:value-of select="$var"/>.getId() )</xsl:when>
+ <xsl:when test="$type='sstr'">writeStr8( <xsl:value-of select="$var"/> )</xsl:when>
+ <xsl:when test="$type='lstr'">writeStr16( <xsl:value-of select="$var"/> )</xsl:when>
+ <xsl:when test="$type='uint16'">writeUint16( <xsl:value-of select="$var"/> )</xsl:when>
+ <xsl:when test="$type='uint32'">writeUint32( <xsl:value-of select="$var"/> )</xsl:when>
+ <xsl:when test="$type='uuid'">writeUuid( <xsl:value-of select="$var"/> )</xsl:when>
+ <xsl:when test="$type='deltaTime'">writeUint64( <xsl:value-of select="$var"/> )</xsl:when>
+ <xsl:when test="$type='count32'">writeUint32( <xsl:value-of select="$var"/> )</xsl:when>
+ <xsl:when test="$type='count64'">writeUint64( <xsl:value-of select="$var"/> )</xsl:when>
+ <xsl:otherwise><xsl:value-of select="$type"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="decoderRead"><xsl:param name="type"/>
+ <xsl:choose><xsl:when test="$type='absTime'">readUint64()</xsl:when>
+ <xsl:when test="$type='bool'">readInt8() != 0</xsl:when>
+ <xsl:when test="$type='map'">readMap()</xsl:when>
+ <xsl:when test="$type='objId'">readBin128()</xsl:when>
+ <xsl:when test="$type='sstr'">readStr8()</xsl:when>
+ <xsl:when test="$type='lstr'">readStr16()</xsl:when>
+ <xsl:when test="$type='uint16'">readUint16()</xsl:when>
+ <xsl:when test="$type='uint32'">readUint32()</xsl:when>
+ <xsl:when test="$type='uuid'">readUuid()</xsl:when>
+ <xsl:when test="$type='deltaTime'">readUint64()</xsl:when>
+ <xsl:when test="$type='count32'">readUint32()</xsl:when>
+ <xsl:when test="$type='count64'">readUint64()</xsl:when>
+ <xsl:otherwise><xsl:value-of select="$type"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+
+<xsl:template name="severity">
+ <xsl:param name="severity"/>
+ <xsl:choose>
+ <xsl:when test="$severity='emerg'">EMERGENCY</xsl:when>
+ <xsl:when test="$severity='alert'">ALERT</xsl:when>
+ <xsl:when test="$severity='crit'">CRITICAL</xsl:when>
+ <xsl:when test="$severity='error'">ERROR</xsl:when>
+ <xsl:when test="$severity='warn'">WARN</xsl:when>
+ <xsl:when test="$severity='notice'">NOTICE</xsl:when>
+ <xsl:when test="$severity='inform'">INFORM</xsl:when>
+ <xsl:when test="$severity='debug'">DEBUG</xsl:when>
+ </xsl:choose>
+
+</xsl:template>
+
+<xsl:template name="substringAfterLast"><xsl:param name="input"/><xsl:param name="arg"/>
+<xsl:choose>
+ <xsl:when test="contains($input,$arg)"><xsl:call-template name="substringAfterLast"><xsl:with-param name="input"><xsl:value-of select="substring-after($input,$arg)"/></xsl:with-param><xsl:with-param name="arg"><xsl:value-of select="$arg"/></xsl:with-param></xsl:call-template></xsl:when>
+ <xsl:otherwise><xsl:value-of select="$input"/></xsl:otherwise>
+</xsl:choose>
+</xsl:template>
+<xsl:template name="initCap"><xsl:param name="input"/><xsl:value-of select="translate(substring($input,1,1),'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/><xsl:value-of select="substring($input,2)"/></xsl:template>
+<xsl:template name="initLower"><xsl:param name="input"/><xsl:value-of select="translate(substring($input,1,1),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')"/><xsl:value-of select="substring($input,2)"/></xsl:template>
+<xsl:template name="toUpper"><xsl:param name="input"/><xsl:value-of select="translate($input,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/></xsl:template>
+</xsl:stylesheet>