From 10f23aca8dab83f51cb4fce341dc7fef7dac44b9 Mon Sep 17 00:00:00 2001 From: "Rafael H. Schloming" Date: Tue, 29 Jul 2008 19:03:34 +0000 Subject: QPID-1072: renamed org.apache.qpidity -> org.apache.qpid git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@680803 13f79535-47bb-0310-9956-ffa450edef68 --- java/client/build.xml | 2 +- .../example/amqpexample/direct/DeclareQueue.java | 6 +- .../example/amqpexample/direct/DirectProducer.java | 16 +- .../qpid/example/amqpexample/direct/Listener.java | 16 +- .../example/amqpexample/fanout/DeclareQueue.java | 6 +- .../amqpexample/fanout/FannoutProducer.java | 12 +- .../qpid/example/amqpexample/fanout/Listener.java | 20 +- .../example/amqpexample/pubsub/TopicListener.java | 16 +- .../example/amqpexample/pubsub/TopicPublisher.java | 12 +- java/client/pom.xml | 8 +- java/client/src/main/grammar/SelectorParser.jj | 20 +- java/client/src/main/java/client.log4j | 5 - .../qpid/client/AMQConnectionDelegate_0_10.java | 12 +- .../org/apache/qpid/client/AMQSession_0_10.java | 32 +- .../qpid/client/BasicMessageConsumer_0_10.java | 16 +- .../qpid/client/BasicMessageProducer_0_10.java | 16 +- .../org/apache/qpid/client/XAResourceImpl.java | 26 +- .../java/org/apache/qpid/client/XASessionImpl.java | 8 +- .../qpid/client/message/AbstractJMSMessage.java | 6 +- .../client/message/AbstractJMSMessageFactory.java | 6 +- .../apache/qpid/client/message/MessageFactory.java | 2 +- .../client/message/MessageFactoryRegistry.java | 6 +- .../client/message/UnprocessedMessage_0_10.java | 4 +- .../apache/qpid/filter/ArithmeticExpression.java | 268 +++++++++ .../org/apache/qpid/filter/BinaryExpression.java | 103 ++++ .../org/apache/qpid/filter/BooleanExpression.java | 33 ++ .../apache/qpid/filter/ComparisonExpression.java | 589 ++++++++++++++++++++ .../org/apache/qpid/filter/ConstantExpression.java | 204 +++++++ .../java/org/apache/qpid/filter/Expression.java | 34 ++ .../org/apache/qpid/filter/JMSSelectorFilter.java | 70 +++ .../org/apache/qpid/filter/LogicExpression.java | 108 ++++ .../java/org/apache/qpid/filter/MessageFilter.java | 27 + .../org/apache/qpid/filter/PropertyExpression.java | 303 ++++++++++ .../org/apache/qpid/filter/UnaryExpression.java | 321 +++++++++++ .../java/org/apache/qpid/jms/BrokerDetails.java | 2 +- .../org/apache/qpid/naming/ReadOnlyContext.java | 509 +++++++++++++++++ .../java/org/apache/qpid/naming/jndi.properties | 40 ++ .../main/java/org/apache/qpid/nclient/Client.java | 294 ++++++++++ .../org/apache/qpid/nclient/ClosedListener.java | 39 ++ .../java/org/apache/qpid/nclient/Connection.java | 86 +++ .../java/org/apache/qpid/nclient/DtxSession.java | 137 +++++ .../java/org/apache/qpid/nclient/JMSTestCase.java | 115 ++++ .../apache/qpid/nclient/MessagePartListener.java | 63 +++ .../main/java/org/apache/qpid/nclient/Session.java | 595 ++++++++++++++++++++ .../apache/qpid/nclient/impl/ClientSession.java | 206 +++++++ .../qpid/nclient/impl/ClientSessionDelegate.java | 75 +++ .../org/apache/qpid/nclient/impl/Constants.java | 78 +++ .../org/apache/qpid/nclient/impl/DemoClient.java | 94 ++++ .../qpid/nclient/impl/LargeMsgDemoClient.java | 76 +++ .../qpid/nclient/interop/BasicInteropTest.java | 156 ++++++ .../qpid/nclient/util/ByteBufferMessage.java | 160 ++++++ .../org/apache/qpid/nclient/util/FileMessage.java | 96 ++++ .../apache/qpid/nclient/util/MessageListener.java | 34 ++ .../nclient/util/MessagePartListenerAdapter.java | 59 ++ .../apache/qpid/nclient/util/ReadOnlyMessage.java | 38 ++ .../apache/qpid/nclient/util/StreamingMessage.java | 68 +++ .../java/org/apache/qpid/njms/ExceptionHelper.java | 60 ++ .../qpidity/filter/ArithmeticExpression.java | 268 --------- .../apache/qpidity/filter/BinaryExpression.java | 103 ---- .../apache/qpidity/filter/BooleanExpression.java | 33 -- .../qpidity/filter/ComparisonExpression.java | 589 -------------------- .../apache/qpidity/filter/ConstantExpression.java | 204 ------- .../java/org/apache/qpidity/filter/Expression.java | 34 -- .../apache/qpidity/filter/JMSSelectorFilter.java | 70 --- .../org/apache/qpidity/filter/LogicExpression.java | 108 ---- .../org/apache/qpidity/filter/MessageFilter.java | 27 - .../apache/qpidity/filter/PropertyExpression.java | 303 ---------- .../org/apache/qpidity/filter/UnaryExpression.java | 321 ----------- .../org/apache/qpidity/naming/ReadOnlyContext.java | 509 ----------------- .../java/org/apache/qpidity/naming/jndi.properties | 40 -- .../java/org/apache/qpidity/nclient/Client.java | 294 ---------- .../org/apache/qpidity/nclient/ClosedListener.java | 39 -- .../org/apache/qpidity/nclient/Connection.java | 86 --- .../org/apache/qpidity/nclient/DtxSession.java | 137 ----- .../org/apache/qpidity/nclient/JMSTestCase.java | 115 ---- .../qpidity/nclient/MessagePartListener.java | 63 --- .../java/org/apache/qpidity/nclient/Session.java | 595 -------------------- .../apache/qpidity/nclient/impl/ClientSession.java | 206 ------- .../nclient/impl/ClientSessionDelegate.java | 75 --- .../org/apache/qpidity/nclient/impl/Constants.java | 78 --- .../apache/qpidity/nclient/impl/DemoClient.java | 94 ---- .../qpidity/nclient/impl/LargeMsgDemoClient.java | 76 --- .../qpidity/nclient/interop/BasicInteropTest.java | 156 ------ .../qpidity/nclient/util/ByteBufferMessage.java | 160 ------ .../apache/qpidity/nclient/util/FileMessage.java | 96 ---- .../qpidity/nclient/util/MessageListener.java | 34 -- .../nclient/util/MessagePartListenerAdapter.java | 59 -- .../qpidity/nclient/util/ReadOnlyMessage.java | 38 -- .../qpidity/nclient/util/StreamingMessage.java | 68 --- .../org/apache/qpidity/njms/ExceptionHelper.java | 60 -- java/common/Composite.tpl | 12 +- java/common/Constant.tpl | 2 +- java/common/Enum.tpl | 2 +- java/common/Invoker.tpl | 2 +- java/common/MethodDelegate.tpl | 2 +- java/common/Option.tpl | 2 +- java/common/StructFactory.tpl | 2 +- java/common/Type.tpl | 2 +- java/common/codegen | 2 +- java/common/pom.xml | 2 +- java/common/src/main/java/log4j.properties | 2 - .../main/java/org/apache/qpid/BrokerDetails.java | 138 +++++ .../java/org/apache/qpid/BrokerDetailsImpl.java | 264 +++++++++ .../main/java/org/apache/qpid/ConsoleOutput.java | 54 ++ .../src/main/java/org/apache/qpid/ErrorCode.java | 102 ++++ .../src/main/java/org/apache/qpid/QpidConfig.java | 90 +++ .../main/java/org/apache/qpid/QpidException.java | 58 ++ .../main/java/org/apache/qpid/SecurityHelper.java | 71 +++ .../src/main/java/org/apache/qpid/ToyBroker.java | 286 ++++++++++ .../src/main/java/org/apache/qpid/ToyClient.java | 133 +++++ .../src/main/java/org/apache/qpid/ToyExchange.java | 132 +++++ .../src/main/java/org/apache/qpid/api/Message.java | 126 +++++ .../src/main/java/org/apache/qpid/dtx/XidImpl.java | 250 +++++++++ .../apache/qpid/security/AMQPCallbackHandler.java | 28 + .../qpid/security/CallbackHandlerRegistry.java | 94 ++++ .../apache/qpid/security/DynamicSaslRegistrar.java | 74 +++ .../java/org/apache/qpid/security/JCAProvider.java | 44 ++ .../security/UsernamePasswordCallbackHandler.java | 60 ++ .../qpid/security/amqplain/AmqPlainSaslClient.java | 105 ++++ .../amqplain/AmqPlainSaslClientFactory.java | 62 +++ .../java/org/apache/qpid/transport/Binary.java | 129 +++++ .../java/org/apache/qpid/transport/Binding.java | 36 ++ .../java/org/apache/qpid/transport/Channel.java | 233 ++++++++ .../org/apache/qpid/transport/ChannelDelegate.java | 54 ++ .../org/apache/qpid/transport/ClientDelegate.java | 40 ++ .../java/org/apache/qpid/transport/Connection.java | 175 ++++++ .../apache/qpid/transport/ConnectionDelegate.java | 281 ++++++++++ .../main/java/org/apache/qpid/transport/Data.java | 98 ++++ .../main/java/org/apache/qpid/transport/Echo.java | 84 +++ .../main/java/org/apache/qpid/transport/Field.java | 83 +++ .../java/org/apache/qpid/transport/Future.java | 37 ++ .../java/org/apache/qpid/transport/Header.java | 123 ++++ .../java/org/apache/qpid/transport/Method.java | 141 +++++ .../apache/qpid/transport/ProtocolDelegate.java | 44 ++ .../org/apache/qpid/transport/ProtocolError.java | 83 +++ .../org/apache/qpid/transport/ProtocolEvent.java | 40 ++ .../org/apache/qpid/transport/ProtocolHeader.java | 116 ++++ .../qpid/transport/ProtocolVersionException.java | 52 ++ .../main/java/org/apache/qpid/transport/Range.java | 125 +++++ .../java/org/apache/qpid/transport/RangeSet.java | 142 +++++ .../java/org/apache/qpid/transport/Receiver.java | 38 ++ .../java/org/apache/qpid/transport/Result.java | 30 + .../java/org/apache/qpid/transport/Sender.java | 38 ++ .../java/org/apache/qpid/transport/Session.java | 558 +++++++++++++++++++ .../org/apache/qpid/transport/SessionDelegate.java | 129 +++++ .../apache/qpid/transport/SessionException.java | 46 ++ .../java/org/apache/qpid/transport/Struct.java | 142 +++++ .../apache/qpid/transport/TransportException.java | 46 ++ .../qpid/transport/codec/AbstractDecoder.java | 470 ++++++++++++++++ .../qpid/transport/codec/AbstractEncoder.java | 620 +++++++++++++++++++++ .../org/apache/qpid/transport/codec/BBDecoder.java | 96 ++++ .../org/apache/qpid/transport/codec/BBEncoder.java | 227 ++++++++ .../org/apache/qpid/transport/codec/Decoder.java | 68 +++ .../org/apache/qpid/transport/codec/Encodable.java | 37 ++ .../org/apache/qpid/transport/codec/Encoder.java | 66 +++ .../org/apache/qpid/transport/codec/Validator.java | 177 ++++++ .../apache/qpid/transport/network/Assembler.java | 219 ++++++++ .../qpid/transport/network/Disassembler.java | 217 ++++++++ .../org/apache/qpid/transport/network/Frame.java | 151 +++++ .../qpid/transport/network/InputHandler.java | 204 +++++++ .../qpid/transport/network/NetworkDelegate.java | 42 ++ .../qpid/transport/network/NetworkEvent.java | 34 ++ .../qpid/transport/network/OutputHandler.java | 125 +++++ .../qpid/transport/network/io/IoReceiver.java | 106 ++++ .../apache/qpid/transport/network/io/IoSender.java | 262 +++++++++ .../qpid/transport/network/io/IoTransport.java | 129 +++++ .../qpid/transport/network/mina/MinaHandler.java | 305 ++++++++++ .../qpid/transport/network/mina/MinaSender.java | 81 +++ .../qpid/transport/network/nio/NioHandler.java | 120 ++++ .../qpid/transport/network/nio/NioSender.java | 100 ++++ .../org/apache/qpid/transport/util/Functions.java | 91 +++ .../org/apache/qpid/transport/util/Logger.java | 125 +++++ .../apache/qpid/transport/util/SliceIterator.java | 59 ++ .../java/org/apache/qpid/url/BindingURLImpl.java | 2 +- .../src/main/java/org/apache/qpid/url/QpidURL.java | 2 +- .../main/java/org/apache/qpid/url/QpidURLImpl.java | 4 +- .../java/org/apache/qpidity/BrokerDetails.java | 138 ----- .../java/org/apache/qpidity/BrokerDetailsImpl.java | 264 --------- .../java/org/apache/qpidity/ConsoleOutput.java | 54 -- .../main/java/org/apache/qpidity/ErrorCode.java | 102 ---- .../main/java/org/apache/qpidity/QpidConfig.java | 90 --- .../java/org/apache/qpidity/QpidException.java | 58 -- .../java/org/apache/qpidity/SecurityHelper.java | 71 --- .../main/java/org/apache/qpidity/ToyBroker.java | 286 ---------- .../main/java/org/apache/qpidity/ToyClient.java | 133 ----- .../main/java/org/apache/qpidity/ToyExchange.java | 132 ----- .../main/java/org/apache/qpidity/api/Message.java | 126 ----- .../main/java/org/apache/qpidity/dtx/XidImpl.java | 250 --------- .../apache/qpidity/exchange/ExchangeDefaults.java | 51 -- .../qpidity/security/AMQPCallbackHandler.java | 28 - .../qpidity/security/CallbackHandlerRegistry.java | 94 ---- .../qpidity/security/DynamicSaslRegistrar.java | 74 --- .../org/apache/qpidity/security/JCAProvider.java | 44 -- .../security/UsernamePasswordCallbackHandler.java | 60 -- .../security/amqplain/AmqPlainSaslClient.java | 105 ---- .../amqplain/AmqPlainSaslClientFactory.java | 62 --- .../java/org/apache/qpidity/transport/Binary.java | 129 ----- .../java/org/apache/qpidity/transport/Binding.java | 36 -- .../java/org/apache/qpidity/transport/Channel.java | 233 -------- .../apache/qpidity/transport/ChannelDelegate.java | 54 -- .../apache/qpidity/transport/ClientDelegate.java | 40 -- .../org/apache/qpidity/transport/Connection.java | 175 ------ .../qpidity/transport/ConnectionDelegate.java | 281 ---------- .../java/org/apache/qpidity/transport/Data.java | 98 ---- .../java/org/apache/qpidity/transport/Echo.java | 84 --- .../java/org/apache/qpidity/transport/Field.java | 83 --- .../java/org/apache/qpidity/transport/Future.java | 37 -- .../java/org/apache/qpidity/transport/Header.java | 123 ---- .../java/org/apache/qpidity/transport/Method.java | 141 ----- .../apache/qpidity/transport/ProtocolDelegate.java | 44 -- .../apache/qpidity/transport/ProtocolError.java | 83 --- .../apache/qpidity/transport/ProtocolEvent.java | 40 -- .../apache/qpidity/transport/ProtocolHeader.java | 116 ---- .../transport/ProtocolVersionException.java | 52 -- .../java/org/apache/qpidity/transport/Range.java | 125 ----- .../org/apache/qpidity/transport/RangeSet.java | 142 ----- .../org/apache/qpidity/transport/Receiver.java | 38 -- .../java/org/apache/qpidity/transport/Result.java | 30 - .../java/org/apache/qpidity/transport/Sender.java | 38 -- .../java/org/apache/qpidity/transport/Session.java | 558 ------------------- .../apache/qpidity/transport/SessionDelegate.java | 129 ----- .../apache/qpidity/transport/SessionException.java | 46 -- .../java/org/apache/qpidity/transport/Struct.java | 142 ----- .../qpidity/transport/TransportException.java | 46 -- .../qpidity/transport/codec/AbstractDecoder.java | 470 ---------------- .../qpidity/transport/codec/AbstractEncoder.java | 620 --------------------- .../apache/qpidity/transport/codec/BBDecoder.java | 96 ---- .../apache/qpidity/transport/codec/BBEncoder.java | 227 -------- .../apache/qpidity/transport/codec/Decoder.java | 68 --- .../apache/qpidity/transport/codec/Encodable.java | 37 -- .../apache/qpidity/transport/codec/Encoder.java | 66 --- .../apache/qpidity/transport/codec/Validator.java | 177 ------ .../qpidity/transport/network/Assembler.java | 219 -------- .../qpidity/transport/network/Disassembler.java | 217 -------- .../apache/qpidity/transport/network/Frame.java | 151 ----- .../qpidity/transport/network/InputHandler.java | 204 ------- .../qpidity/transport/network/NetworkDelegate.java | 42 -- .../qpidity/transport/network/NetworkEvent.java | 34 -- .../qpidity/transport/network/OutputHandler.java | 125 ----- .../qpidity/transport/network/io/IoReceiver.java | 106 ---- .../qpidity/transport/network/io/IoSender.java | 262 --------- .../qpidity/transport/network/io/IoTransport.java | 129 ----- .../transport/network/mina/MinaHandler.java | 305 ---------- .../qpidity/transport/network/mina/MinaSender.java | 81 --- .../qpidity/transport/network/nio/NioHandler.java | 120 ---- .../qpidity/transport/network/nio/NioSender.java | 100 ---- .../apache/qpidity/transport/util/Functions.java | 91 --- .../org/apache/qpidity/transport/util/Logger.java | 125 ----- .../qpidity/transport/util/SliceIterator.java | 59 -- .../org/apache/qpid/transport/ConnectionTest.java | 118 ++++ .../org/apache/qpid/transport/RangeSetTest.java | 238 ++++++++ .../apache/qpidity/transport/ConnectionTest.java | 118 ---- .../org/apache/qpidity/transport/RangeSetTest.java | 238 -------- java/log4j-test.xml | 4 - .../client/connection/ConnectionCloseTest.java | 2 +- .../qpid/test/unit/xa/AbstractXATestCase.java | 2 +- java/testkit/etc/test.log4j | 3 - 257 files changed, 15095 insertions(+), 15160 deletions(-) create mode 100644 java/client/src/main/java/org/apache/qpid/filter/ArithmeticExpression.java create mode 100644 java/client/src/main/java/org/apache/qpid/filter/BinaryExpression.java create mode 100644 java/client/src/main/java/org/apache/qpid/filter/BooleanExpression.java create mode 100644 java/client/src/main/java/org/apache/qpid/filter/ComparisonExpression.java create mode 100644 java/client/src/main/java/org/apache/qpid/filter/ConstantExpression.java create mode 100644 java/client/src/main/java/org/apache/qpid/filter/Expression.java create mode 100644 java/client/src/main/java/org/apache/qpid/filter/JMSSelectorFilter.java create mode 100644 java/client/src/main/java/org/apache/qpid/filter/LogicExpression.java create mode 100644 java/client/src/main/java/org/apache/qpid/filter/MessageFilter.java create mode 100644 java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java create mode 100644 java/client/src/main/java/org/apache/qpid/filter/UnaryExpression.java create mode 100644 java/client/src/main/java/org/apache/qpid/naming/ReadOnlyContext.java create mode 100644 java/client/src/main/java/org/apache/qpid/naming/jndi.properties create mode 100644 java/client/src/main/java/org/apache/qpid/nclient/Client.java create mode 100644 java/client/src/main/java/org/apache/qpid/nclient/ClosedListener.java create mode 100644 java/client/src/main/java/org/apache/qpid/nclient/Connection.java create mode 100644 java/client/src/main/java/org/apache/qpid/nclient/DtxSession.java create mode 100644 java/client/src/main/java/org/apache/qpid/nclient/JMSTestCase.java create mode 100644 java/client/src/main/java/org/apache/qpid/nclient/MessagePartListener.java create mode 100644 java/client/src/main/java/org/apache/qpid/nclient/Session.java create mode 100644 java/client/src/main/java/org/apache/qpid/nclient/impl/ClientSession.java create mode 100644 java/client/src/main/java/org/apache/qpid/nclient/impl/ClientSessionDelegate.java create mode 100644 java/client/src/main/java/org/apache/qpid/nclient/impl/Constants.java create mode 100644 java/client/src/main/java/org/apache/qpid/nclient/impl/DemoClient.java create mode 100644 java/client/src/main/java/org/apache/qpid/nclient/impl/LargeMsgDemoClient.java create mode 100644 java/client/src/main/java/org/apache/qpid/nclient/interop/BasicInteropTest.java create mode 100644 java/client/src/main/java/org/apache/qpid/nclient/util/ByteBufferMessage.java create mode 100644 java/client/src/main/java/org/apache/qpid/nclient/util/FileMessage.java create mode 100644 java/client/src/main/java/org/apache/qpid/nclient/util/MessageListener.java create mode 100644 java/client/src/main/java/org/apache/qpid/nclient/util/MessagePartListenerAdapter.java create mode 100644 java/client/src/main/java/org/apache/qpid/nclient/util/ReadOnlyMessage.java create mode 100644 java/client/src/main/java/org/apache/qpid/nclient/util/StreamingMessage.java create mode 100644 java/client/src/main/java/org/apache/qpid/njms/ExceptionHelper.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/filter/ArithmeticExpression.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/filter/BinaryExpression.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/filter/BooleanExpression.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/filter/ComparisonExpression.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/filter/ConstantExpression.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/filter/Expression.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/filter/JMSSelectorFilter.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/filter/LogicExpression.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/filter/MessageFilter.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/filter/PropertyExpression.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/filter/UnaryExpression.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/naming/ReadOnlyContext.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/naming/jndi.properties delete mode 100644 java/client/src/main/java/org/apache/qpidity/nclient/Client.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/nclient/ClosedListener.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/nclient/Connection.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/nclient/DtxSession.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/nclient/JMSTestCase.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/nclient/MessagePartListener.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/nclient/Session.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/nclient/impl/ClientSession.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/nclient/impl/ClientSessionDelegate.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/nclient/impl/Constants.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/nclient/impl/DemoClient.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/nclient/impl/LargeMsgDemoClient.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/nclient/interop/BasicInteropTest.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/nclient/util/ByteBufferMessage.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/nclient/util/FileMessage.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/nclient/util/MessageListener.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/nclient/util/MessagePartListenerAdapter.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/nclient/util/ReadOnlyMessage.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/nclient/util/StreamingMessage.java delete mode 100644 java/client/src/main/java/org/apache/qpidity/njms/ExceptionHelper.java create mode 100644 java/common/src/main/java/org/apache/qpid/BrokerDetails.java create mode 100644 java/common/src/main/java/org/apache/qpid/BrokerDetailsImpl.java create mode 100644 java/common/src/main/java/org/apache/qpid/ConsoleOutput.java create mode 100644 java/common/src/main/java/org/apache/qpid/ErrorCode.java create mode 100644 java/common/src/main/java/org/apache/qpid/QpidConfig.java create mode 100644 java/common/src/main/java/org/apache/qpid/QpidException.java create mode 100644 java/common/src/main/java/org/apache/qpid/SecurityHelper.java create mode 100644 java/common/src/main/java/org/apache/qpid/ToyBroker.java create mode 100644 java/common/src/main/java/org/apache/qpid/ToyClient.java create mode 100644 java/common/src/main/java/org/apache/qpid/ToyExchange.java create mode 100644 java/common/src/main/java/org/apache/qpid/api/Message.java create mode 100644 java/common/src/main/java/org/apache/qpid/dtx/XidImpl.java create mode 100644 java/common/src/main/java/org/apache/qpid/security/AMQPCallbackHandler.java create mode 100644 java/common/src/main/java/org/apache/qpid/security/CallbackHandlerRegistry.java create mode 100644 java/common/src/main/java/org/apache/qpid/security/DynamicSaslRegistrar.java create mode 100644 java/common/src/main/java/org/apache/qpid/security/JCAProvider.java create mode 100644 java/common/src/main/java/org/apache/qpid/security/UsernamePasswordCallbackHandler.java create mode 100644 java/common/src/main/java/org/apache/qpid/security/amqplain/AmqPlainSaslClient.java create mode 100644 java/common/src/main/java/org/apache/qpid/security/amqplain/AmqPlainSaslClientFactory.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/Binary.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/Binding.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/Channel.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/ChannelDelegate.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/ClientDelegate.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/Connection.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/ConnectionDelegate.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/Data.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/Echo.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/Field.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/Future.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/Header.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/Method.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/ProtocolDelegate.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/ProtocolError.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/ProtocolEvent.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/ProtocolHeader.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/ProtocolVersionException.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/Range.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/RangeSet.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/Receiver.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/Result.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/Sender.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/Session.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/SessionDelegate.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/SessionException.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/Struct.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/TransportException.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/codec/AbstractDecoder.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/codec/AbstractEncoder.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/codec/BBDecoder.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/codec/BBEncoder.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/codec/Decoder.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/codec/Encodable.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/codec/Encoder.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/codec/Validator.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/network/Assembler.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/network/Disassembler.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/network/Frame.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/network/InputHandler.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/network/NetworkDelegate.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/network/NetworkEvent.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/network/OutputHandler.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/network/io/IoReceiver.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/network/io/IoSender.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/network/io/IoTransport.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaHandler.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaSender.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/network/nio/NioHandler.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/network/nio/NioSender.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/util/Functions.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/util/Logger.java create mode 100644 java/common/src/main/java/org/apache/qpid/transport/util/SliceIterator.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/BrokerDetails.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/BrokerDetailsImpl.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/ConsoleOutput.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/ErrorCode.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/QpidConfig.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/QpidException.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/SecurityHelper.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/ToyBroker.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/ToyClient.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/ToyExchange.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/api/Message.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/dtx/XidImpl.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/exchange/ExchangeDefaults.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/security/AMQPCallbackHandler.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/security/CallbackHandlerRegistry.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/security/DynamicSaslRegistrar.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/security/JCAProvider.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/security/UsernamePasswordCallbackHandler.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/security/amqplain/AmqPlainSaslClient.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/security/amqplain/AmqPlainSaslClientFactory.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/Binary.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/Binding.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/Channel.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/ChannelDelegate.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/ClientDelegate.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/Connection.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/ConnectionDelegate.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/Data.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/Echo.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/Field.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/Future.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/Header.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/Method.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/ProtocolDelegate.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/ProtocolError.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/ProtocolEvent.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/ProtocolHeader.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/ProtocolVersionException.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/Range.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/RangeSet.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/Receiver.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/Result.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/Sender.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/Session.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/SessionDelegate.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/SessionException.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/Struct.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/TransportException.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractDecoder.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractEncoder.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/codec/BBDecoder.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/codec/BBEncoder.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/codec/Decoder.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/codec/Encodable.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/codec/Encoder.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/codec/Validator.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/network/Assembler.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/network/Disassembler.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/network/Frame.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/network/InputHandler.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/network/NetworkDelegate.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/network/NetworkEvent.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/network/OutputHandler.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/network/io/IoReceiver.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/network/io/IoSender.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/network/io/IoTransport.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/network/mina/MinaHandler.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/network/mina/MinaSender.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/network/nio/NioHandler.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/network/nio/NioSender.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/util/Functions.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/util/Logger.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/transport/util/SliceIterator.java create mode 100644 java/common/src/test/java/org/apache/qpid/transport/ConnectionTest.java create mode 100644 java/common/src/test/java/org/apache/qpid/transport/RangeSetTest.java delete mode 100644 java/common/src/test/java/org/apache/qpidity/transport/ConnectionTest.java delete mode 100644 java/common/src/test/java/org/apache/qpidity/transport/RangeSetTest.java (limited to 'java') diff --git a/java/client/build.xml b/java/client/build.xml index d26064ed15..abeb3ec903 100644 --- a/java/client/build.xml +++ b/java/client/build.xml @@ -24,7 +24,7 @@ - + diff --git a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/DeclareQueue.java b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/DeclareQueue.java index 8bb27847ce..b16a7fa7c3 100755 --- a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/DeclareQueue.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/DeclareQueue.java @@ -1,8 +1,8 @@ package org.apache.qpid.example.amqpexample.direct; -import org.apache.qpidity.nclient.Client; -import org.apache.qpidity.nclient.Connection; -import org.apache.qpidity.nclient.Session; +import org.apache.qpid.nclient.Client; +import org.apache.qpid.nclient.Connection; +import org.apache.qpid.nclient.Session; /** * This creates a queue a queue and binds it to the diff --git a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/DirectProducer.java b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/DirectProducer.java index 7329792a2b..62609182cf 100755 --- a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/DirectProducer.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/DirectProducer.java @@ -2,14 +2,14 @@ package org.apache.qpid.example.amqpexample.direct; import java.nio.ByteBuffer; -import org.apache.qpidity.api.Message; -import org.apache.qpidity.nclient.Client; -import org.apache.qpidity.nclient.Connection; -import org.apache.qpidity.nclient.Session; -import org.apache.qpidity.nclient.util.MessageListener; -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.MessageAcceptMode; -import org.apache.qpidity.transport.MessageAcquireMode; +import org.apache.qpid.api.Message; +import org.apache.qpid.nclient.Client; +import org.apache.qpid.nclient.Connection; +import org.apache.qpid.nclient.Session; +import org.apache.qpid.nclient.util.MessageListener; +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.MessageAcceptMode; +import org.apache.qpid.transport.MessageAcquireMode; public class DirectProducer implements MessageListener { diff --git a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/Listener.java b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/Listener.java index b199c3a69a..081fbf2521 100755 --- a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/Listener.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/Listener.java @@ -2,14 +2,14 @@ package org.apache.qpid.example.amqpexample.direct; import java.nio.ByteBuffer; -import org.apache.qpidity.api.Message; -import org.apache.qpidity.nclient.Client; -import org.apache.qpidity.nclient.Connection; -import org.apache.qpidity.nclient.Session; -import org.apache.qpidity.nclient.util.MessageListener; -import org.apache.qpidity.nclient.util.MessagePartListenerAdapter; - -import org.apache.qpidity.transport.MessageCreditUnit; +import org.apache.qpid.api.Message; +import org.apache.qpid.nclient.Client; +import org.apache.qpid.nclient.Connection; +import org.apache.qpid.nclient.Session; +import org.apache.qpid.nclient.util.MessageListener; +import org.apache.qpid.nclient.util.MessagePartListenerAdapter; + +import org.apache.qpid.transport.MessageCreditUnit; /** * This listens to messages on a queue and terminates diff --git a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/DeclareQueue.java b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/DeclareQueue.java index 67f24148d8..9af5f21e66 100755 --- a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/DeclareQueue.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/DeclareQueue.java @@ -1,8 +1,8 @@ package org.apache.qpid.example.amqpexample.fanout; -import org.apache.qpidity.nclient.Client; -import org.apache.qpidity.nclient.Connection; -import org.apache.qpidity.nclient.Session; +import org.apache.qpid.nclient.Client; +import org.apache.qpid.nclient.Connection; +import org.apache.qpid.nclient.Session; /** * This creates a queue a queue and binds it to the diff --git a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/FannoutProducer.java b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/FannoutProducer.java index 4c647fde36..27540b3d9c 100755 --- a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/FannoutProducer.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/FannoutProducer.java @@ -1,11 +1,11 @@ package org.apache.qpid.example.amqpexample.fanout; -import org.apache.qpidity.nclient.Client; -import org.apache.qpidity.nclient.Connection; -import org.apache.qpidity.nclient.Session; -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.MessageAcceptMode; -import org.apache.qpidity.transport.MessageAcquireMode; +import org.apache.qpid.nclient.Client; +import org.apache.qpid.nclient.Connection; +import org.apache.qpid.nclient.Session; +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.MessageAcceptMode; +import org.apache.qpid.transport.MessageAcquireMode; public class FannoutProducer { diff --git a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/Listener.java b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/Listener.java index 1feb5cfe23..7942ce5ca3 100755 --- a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/Listener.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/Listener.java @@ -2,16 +2,16 @@ package org.apache.qpid.example.amqpexample.fanout; import java.nio.ByteBuffer; -import org.apache.qpidity.api.Message; -import org.apache.qpidity.nclient.Client; -import org.apache.qpidity.nclient.Connection; -import org.apache.qpidity.nclient.Session; -import org.apache.qpidity.nclient.util.MessageListener; -import org.apache.qpidity.nclient.util.MessagePartListenerAdapter; - -import org.apache.qpidity.transport.MessageAcceptMode; -import org.apache.qpidity.transport.MessageAcquireMode; -import org.apache.qpidity.transport.MessageCreditUnit; +import org.apache.qpid.api.Message; +import org.apache.qpid.nclient.Client; +import org.apache.qpid.nclient.Connection; +import org.apache.qpid.nclient.Session; +import org.apache.qpid.nclient.util.MessageListener; +import org.apache.qpid.nclient.util.MessagePartListenerAdapter; + +import org.apache.qpid.transport.MessageAcceptMode; +import org.apache.qpid.transport.MessageAcquireMode; +import org.apache.qpid.transport.MessageCreditUnit; /** * This listens to messages on a queue and terminates diff --git a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicListener.java b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicListener.java index 100dcf52bf..2e4edfbe6f 100755 --- a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicListener.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicListener.java @@ -2,14 +2,14 @@ package org.apache.qpid.example.amqpexample.pubsub; import java.nio.ByteBuffer; -import org.apache.qpidity.api.Message; -import org.apache.qpidity.nclient.Client; -import org.apache.qpidity.nclient.Connection; -import org.apache.qpidity.nclient.Session; -import org.apache.qpidity.nclient.util.MessageListener; -import org.apache.qpidity.nclient.util.MessagePartListenerAdapter; -import org.apache.qpidity.transport.MessageCreditUnit; -import org.apache.qpidity.transport.Option; +import org.apache.qpid.api.Message; +import org.apache.qpid.nclient.Client; +import org.apache.qpid.nclient.Connection; +import org.apache.qpid.nclient.Session; +import org.apache.qpid.nclient.util.MessageListener; +import org.apache.qpid.nclient.util.MessagePartListenerAdapter; +import org.apache.qpid.transport.MessageCreditUnit; +import org.apache.qpid.transport.Option; public class TopicListener implements MessageListener diff --git a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicPublisher.java b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicPublisher.java index c960643504..9808ebba9f 100755 --- a/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicPublisher.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicPublisher.java @@ -1,11 +1,11 @@ package org.apache.qpid.example.amqpexample.pubsub; -import org.apache.qpidity.nclient.Client; -import org.apache.qpidity.nclient.Connection; -import org.apache.qpidity.nclient.Session; -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.MessageAcceptMode; -import org.apache.qpidity.transport.MessageAcquireMode; +import org.apache.qpid.nclient.Client; +import org.apache.qpid.nclient.Connection; +import org.apache.qpid.nclient.Session; +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.MessageAcceptMode; +import org.apache.qpid.transport.MessageAcquireMode; public class TopicPublisher { diff --git a/java/client/pom.xml b/java/client/pom.xml index bcce3e1d3b..2ad41d96cd 100644 --- a/java/client/pom.xml +++ b/java/client/pom.xml @@ -112,7 +112,7 @@ ${basedir}/src/main/grammar ${basedir}/target/generated-sources - org.apache.qpidity.filter.selector + org.apache.qpid.filter.selector javacc @@ -237,16 +237,16 @@ maven-javadoc-plugin - org.apache.qpid.*:org.apache.qpidity.njms:org.apache.qpidity.njms.*:org.apache.qpidity.nclient.impl + org.apache.qpid.*:org.apache.qpid.njms:org.apache.qpid.njms.*:org.apache.qpid.nclient.impl API - org.apache.qpidity.nclient + org.apache.qpid.nclient Utility Package - org.apache.qpidity.nclient.util + org.apache.qpid.nclient.util diff --git a/java/client/src/main/grammar/SelectorParser.jj b/java/client/src/main/grammar/SelectorParser.jj index a72da526ae..b45cf1a487 100644 --- a/java/client/src/main/grammar/SelectorParser.jj +++ b/java/client/src/main/grammar/SelectorParser.jj @@ -61,20 +61,20 @@ PARSER_BEGIN(SelectorParser) * */ -package org.apache.qpidity.filter.selector; +package org.apache.qpid.filter.selector; import java.io.StringReader; import java.util.ArrayList; -import org.apache.qpidity.QpidException; -import org.apache.qpidity.filter.ArithmeticExpression; -import org.apache.qpidity.filter.BooleanExpression; -import org.apache.qpidity.filter.ComparisonExpression; -import org.apache.qpidity.filter.ConstantExpression; -import org.apache.qpidity.filter.Expression; -import org.apache.qpidity.filter.LogicExpression; -import org.apache.qpidity.filter.PropertyExpression; -import org.apache.qpidity.filter.UnaryExpression; +import org.apache.qpid.QpidException; +import org.apache.qpid.filter.ArithmeticExpression; +import org.apache.qpid.filter.BooleanExpression; +import org.apache.qpid.filter.ComparisonExpression; +import org.apache.qpid.filter.ConstantExpression; +import org.apache.qpid.filter.Expression; +import org.apache.qpid.filter.LogicExpression; +import org.apache.qpid.filter.PropertyExpression; +import org.apache.qpid.filter.UnaryExpression; /** * JMS Selector Parser generated by JavaCC diff --git a/java/client/src/main/java/client.log4j b/java/client/src/main/java/client.log4j index a5531bb874..19cc946118 100644 --- a/java/client/src/main/java/client.log4j +++ b/java/client/src/main/java/client.log4j @@ -21,15 +21,10 @@ log4j.rootLogger=${root.logging.level} #log4j.logger.org.apache.qpid=${amqj.logging.level}, console #log4j.additivity.org.apache.qpid=false -#log4j.logger.org.apache.qpidity.transport=TRACE, console log4j.logger.org.apache.qpid=ERROR, console log4j.additivity.org.apache.qpid=false -log4j.logger.org.apache.qpidity=ERROR, console -log4j.additivity.org.apache.qpidity=false - -#log4j.logger.org.apache.qpidity.transport=DEBUG, console #log4j.logger.org.apache.qpid.client.message.AbstractBytesTypedMessage=DEBUG, console log4j.appender.console=org.apache.log4j.ConsoleAppender diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java index ce10553210..a2df2f3cf2 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java @@ -12,11 +12,11 @@ import org.apache.qpid.client.failover.FailoverException; import org.apache.qpid.framing.ProtocolVersion; import org.apache.qpid.jms.BrokerDetails; import org.apache.qpid.jms.Session; -import org.apache.qpidity.nclient.Client; -import org.apache.qpidity.nclient.ClosedListener; -import org.apache.qpidity.ErrorCode; -import org.apache.qpidity.QpidException; -import org.apache.qpidity.transport.ProtocolVersionException; +import org.apache.qpid.nclient.Client; +import org.apache.qpid.nclient.ClosedListener; +import org.apache.qpid.ErrorCode; +import org.apache.qpid.QpidException; +import org.apache.qpid.transport.ProtocolVersionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,7 +35,7 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Closed /** * The QpidConeection instance that is mapped with thie JMS connection. */ - org.apache.qpidity.nclient.Connection _qpidConnection; + org.apache.qpid.nclient.Connection _qpidConnection; //--- constructor public AMQConnectionDelegate_0_10(AMQConnection conn) diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java b/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java index 9dff8e3e7e..cf73bc5089 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java @@ -28,16 +28,16 @@ import org.apache.qpid.client.protocol.AMQProtocolHandler; import org.apache.qpid.client.message.MessageFactoryRegistry; import org.apache.qpid.client.message.FiledTableSupport; import org.apache.qpid.util.Serial; -import org.apache.qpidity.nclient.Session; -import org.apache.qpidity.nclient.util.MessagePartListenerAdapter; -import org.apache.qpidity.ErrorCode; -import org.apache.qpidity.QpidException; -import org.apache.qpidity.transport.MessageCreditUnit; -import org.apache.qpidity.transport.MessageFlowMode; -import org.apache.qpidity.transport.RangeSet; -import org.apache.qpidity.transport.Option; -import org.apache.qpidity.transport.ExchangeBoundResult; -import org.apache.qpidity.transport.Future; +import org.apache.qpid.nclient.Session; +import org.apache.qpid.nclient.util.MessagePartListenerAdapter; +import org.apache.qpid.ErrorCode; +import org.apache.qpid.QpidException; +import org.apache.qpid.transport.MessageCreditUnit; +import org.apache.qpid.transport.MessageFlowMode; +import org.apache.qpid.transport.RangeSet; +import org.apache.qpid.transport.Option; +import org.apache.qpid.transport.ExchangeBoundResult; +import org.apache.qpid.transport.Future; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -71,8 +71,8 @@ public class AMQSession_0_10 extends AMQSession private Object _currentExceptionLock = new Object(); private QpidException _currentException; - // a ref on the qpidity connection - protected org.apache.qpidity.nclient.Connection _qpidConnection; + // a ref on the qpid connection + protected org.apache.qpid.nclient.Connection _qpidConnection; private RangeSet unacked = new RangeSet(); private int unackedCount = 0; @@ -96,7 +96,7 @@ public class AMQSession_0_10 extends AMQSession * @param defaultPrefetchLowMark The number of prefetched messages at which to resume the session. * @param qpidConnection The qpid connection */ - AMQSession_0_10(org.apache.qpidity.nclient.Connection qpidConnection, AMQConnection con, int channelId, + AMQSession_0_10(org.apache.qpid.nclient.Connection qpidConnection, AMQConnection con, int channelId, boolean transacted, int acknowledgeMode, MessageFactoryRegistry messageFactoryRegistry, int defaultPrefetchHighMark, int defaultPrefetchLowMark) { @@ -126,7 +126,7 @@ public class AMQSession_0_10 extends AMQSession * @param defaultPrefetchLow The number of prefetched messages at which to resume the session. * @param qpidConnection The connection */ - AMQSession_0_10(org.apache.qpidity.nclient.Connection qpidConnection, AMQConnection con, int channelId, + AMQSession_0_10(org.apache.qpid.nclient.Connection qpidConnection, AMQConnection con, int channelId, boolean transacted, int acknowledgeMode, int defaultPrefetchHigh, int defaultPrefetchLow) { @@ -594,7 +594,7 @@ public class AMQSession_0_10 extends AMQSession * * @return The associated Qpid Session. */ - protected org.apache.qpidity.nclient.Session getQpidSession() + protected org.apache.qpid.nclient.Session getQpidSession() { return _qpidSession; } @@ -645,7 +645,7 @@ public class AMQSession_0_10 extends AMQSession /** * Lstener for qpid protocol exceptions */ - private class QpidSessionExceptionListener implements org.apache.qpidity.nclient.ClosedListener + private class QpidSessionExceptionListener implements org.apache.qpid.nclient.ClosedListener { public void onClosed(ErrorCode errorCode, String reason, Throwable t) { diff --git a/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java b/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java index 9230225bd5..255b38aa10 100644 --- a/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java +++ b/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java @@ -27,12 +27,12 @@ import org.apache.qpid.AMQException; import org.apache.qpid.jms.*; import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpidity.api.Message; -import org.apache.qpidity.transport.*; -import org.apache.qpidity.transport.Session; -import org.apache.qpidity.QpidException; -import org.apache.qpidity.filter.MessageFilter; -import org.apache.qpidity.filter.JMSSelectorFilter; +import org.apache.qpid.api.Message; +import org.apache.qpid.transport.*; +import org.apache.qpid.transport.Session; +import org.apache.qpid.QpidException; +import org.apache.qpid.filter.MessageFilter; +import org.apache.qpid.filter.JMSSelectorFilter; import javax.jms.InvalidSelectorException; import javax.jms.JMSException; @@ -46,7 +46,7 @@ import java.util.concurrent.atomic.AtomicBoolean; * This is a 0.10 message consumer. */ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer - implements org.apache.qpidity.nclient.util.MessageListener + implements org.apache.qpid.nclient.util.MessageListener { /** @@ -108,7 +108,7 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer')); + ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('=')); + ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('!')); + } + + static class LikeExpression extends UnaryExpression implements BooleanExpression + { + + Pattern likePattern; + + /** + * @param right + */ + public LikeExpression(Expression right, String like, int escape) + { + super(right); + + StringBuffer regexp = new StringBuffer(like.length() * 2); + regexp.append("\\A"); // The beginning of the input + for (int i = 0; i < like.length(); i++) + { + char c = like.charAt(i); + if (escape == (0xFFFF & c)) + { + i++; + if (i >= like.length()) + { + // nothing left to escape... + break; + } + + char t = like.charAt(i); + regexp.append("\\x"); + regexp.append(Integer.toHexString(0xFFFF & t)); + } + else if (c == '%') + { + regexp.append(".*?"); // Do a non-greedy match + } + else if (c == '_') + { + regexp.append("."); // match one + } + else if (ComparisonExpression.REGEXP_CONTROL_CHARS.contains(new Character(c))) + { + regexp.append("\\x"); + regexp.append(Integer.toHexString(0xFFFF & c)); + } + else + { + regexp.append(c); + } + } + + regexp.append("\\z"); // The end of the input + + likePattern = Pattern.compile(regexp.toString(), Pattern.DOTALL); + } + + /** + * org.apache.activemq.filter.UnaryExpression#getExpressionSymbol() + */ + public String getExpressionSymbol() + { + return "LIKE"; + } + + /** + * org.apache.activemq.filter.Expression#evaluate(MessageEvaluationContext) + */ + public Object evaluate(AbstractJMSMessage message) throws QpidException + { + + Object rv = this.getRight().evaluate(message); + + if (rv == null) + { + return null; + } + + if (!(rv instanceof String)) + { + return + Boolean.FALSE; + // throw new RuntimeException("LIKE can only operate on String identifiers. LIKE attemped on: '" + rv.getClass()); + } + + return likePattern.matcher((String) rv).matches() ? Boolean.TRUE : Boolean.FALSE; + } + + public boolean matches(AbstractJMSMessage message) throws QpidException + { + Object object = evaluate(message); + + return (object != null) && (object == Boolean.TRUE); + } + } + + public static BooleanExpression createLike(Expression left, String right, String escape) + { + if ((escape != null) && (escape.length() != 1)) + { + throw new RuntimeException( + "The ESCAPE string litteral is invalid. It can only be one character. Litteral used: " + escape); + } + + int c = -1; + if (escape != null) + { + c = 0xFFFF & escape.charAt(0); + } + + return new LikeExpression(left, right, c); + } + + public static BooleanExpression createNotLike(Expression left, String right, String escape) + { + return UnaryExpression.createNOT(ComparisonExpression.createLike(left, right, escape)); + } + + public static BooleanExpression createInFilter(Expression left, List elements) + { + + if (!(left instanceof PropertyExpression)) + { + throw new RuntimeException("Expected a property for In expression, got: " + left); + } + + return UnaryExpression.createInExpression((PropertyExpression) left, elements, false); + + } + + public static BooleanExpression createNotInFilter(Expression left, List elements) + { + + if (!(left instanceof PropertyExpression)) + { + throw new RuntimeException("Expected a property for In expression, got: " + left); + } + + return UnaryExpression.createInExpression((PropertyExpression) left, elements, true); + + } + + public static BooleanExpression createIsNull(Expression left) + { + return ComparisonExpression.doCreateEqual(left, ConstantExpression.NULL); + } + + public static BooleanExpression createIsNotNull(Expression left) + { + return UnaryExpression.createNOT(ComparisonExpression.doCreateEqual(left, ConstantExpression.NULL)); + } + + public static BooleanExpression createNotEqual(Expression left, Expression right) + { + return UnaryExpression.createNOT(ComparisonExpression.createEqual(left, right)); + } + + public static BooleanExpression createEqual(Expression left, Expression right) + { + ComparisonExpression.checkEqualOperand(left); + ComparisonExpression.checkEqualOperand(right); + ComparisonExpression.checkEqualOperandCompatability(left, right); + + return ComparisonExpression.doCreateEqual(left, right); + } + + private static BooleanExpression doCreateEqual(Expression left, Expression right) + { + return new ComparisonExpression(left, right) + { + + public Object evaluate(AbstractJMSMessage message) throws QpidException + { + Object lv = left.evaluate(message); + Object rv = right.evaluate(message); + + // Iff one of the values is null + if ((lv == null) ^ (rv == null)) + { + return Boolean.FALSE; + } + + if ((lv == rv) || lv.equals(rv)) + { + return Boolean.TRUE; + } + + if ((lv instanceof Comparable) && (rv instanceof Comparable)) + { + return compare((Comparable) lv, (Comparable) rv); + } + + return Boolean.FALSE; + } + + protected boolean asBoolean(int answer) + { + return answer == 0; + } + + public String getExpressionSymbol() + { + return "="; + } + }; + } + + public static BooleanExpression createGreaterThan(final Expression left, final Expression right) + { + ComparisonExpression.checkLessThanOperand(left); + ComparisonExpression.checkLessThanOperand(right); + + return new ComparisonExpression(left, right) + { + protected boolean asBoolean(int answer) + { + return answer > 0; + } + + public String getExpressionSymbol() + { + return ">"; + } + }; + } + + public static BooleanExpression createGreaterThanEqual(final Expression left, final Expression right) + { + ComparisonExpression.checkLessThanOperand(left); + ComparisonExpression.checkLessThanOperand(right); + + return new ComparisonExpression(left, right) + { + protected boolean asBoolean(int answer) + { + return answer >= 0; + } + + public String getExpressionSymbol() + { + return ">="; + } + }; + } + + public static BooleanExpression createLessThan(final Expression left, final Expression right) + { + ComparisonExpression.checkLessThanOperand(left); + ComparisonExpression.checkLessThanOperand(right); + + return new ComparisonExpression(left, right) + { + + protected boolean asBoolean(int answer) + { + return answer < 0; + } + + public String getExpressionSymbol() + { + return "<"; + } + + }; + } + + public static BooleanExpression createLessThanEqual(final Expression left, final Expression right) + { + ComparisonExpression.checkLessThanOperand(left); + ComparisonExpression.checkLessThanOperand(right); + + return new ComparisonExpression(left, right) + { + + protected boolean asBoolean(int answer) + { + return answer <= 0; + } + + public String getExpressionSymbol() + { + return "<="; + } + }; + } + + /** + * Only Numeric expressions can be used in >, >=, < or <= expressions.s + * + * @param expr + */ + public static void checkLessThanOperand(Expression expr) + { + if (expr instanceof ConstantExpression) + { + Object value = ((ConstantExpression) expr).getValue(); + if (value instanceof Number) + { + return; + } + + // Else it's boolean or a String.. + throw new RuntimeException("Value '" + expr + "' cannot be compared."); + } + + if (expr instanceof BooleanExpression) + { + throw new RuntimeException("Value '" + expr + "' cannot be compared."); + } + } + + /** + * Validates that the expression can be used in == or <> expression. + * Cannot not be NULL TRUE or FALSE litterals. + * + * @param expr + */ + public static void checkEqualOperand(Expression expr) + { + if (expr instanceof ConstantExpression) + { + Object value = ((ConstantExpression) expr).getValue(); + if (value == null) + { + throw new RuntimeException("'" + expr + "' cannot be compared."); + } + } + } + + /** + * + * @param left + * @param right + */ + private static void checkEqualOperandCompatability(Expression left, Expression right) + { + if ((left instanceof ConstantExpression) && (right instanceof ConstantExpression)) + { + if ((left instanceof BooleanExpression) && !(right instanceof BooleanExpression)) + { + throw new RuntimeException("'" + left + "' cannot be compared with '" + right + "'"); + } + } + } + + /** + * @param left + * @param right + */ + public ComparisonExpression(Expression left, Expression right) + { + super(left, right); + } + + public Object evaluate(AbstractJMSMessage message) throws QpidException + { + Comparable lv = (Comparable) left.evaluate(message); + if (lv == null) + { + return null; + } + + Comparable rv = (Comparable) right.evaluate(message); + if (rv == null) + { + return null; + } + + return compare(lv, rv); + } + + protected Boolean compare(Comparable lv, Comparable rv) + { + Class lc = lv.getClass(); + Class rc = rv.getClass(); + // If the the objects are not of the same type, + // try to convert up to allow the comparison. + if (lc != rc) + { + if (lc == Byte.class) + { + if (rc == Short.class) + { + lv = new Short(((Number) lv).shortValue()); + } + else if (rc == Integer.class) + { + lv = new Integer(((Number) lv).intValue()); + } + else if (rc == Long.class) + { + lv = new Long(((Number) lv).longValue()); + } + else if (rc == Float.class) + { + lv = new Float(((Number) lv).floatValue()); + } + else if (rc == Double.class) + { + lv = new Double(((Number) lv).doubleValue()); + } + else + { + return Boolean.FALSE; + } + } + else if (lc == Short.class) + { + if (rc == Integer.class) + { + lv = new Integer(((Number) lv).intValue()); + } + else if (rc == Long.class) + { + lv = new Long(((Number) lv).longValue()); + } + else if (rc == Float.class) + { + lv = new Float(((Number) lv).floatValue()); + } + else if (rc == Double.class) + { + lv = new Double(((Number) lv).doubleValue()); + } + else + { + return Boolean.FALSE; + } + } + else if (lc == Integer.class) + { + if (rc == Long.class) + { + lv = new Long(((Number) lv).longValue()); + } + else if (rc == Float.class) + { + lv = new Float(((Number) lv).floatValue()); + } + else if (rc == Double.class) + { + lv = new Double(((Number) lv).doubleValue()); + } + else + { + return Boolean.FALSE; + } + } + else if (lc == Long.class) + { + if (rc == Integer.class) + { + rv = new Long(((Number) rv).longValue()); + } + else if (rc == Float.class) + { + lv = new Float(((Number) lv).floatValue()); + } + else if (rc == Double.class) + { + lv = new Double(((Number) lv).doubleValue()); + } + else + { + return Boolean.FALSE; + } + } + else if (lc == Float.class) + { + if (rc == Integer.class) + { + rv = new Float(((Number) rv).floatValue()); + } + else if (rc == Long.class) + { + rv = new Float(((Number) rv).floatValue()); + } + else if (rc == Double.class) + { + lv = new Double(((Number) lv).doubleValue()); + } + else + { + return Boolean.FALSE; + } + } + else if (lc == Double.class) + { + if (rc == Integer.class) + { + rv = new Double(((Number) rv).doubleValue()); + } + else if (rc == Long.class) + { + rv = new Double(((Number) rv).doubleValue()); + } + else if (rc == Float.class) + { + rv = new Float(((Number) rv).doubleValue()); + } + else + { + return Boolean.FALSE; + } + } + else + { + return Boolean.FALSE; + } + } + + return asBoolean(lv.compareTo(rv)) ? Boolean.TRUE : Boolean.FALSE; + } + + protected abstract boolean asBoolean(int answer); + + public boolean matches(AbstractJMSMessage message) throws QpidException + { + Object object = evaluate(message); + + return (object != null) && (object == Boolean.TRUE); + } + +} diff --git a/java/client/src/main/java/org/apache/qpid/filter/ConstantExpression.java b/java/client/src/main/java/org/apache/qpid/filter/ConstantExpression.java new file mode 100644 index 0000000000..447de914a4 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/filter/ConstantExpression.java @@ -0,0 +1,204 @@ +/* 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.filter; + +import org.apache.qpid.QpidException; +import org.apache.qpid.client.message.AbstractJMSMessage; + +import java.math.BigDecimal; + +/** + * Represents a constant expression + */ +public class ConstantExpression implements Expression +{ + + static class BooleanConstantExpression extends ConstantExpression implements BooleanExpression + { + public BooleanConstantExpression(Object value) + { + super(value); + } + + public boolean matches(AbstractJMSMessage message) throws QpidException + { + Object object = evaluate(message); + + return (object != null) && (object == Boolean.TRUE); + } + } + + public static final BooleanConstantExpression NULL = new BooleanConstantExpression(null); + public static final BooleanConstantExpression TRUE = new BooleanConstantExpression(Boolean.TRUE); + public static final BooleanConstantExpression FALSE = new BooleanConstantExpression(Boolean.FALSE); + + private Object value; + + public static ConstantExpression createFromDecimal(String text) + { + + // Strip off the 'l' or 'L' if needed. + if (text.endsWith("l") || text.endsWith("L")) + { + text = text.substring(0, text.length() - 1); + } + + Number value; + try + { + value = new Long(text); + } + catch (NumberFormatException e) + { + // The number may be too big to fit in a long. + value = new BigDecimal(text); + } + + long l = value.longValue(); + if ((Integer.MIN_VALUE <= l) && (l <= Integer.MAX_VALUE)) + { + value = new Integer(value.intValue()); + } + + return new ConstantExpression(value); + } + + public static ConstantExpression createFromHex(String text) + { + Number value = new Long(Long.parseLong(text.substring(2), 16)); + long l = value.longValue(); + if ((Integer.MIN_VALUE <= l) && (l <= Integer.MAX_VALUE)) + { + value = new Integer(value.intValue()); + } + + return new ConstantExpression(value); + } + + public static ConstantExpression createFromOctal(String text) + { + Number value = new Long(Long.parseLong(text, 8)); + long l = value.longValue(); + if ((Integer.MIN_VALUE <= l) && (l <= Integer.MAX_VALUE)) + { + value = new Integer(value.intValue()); + } + + return new ConstantExpression(value); + } + + public static ConstantExpression createFloat(String text) + { + Number value = new Double(text); + + return new ConstantExpression(value); + } + + public ConstantExpression(Object value) + { + this.value = value; + } + + public Object evaluate(AbstractJMSMessage message) throws QpidException + { + return value; + } + + public Object getValue() + { + return value; + } + + /** + * @see Object#toString() + */ + public String toString() + { + if (value == null) + { + return "NULL"; + } + + if (value instanceof Boolean) + { + return ((Boolean) value).booleanValue() ? "TRUE" : "FALSE"; + } + + if (value instanceof String) + { + return ConstantExpression.encodeString((String) value); + } + + return value.toString(); + } + + /** + * TODO: more efficient hashCode() + * + * @see Object#hashCode() + */ + public int hashCode() + { + return toString().hashCode(); + } + + /** + * TODO: more efficient hashCode() + * + * @see Object#equals(Object) + */ + public boolean equals(Object o) + { + + if ((o == null) || !this.getClass().equals(o.getClass())) + { + return false; + } + + return toString().equals(o.toString()); + + } + + /** + * Encodes the value of string so that it looks like it would look like + * when it was provided in a selector. + * + * @param s + * @return + */ + public static String encodeString(String s) + { + StringBuffer b = new StringBuffer(); + b.append('\''); + for (int i = 0; i < s.length(); i++) + { + char c = s.charAt(i); + if (c == '\'') + { + b.append(c); + } + + b.append(c); + } + + b.append('\''); + + return b.toString(); + } + +} diff --git a/java/client/src/main/java/org/apache/qpid/filter/Expression.java b/java/client/src/main/java/org/apache/qpid/filter/Expression.java new file mode 100644 index 0000000000..e578775a77 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/filter/Expression.java @@ -0,0 +1,34 @@ +/* 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.filter; + +import org.apache.qpid.QpidException; +import org.apache.qpid.client.message.AbstractJMSMessage; + + +/** + * Represents an expression + */ +public interface Expression +{ + /** + * @param message The message to evaluate + * @return the value of this expression + */ + public Object evaluate(AbstractJMSMessage message) throws QpidException; +} diff --git a/java/client/src/main/java/org/apache/qpid/filter/JMSSelectorFilter.java b/java/client/src/main/java/org/apache/qpid/filter/JMSSelectorFilter.java new file mode 100644 index 0000000000..dcfb9a9940 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/filter/JMSSelectorFilter.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.filter; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.apache.qpid.QpidException; +import org.apache.qpid.filter.selector.SelectorParser; +import org.apache.qpid.client.message.AbstractJMSMessage; + + +public class JMSSelectorFilter implements MessageFilter +{ + /** + * this JMSSelectorFilter's logger + */ + private static final Logger _logger = LoggerFactory.getLogger(JMSSelectorFilter.class); + + private String _selector; + private BooleanExpression _matcher; + + public JMSSelectorFilter(String selector) throws QpidException + { + _selector = selector; + if (JMSSelectorFilter._logger.isDebugEnabled()) + { + JMSSelectorFilter._logger.debug("Created JMSSelectorFilter with selector:" + _selector); + } + _matcher = new SelectorParser().parse(selector); + } + + public boolean matches(AbstractJMSMessage message) + { + try + { + boolean match = _matcher.matches(message); + if (JMSSelectorFilter._logger.isDebugEnabled()) + { + JMSSelectorFilter._logger.debug(message + " match(" + match + ") selector(" + System + .identityHashCode(_selector) + "):" + _selector); + } + return match; + } + catch (QpidException e) + { + JMSSelectorFilter._logger.warn("Caght exception when evaluating message selector for message " + message, e); + } + return false; + } + + public String getSelector() + { + return _selector; + } +} diff --git a/java/client/src/main/java/org/apache/qpid/filter/LogicExpression.java b/java/client/src/main/java/org/apache/qpid/filter/LogicExpression.java new file mode 100644 index 0000000000..d7aabd5a46 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/filter/LogicExpression.java @@ -0,0 +1,108 @@ +/* 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.filter; + +import org.apache.qpid.QpidException; +import org.apache.qpid.client.message.AbstractJMSMessage; + + +/** + * A filter performing a comparison of two objects + */ +public abstract class LogicExpression extends BinaryExpression implements BooleanExpression +{ + + public static BooleanExpression createOR(BooleanExpression lvalue, BooleanExpression rvalue) + { + return new LogicExpression(lvalue, rvalue) + { + + public Object evaluate(AbstractJMSMessage message) throws QpidException + { + + Boolean lv = (Boolean) left.evaluate(message); + // Can we do an OR shortcut?? + if ((lv != null) && lv.booleanValue()) + { + return Boolean.TRUE; + } + + Boolean rv = (Boolean) right.evaluate(message); + + return (rv == null) ? null : rv; + } + + public String getExpressionSymbol() + { + return "OR"; + } + }; + } + + public static BooleanExpression createAND(BooleanExpression lvalue, BooleanExpression rvalue) + { + return new LogicExpression(lvalue, rvalue) + { + + public Object evaluate(AbstractJMSMessage message) throws QpidException + { + + Boolean lv = (Boolean) left.evaluate(message); + + // Can we do an AND shortcut?? + if (lv == null) + { + return null; + } + + if (!lv.booleanValue()) + { + return Boolean.FALSE; + } + + Boolean rv = (Boolean) right.evaluate(message); + + return (rv == null) ? null : rv; + } + + public String getExpressionSymbol() + { + return "AND"; + } + }; + } + + /** + * @param left + * @param right + */ + public LogicExpression(BooleanExpression left, BooleanExpression right) + { + super(left, right); + } + + public abstract Object evaluate(AbstractJMSMessage message) throws QpidException; + + public boolean matches(AbstractJMSMessage message) throws QpidException + { + Object object = evaluate(message); + + return (object != null) && (object == Boolean.TRUE); + } + +} diff --git a/java/client/src/main/java/org/apache/qpid/filter/MessageFilter.java b/java/client/src/main/java/org/apache/qpid/filter/MessageFilter.java new file mode 100644 index 0000000000..a775080d81 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/filter/MessageFilter.java @@ -0,0 +1,27 @@ +/* Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.qpid.filter; + +import org.apache.qpid.QpidException; +import org.apache.qpid.client.message.AbstractJMSMessage; + + +public interface MessageFilter +{ + boolean matches(AbstractJMSMessage message) throws QpidException; +} diff --git a/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java b/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java new file mode 100644 index 0000000000..700c6a15ac --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java @@ -0,0 +1,303 @@ +/* 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.filter; + +import org.apache.qpid.framing.CommonContentHeaderProperties; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.client.message.AbstractJMSMessage; +import org.apache.qpid.QpidException; +import org.slf4j.LoggerFactory; +import org.slf4j.Logger; + +import javax.jms.JMSException; +import java.util.HashMap; + +/** + * Represents a property expression + */ +public class PropertyExpression implements Expression +{ + // Constants - defined the same as JMS + private static final int NON_PERSISTENT = 1; + private static final int DEFAULT_PRIORITY = 4; + + private static final Logger _logger = LoggerFactory.getLogger(PropertyExpression.class); + + private static final HashMap JMS_PROPERTY_EXPRESSIONS = new HashMap(); + + static + { + JMS_PROPERTY_EXPRESSIONS.put("JMSDestination", new Expression() + { + public Object evaluate(AbstractJMSMessage message) + { + //TODO + return null; + } + }); + JMS_PROPERTY_EXPRESSIONS.put("JMSReplyTo", new Expression() + { + public Object evaluate(AbstractJMSMessage message) + { + try + { + CommonContentHeaderProperties _properties = + message.getContentHeaderProperties(); + AMQShortString replyTo = _properties.getReplyTo(); + + return (replyTo == null) ? null : replyTo.toString(); + } + catch (Exception e) + { + _logger.warn("Error evaluating property", e); + + return null; + } + } + }); + + JMS_PROPERTY_EXPRESSIONS.put("JMSType", new Expression() + { + public Object evaluate(AbstractJMSMessage message) + { + try + { + CommonContentHeaderProperties _properties = + message.getContentHeaderProperties(); + AMQShortString type = _properties.getType(); + + return (type == null) ? null : type.toString(); + } + catch (Exception e) + { + _logger.warn("Error evaluating property", e); + + return null; + } + + } + }); + + JMS_PROPERTY_EXPRESSIONS.put("JMSDeliveryMode", new Expression() + { + public Object evaluate(AbstractJMSMessage message) + { + try + { + int mode = message.getJMSDeliveryMode(); + if (_logger.isDebugEnabled()) + { + _logger.debug("JMSDeliveryMode is :" + mode); + } + + return mode; + } + catch (Exception e) + { + _logger.warn("Error evaluating property",e); + } + + return NON_PERSISTENT; + } + }); + + JMS_PROPERTY_EXPRESSIONS.put("JMSPriority", new Expression() + { + public Object evaluate(AbstractJMSMessage message) + { + try + { + CommonContentHeaderProperties _properties = + message.getContentHeaderProperties(); + return (int) _properties.getPriority(); + } + catch (Exception e) + { + _logger.warn("Error evaluating property",e); + } + + return DEFAULT_PRIORITY; + } + }); + + JMS_PROPERTY_EXPRESSIONS.put("AMQMessageID", new Expression() + { + public Object evaluate(AbstractJMSMessage message) + { + + try + { + CommonContentHeaderProperties _properties = + message.getContentHeaderProperties(); + AMQShortString messageId = _properties.getMessageId(); + + return (messageId == null) ? null : messageId; + } + catch (Exception e) + { + _logger.warn("Error evaluating property",e); + + return null; + } + + } + }); + + JMS_PROPERTY_EXPRESSIONS.put("JMSTimestamp", new Expression() + { + public Object evaluate(AbstractJMSMessage message) + { + try + { + CommonContentHeaderProperties _properties = + message.getContentHeaderProperties(); + return _properties.getTimestamp(); + } + catch (Exception e) + { + _logger.warn("Error evaluating property",e); + + return null; + } + + } + }); + + JMS_PROPERTY_EXPRESSIONS.put("JMSCorrelationID", new Expression() + { + public Object evaluate(AbstractJMSMessage message) + { + + try + { + CommonContentHeaderProperties _properties = + message.getContentHeaderProperties(); + AMQShortString correlationId = _properties.getCorrelationId(); + return (correlationId == null) ? null : correlationId.toString(); + } + catch (Exception e) + { + _logger.warn("Error evaluating property",e); + + return null; + } + + } + }); + + JMS_PROPERTY_EXPRESSIONS.put("JMSExpiration", new Expression() + { + public Object evaluate(AbstractJMSMessage message) + { + + try + { + CommonContentHeaderProperties _properties = + message.getContentHeaderProperties(); + return _properties.getExpiration(); + } + catch (Exception e) + { + _logger.warn("Error evaluating property",e); + return null; + } + + } + }); + + JMS_PROPERTY_EXPRESSIONS.put("JMSRedelivered", new Expression() + { + public Object evaluate(AbstractJMSMessage message) + { + try + { + return message.getJMSRedelivered(); + } + catch (JMSException e) + { + _logger.warn("Error evaluating property",e); + return null; + } + } + }); + + } + + private final String name; + private final Expression jmsPropertyExpression; + + public PropertyExpression(String name) + { + this.name = name; + jmsPropertyExpression = JMS_PROPERTY_EXPRESSIONS.get(name); + } + + public Object evaluate(AbstractJMSMessage message) throws QpidException + { + + if (jmsPropertyExpression != null) + { + return jmsPropertyExpression.evaluate(message); + } + else + { + + CommonContentHeaderProperties _properties = message.getContentHeaderProperties(); + if (_logger.isDebugEnabled()) + { + _logger.debug("Looking up property:" + name); + _logger.debug("Properties are:" + _properties.getHeaders().keySet()); + } + return _properties.getHeaders().getObject(name); + } + } + + public String getName() + { + return name; + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() + { + return name; + } + + /** + * @see java.lang.Object#hashCode() + */ + public int hashCode() + { + return name.hashCode(); + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object o) + { + if ((o == null) || !this.getClass().equals(o.getClass())) + { + return false; + } + return name.equals(((PropertyExpression) o).name); + } + +} diff --git a/java/client/src/main/java/org/apache/qpid/filter/UnaryExpression.java b/java/client/src/main/java/org/apache/qpid/filter/UnaryExpression.java new file mode 100644 index 0000000000..b620b107c4 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/filter/UnaryExpression.java @@ -0,0 +1,321 @@ +/* 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.filter; + +import org.apache.qpid.QpidException; +import org.apache.qpid.client.message.AbstractJMSMessage; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; + +/** + * An expression which performs an operation on two expression values + */ +public abstract class UnaryExpression implements Expression +{ + + private static final BigDecimal BD_LONG_MIN_VALUE = BigDecimal.valueOf(Long.MIN_VALUE); + protected Expression right; + + public static Expression createNegate(Expression left) + { + return new UnaryExpression(left) + { + public Object evaluate(AbstractJMSMessage message) throws QpidException + { + Object rvalue = right.evaluate(message); + if (rvalue == null) + { + return null; + } + + if (rvalue instanceof Number) + { + return UnaryExpression.negate((Number) rvalue); + } + + return null; + } + + public String getExpressionSymbol() + { + return "-"; + } + }; + } + + public static BooleanExpression createInExpression(PropertyExpression right, List elements, final boolean not) + { + + // Use a HashSet if there are many elements. + Collection t; + if (elements.size() == 0) + { + t = null; + } + else if (elements.size() < 5) + { + t = elements; + } + else + { + t = new HashSet(elements); + } + + final Collection inList = t; + + return new BooleanUnaryExpression(right) + { + public Object evaluate(AbstractJMSMessage message) throws QpidException + { + + Object rvalue = right.evaluate(message); + if (rvalue == null) + { + return null; + } + + if (rvalue.getClass() != String.class) + { + return null; + } + + if (((inList != null) && inList.contains(rvalue)) ^ not) + { + return Boolean.TRUE; + } + else + { + return Boolean.FALSE; + } + + } + + public String toString() + { + StringBuffer answer = new StringBuffer(); + answer.append(right); + answer.append(" "); + answer.append(getExpressionSymbol()); + answer.append(" ( "); + + int count = 0; + for (Iterator i = inList.iterator(); i.hasNext();) + { + Object o = (Object) i.next(); + if (count != 0) + { + answer.append(", "); + } + + answer.append(o); + count++; + } + + answer.append(" )"); + + return answer.toString(); + } + + public String getExpressionSymbol() + { + if (not) + { + return "NOT IN"; + } + else + { + return "IN"; + } + } + }; + } + + abstract static class BooleanUnaryExpression extends UnaryExpression implements BooleanExpression + { + public BooleanUnaryExpression(Expression left) + { + super(left); + } + + public boolean matches(AbstractJMSMessage message) throws QpidException + { + Object object = evaluate(message); + + return (object != null) && (object == Boolean.TRUE); + } + } + + ; + + public static BooleanExpression createNOT(BooleanExpression left) + { + return new BooleanUnaryExpression(left) + { + public Object evaluate(AbstractJMSMessage message) throws QpidException + { + Boolean lvalue = (Boolean) right.evaluate(message); + if (lvalue == null) + { + return null; + } + + return lvalue.booleanValue() ? Boolean.FALSE : Boolean.TRUE; + } + + public String getExpressionSymbol() + { + return "NOT"; + } + }; + } + public static BooleanExpression createBooleanCast(Expression left) + { + return new BooleanUnaryExpression(left) + { + public Object evaluate(AbstractJMSMessage message) throws QpidException + { + Object rvalue = right.evaluate(message); + if (rvalue == null) + { + return null; + } + + if (!rvalue.getClass().equals(Boolean.class)) + { + return Boolean.FALSE; + } + + return ((Boolean) rvalue).booleanValue() ? Boolean.TRUE : Boolean.FALSE; + } + + public String toString() + { + return right.toString(); + } + + public String getExpressionSymbol() + { + return ""; + } + }; + } + + private static Number negate(Number left) + { + Class clazz = left.getClass(); + if (clazz == Integer.class) + { + return new Integer(-left.intValue()); + } + else if (clazz == Long.class) + { + return new Long(-left.longValue()); + } + else if (clazz == Float.class) + { + return new Float(-left.floatValue()); + } + else if (clazz == Double.class) + { + return new Double(-left.doubleValue()); + } + else if (clazz == BigDecimal.class) + { + // We ussually get a big deciamal when we have Long.MIN_VALUE constant in the + // Selector. Long.MIN_VALUE is too big to store in a Long as a positive so we store it + // as a Big decimal. But it gets Negated right away.. to here we try to covert it back + // to a Long. + BigDecimal bd = (BigDecimal) left; + bd = bd.negate(); + + if (UnaryExpression.BD_LONG_MIN_VALUE.compareTo(bd) == 0) + { + return new Long(Long.MIN_VALUE); + } + + return bd; + } + else + { + throw new RuntimeException("Don't know how to negate: " + left); + } + } + + public UnaryExpression(Expression left) + { + this.right = left; + } + + public Expression getRight() + { + return right; + } + + public void setRight(Expression expression) + { + right = expression; + } + + /** + * @see Object#toString() + */ + public String toString() + { + return "(" + getExpressionSymbol() + " " + right.toString() + ")"; + } + + /** + * TODO: more efficient hashCode() + * + * @see Object#hashCode() + */ + public int hashCode() + { + return toString().hashCode(); + } + + /** + * TODO: more efficient hashCode() + * + * @see Object#equals(Object) + */ + public boolean equals(Object o) + { + + if ((o == null) || !this.getClass().equals(o.getClass())) + { + return false; + } + + return toString().equals(o.toString()); + + } + + /** + * Returns the symbol that represents this binary expression. For example, addition is + * represented by "+" + * + * @return + */ + public abstract String getExpressionSymbol(); + +} diff --git a/java/client/src/main/java/org/apache/qpid/jms/BrokerDetails.java b/java/client/src/main/java/org/apache/qpid/jms/BrokerDetails.java index 72ba16086d..0316255b2c 100644 --- a/java/client/src/main/java/org/apache/qpid/jms/BrokerDetails.java +++ b/java/client/src/main/java/org/apache/qpid/jms/BrokerDetails.java @@ -48,7 +48,7 @@ public interface BrokerDetails public static final long DEFAULT_CONNECT_TIMEOUT = 30000L; public static final boolean USE_SSL_DEFAULT = false; - // pulled these properties from the new BrokerDetails class in the qpidity package + // pulled these properties from the new BrokerDetails class in the qpid package public static final String PROTOCOL_TCP = "tcp"; public static final String PROTOCOL_TLS = "tls"; diff --git a/java/client/src/main/java/org/apache/qpid/naming/ReadOnlyContext.java b/java/client/src/main/java/org/apache/qpid/naming/ReadOnlyContext.java new file mode 100644 index 0000000000..59ec4cfba7 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/naming/ReadOnlyContext.java @@ -0,0 +1,509 @@ +/* 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.naming; + +import org.apache.qpid.jndi.NameParserImpl; + +import javax.naming.*; +import javax.naming.spi.NamingManager; +import java.io.Serializable; +import java.util.*; + +/** + * Based on class from ActiveMQ. + * A read-only Context + *

+ * This version assumes it and all its subcontext are read-only and any attempt + * to modify (e.g. through bind) will result in an OperationNotSupportedException. + * Each Context in the tree builds a cache of the entries in all sub-contexts + * to optimise the performance of lookup. + *

+ *

This implementation is intended to optimise the performance of lookup(String) + * to about the level of a HashMap get. It has been observed that the scheme + * resolution phase performed by the JVM takes considerably longer, so for + * optimum performance lookups should be coded like:

+ * + * Context componentContext = (Context)new InitialContext().lookup("java:comp"); + * String envEntry = (String) componentContext.lookup("env/myEntry"); + * String envEntry2 = (String) componentContext.lookup("env/myEntry2"); + * + */ +public class ReadOnlyContext implements Context, Serializable +{ + private static final long serialVersionUID = -5754338187296859149L; + protected static final NameParser nameParser = new NameParserImpl(); + + protected final Hashtable environment; // environment for this context + protected final Map bindings; // bindings at my level + protected final Map treeBindings; // all bindings under me + + private boolean frozen = false; + private String nameInNamespace = ""; + public static final String SEPARATOR = "/"; + + public ReadOnlyContext() + { + environment = new Hashtable(); + bindings = new HashMap(); + treeBindings = new HashMap(); + } + + public ReadOnlyContext(Hashtable env) + { + if (env == null) + { + this.environment = new Hashtable(); + } + else + { + this.environment = new Hashtable(env); + } + + this.bindings = Collections.EMPTY_MAP; + this.treeBindings = Collections.EMPTY_MAP; + } + + public ReadOnlyContext(Hashtable environment, Map bindings) + { + if (environment == null) + { + this.environment = new Hashtable(); + } + else + { + this.environment = new Hashtable(environment); + } + + this.bindings = bindings; + treeBindings = new HashMap(); + frozen = true; + } + + public ReadOnlyContext(Hashtable environment, Map bindings, String nameInNamespace) + { + this(environment, bindings); + this.nameInNamespace = nameInNamespace; + } + + protected ReadOnlyContext(ReadOnlyContext clone, Hashtable env) + { + this.bindings = clone.bindings; + this.treeBindings = clone.treeBindings; + this.environment = new Hashtable(env); + } + + protected ReadOnlyContext(ReadOnlyContext clone, Hashtable env, String nameInNamespace) + { + this(clone, env); + this.nameInNamespace = nameInNamespace; + } + + public void freeze() + { + frozen = true; + } + + boolean isFrozen() + { + return frozen; + } + + /** + * internalBind is intended for use only during setup or possibly by suitably synchronized superclasses. + * It binds every possible lookup into a map in each context. To do this, each context + * strips off one name segment and if necessary creates a new context for it. Then it asks that context + * to bind the remaining name. It returns a map containing all the bindings from the next context, plus + * the context it just created (if it in fact created it). (the names are suitably extended by the segment + * originally lopped off). + * + * @param name + * @param value + * @return + * @throws javax.naming.NamingException + */ + protected Map internalBind(String name, Object value) throws NamingException + { + assert (name != null) && (name.length() > 0); + assert !frozen; + + Map newBindings = new HashMap(); + int pos = name.indexOf('/'); + if (pos == -1) + { + if (treeBindings.put(name, value) != null) + { + throw new NamingException("Something already bound at " + name); + } + + bindings.put(name, value); + newBindings.put(name, value); + } + else + { + String segment = name.substring(0, pos); + assert segment != null; + assert !segment.equals(""); + Object o = treeBindings.get(segment); + if (o == null) + { + o = newContext(); + treeBindings.put(segment, o); + bindings.put(segment, o); + newBindings.put(segment, o); + } + else if (!(o instanceof ReadOnlyContext)) + { + throw new NamingException("Something already bound where a subcontext should go"); + } + + ReadOnlyContext readOnlyContext = (ReadOnlyContext) o; + String remainder = name.substring(pos + 1); + Map subBindings = readOnlyContext.internalBind(remainder, value); + for (Iterator iterator = subBindings.entrySet().iterator(); iterator.hasNext();) + { + Map.Entry entry = (Map.Entry) iterator.next(); + String subName = segment + "/" + (String) entry.getKey(); + Object bound = entry.getValue(); + treeBindings.put(subName, bound); + newBindings.put(subName, bound); + } + } + + return newBindings; + } + + protected ReadOnlyContext newContext() + { + return new ReadOnlyContext(); + } + + public Object addToEnvironment(String propName, Object propVal) throws NamingException + { + return environment.put(propName, propVal); + } + + public Hashtable getEnvironment() throws NamingException + { + return (Hashtable) environment.clone(); + } + + public Object removeFromEnvironment(String propName) throws NamingException + { + return environment.remove(propName); + } + + public Object lookup(String name) throws NamingException + { + if (name.length() == 0) + { + return this; + } + + Object result = treeBindings.get(name); + if (result == null) + { + result = bindings.get(name); + } + + if (result == null) + { + int pos = name.indexOf(':'); + if (pos > 0) + { + String scheme = name.substring(0, pos); + Context ctx = NamingManager.getURLContext(scheme, environment); + if (ctx == null) + { + throw new NamingException("scheme " + scheme + " not recognized"); + } + + return ctx.lookup(name); + } + else + { + // Split out the first name of the path + // and look for it in the bindings map. + CompositeName path = new CompositeName(name); + + if (path.size() == 0) + { + return this; + } + else + { + String first = path.get(0); + Object obj = bindings.get(first); + if (obj == null) + { + throw new NameNotFoundException(name); + } + else if ((obj instanceof Context) && (path.size() > 1)) + { + Context subContext = (Context) obj; + obj = subContext.lookup(path.getSuffix(1)); + } + + return obj; + } + } + } + + if (result instanceof LinkRef) + { + LinkRef ref = (LinkRef) result; + result = lookup(ref.getLinkName()); + } + + if (result instanceof Reference) + { + try + { + result = NamingManager.getObjectInstance(result, null, null, this.environment); + } + catch (NamingException e) + { + throw e; + } + catch (Exception e) + { + throw (NamingException) new NamingException("could not look up : " + name).initCause(e); + } + } + + if (result instanceof ReadOnlyContext) + { + String prefix = getNameInNamespace(); + if (prefix.length() > 0) + { + prefix = prefix + SEPARATOR; + } + + result = new ReadOnlyContext((ReadOnlyContext) result, environment, prefix + name); + } + + return result; + } + + public Object lookup(Name name) throws NamingException + { + return lookup(name.toString()); + } + + public Object lookupLink(String name) throws NamingException + { + return lookup(name); + } + + public Name composeName(Name name, Name prefix) throws NamingException + { + Name result = (Name) prefix.clone(); + result.addAll(name); + + return result; + } + + public String composeName(String name, String prefix) throws NamingException + { + CompositeName result = new CompositeName(prefix); + result.addAll(new CompositeName(name)); + + return result.toString(); + } + + public NamingEnumeration list(String name) throws NamingException + { + Object o = lookup(name); + if (o == this) + { + return new ReadOnlyContext.ListEnumeration(); + } + else if (o instanceof Context) + { + return ((Context) o).list(""); + } + else + { + throw new NotContextException(); + } + } + + public NamingEnumeration listBindings(String name) throws NamingException + { + Object o = lookup(name); + if (o == this) + { + return new ReadOnlyContext.ListBindingEnumeration(); + } + else if (o instanceof Context) + { + return ((Context) o).listBindings(""); + } + else + { + throw new NotContextException(); + } + } + + public Object lookupLink(Name name) throws NamingException + { + return lookupLink(name.toString()); + } + + public NamingEnumeration list(Name name) throws NamingException + { + return list(name.toString()); + } + + public NamingEnumeration listBindings(Name name) throws NamingException + { + return listBindings(name.toString()); + } + + public void bind(Name name, Object obj) throws NamingException + { + throw new OperationNotSupportedException(); + } + + public void bind(String name, Object obj) throws NamingException + { + throw new OperationNotSupportedException(); + } + + public void close() throws NamingException + { + // ignore + } + + public Context createSubcontext(Name name) throws NamingException + { + throw new OperationNotSupportedException(); + } + + public Context createSubcontext(String name) throws NamingException + { + throw new OperationNotSupportedException(); + } + + public void destroySubcontext(Name name) throws NamingException + { + throw new OperationNotSupportedException(); + } + + public void destroySubcontext(String name) throws NamingException + { + throw new OperationNotSupportedException(); + } + + public String getNameInNamespace() throws NamingException + { + return nameInNamespace; + } + + public NameParser getNameParser(Name name) throws NamingException + { + return nameParser; + } + + public NameParser getNameParser(String name) throws NamingException + { + return nameParser; + } + + public void rebind(Name name, Object obj) throws NamingException + { + throw new OperationNotSupportedException(); + } + + public void rebind(String name, Object obj) throws NamingException + { + throw new OperationNotSupportedException(); + } + + public void rename(Name oldName, Name newName) throws NamingException + { + throw new OperationNotSupportedException(); + } + + public void rename(String oldName, String newName) throws NamingException + { + throw new OperationNotSupportedException(); + } + + public void unbind(Name name) throws NamingException + { + throw new OperationNotSupportedException(); + } + + public void unbind(String name) throws NamingException + { + throw new OperationNotSupportedException(); + } + + private abstract class LocalNamingEnumeration implements NamingEnumeration + { + private Iterator i = bindings.entrySet().iterator(); + + public boolean hasMore() throws NamingException + { + return i.hasNext(); + } + + public boolean hasMoreElements() + { + return i.hasNext(); + } + + protected Map.Entry getNext() + { + return (Map.Entry) i.next(); + } + + public void close() throws NamingException + { } + } + + private class ListEnumeration extends ReadOnlyContext.LocalNamingEnumeration + { + public Object next() throws NamingException + { + return nextElement(); + } + + public Object nextElement() + { + Map.Entry entry = getNext(); + + return new NameClassPair((String) entry.getKey(), entry.getValue().getClass().getName()); + } + } + + private class ListBindingEnumeration extends ReadOnlyContext.LocalNamingEnumeration + { + public Object next() throws NamingException + { + return nextElement(); + } + + public Object nextElement() + { + Map.Entry entry = getNext(); + + return new Binding((String) entry.getKey(), entry.getValue()); + } + } +} diff --git a/java/client/src/main/java/org/apache/qpid/naming/jndi.properties b/java/client/src/main/java/org/apache/qpid/naming/jndi.properties new file mode 100644 index 0000000000..830de5f619 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/naming/jndi.properties @@ -0,0 +1,40 @@ +# +# 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. +# +java.naming.factory.initial = org.apache.qpid.naming.PropertiesFileInitialConextFactory + +# use the following property to configure the default connector +#java.naming.provider.url - ignored. + +# register some connection factories +# connectionfactory.[jndiname] = [ConnectionURL] +# qpid:username=foo;password=password;client_id=id;virtualhost=path@tpc:localhost:1556 +connectionfactory.local = qpid:tcp:localhost' + +# register some queues in JNDI using the form +# queue.[jndiName] = [physicalName] +queue.MyQueue = example.MyQueue + +# register some topics in JNDI using the form +# topic.[jndiName] = [physicalName] +topic.ibmStocks = stocks.nyse.ibm + +# Register an AMQP destination in JNDI +# NOTE: Qpid currently only supports direct,topics and headers +# destination.[jniName] = [BindingURL] +destination.direct = direct://amq.direct//directQueue diff --git a/java/client/src/main/java/org/apache/qpid/nclient/Client.java b/java/client/src/main/java/org/apache/qpid/nclient/Client.java new file mode 100644 index 0000000000..bed3ee02cb --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/nclient/Client.java @@ -0,0 +1,294 @@ +/* + * 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.nclient; + +import java.util.List; +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import org.apache.qpid.client.url.URLParser_0_10; +import org.apache.qpid.jms.BrokerDetails; +import org.apache.qpid.url.QpidURL; +import org.apache.qpid.ErrorCode; +import org.apache.qpid.QpidException; +import org.apache.qpid.nclient.impl.ClientSession; +import org.apache.qpid.nclient.impl.ClientSessionDelegate; +import org.apache.qpid.transport.Channel; +import org.apache.qpid.transport.ClientDelegate; +import org.apache.qpid.transport.Connection; +import org.apache.qpid.transport.ConnectionClose; +import org.apache.qpid.transport.ConnectionCloseCode; +import org.apache.qpid.transport.ConnectionCloseOk; +import org.apache.qpid.transport.ProtocolHeader; +import org.apache.qpid.transport.ProtocolVersionException; +import org.apache.qpid.transport.SessionDelegate; +import org.apache.qpid.transport.network.io.IoTransport; +import org.apache.qpid.transport.network.mina.MinaHandler; +import org.apache.qpid.transport.network.nio.NioHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class Client implements org.apache.qpid.nclient.Connection +{ + private Connection _conn; + private ClosedListener _closedListner; + private final Lock _lock = new ReentrantLock(); + private static Logger _logger = LoggerFactory.getLogger(Client.class); + private Condition closeOk; + private boolean closed = false; + private long timeout = 60000; + + private ProtocolHeader header = null; + + /** + * + * @return returns a new connection to the broker. + */ + public static org.apache.qpid.nclient.Connection createConnection() + { + return new Client(); + } + + public void connect(String host, int port,String virtualHost,String username, String password) throws QpidException + { + + final Condition negotiationComplete = _lock.newCondition(); + closeOk = _lock.newCondition(); + _lock.lock(); + + ClientDelegate connectionDelegate = new ClientDelegate() + { + private boolean receivedClose = false; + public SessionDelegate getSessionDelegate() + { + return new ClientSessionDelegate(); + } + + public void exception(Throwable t) + { + if (_closedListner != null) + { + _closedListner.onClosed(ErrorCode.CONNECTION_ERROR,ErrorCode.CONNECTION_ERROR.getDesc(),t); + } + else + { + throw new RuntimeException("connection closed",t); + } + } + + public void closed() + { + if (_closedListner != null && !this.receivedClose) + { + _closedListner.onClosed(ErrorCode.CONNECTION_ERROR,ErrorCode.CONNECTION_ERROR.getDesc(),null); + } + } + + @Override public void connectionCloseOk(Channel context, ConnectionCloseOk struct) + { + _lock.lock(); + try + { + closed = true; + this.receivedClose = true; + closeOk.signalAll(); + } + finally + { + _lock.unlock(); + } + } + + @Override public void connectionClose(Channel context, ConnectionClose connectionClose) + { + ErrorCode errorCode = ErrorCode.get(connectionClose.getReplyCode().getValue()); + if (_closedListner == null && errorCode != ErrorCode.NO_ERROR) + { + throw new RuntimeException + (new QpidException("Server closed the connection: Reason " + + connectionClose.getReplyText(), + errorCode, + null)); + } + else + { + _closedListner.onClosed(errorCode, connectionClose.getReplyText(),null); + } + + this.receivedClose = true; + } + @Override public void init(Channel ch, ProtocolHeader hdr) + { + // TODO: once the merge is done we'll need to update this code + // for handling 0.8 protocol version type i.e. major=8 and mino + if (hdr.getMajor() != 0 || hdr.getMinor() != 10) + { + Client.this.header = hdr; + _lock.lock(); + negotiationComplete.signalAll(); + _lock.unlock(); + } + } + }; + + connectionDelegate.setCondition(_lock,negotiationComplete); + connectionDelegate.setUsername(username); + connectionDelegate.setPassword(password); + connectionDelegate.setVirtualHost(virtualHost); + + String transport = System.getProperty("transport","io"); + if (transport.equalsIgnoreCase("nio")) + { + _logger.info("using NIO Transport"); + _conn = NioHandler.connect(host, port,connectionDelegate); + } + else if (transport.equalsIgnoreCase("io")) + { + _logger.info("using Plain IO Transport"); + _conn = IoTransport.connect(host, port,connectionDelegate); + } + else + { + _logger.info("using MINA Transport"); + _conn = MinaHandler.connect(host, port,connectionDelegate); + // _conn = NativeHandler.connect(host, port,connectionDelegate); + } + + // XXX: hardcoded version numbers + _conn.send(new ProtocolHeader(1, 0, 10)); + + try + { + negotiationComplete.await(timeout, TimeUnit.MILLISECONDS); + if (header != null) + { + _conn.close(); + throw new ProtocolVersionException(header.getMajor(), header.getMinor()); + } + } + catch (InterruptedException e) + { + throw new RuntimeException(e); + } + finally + { + _lock.unlock(); + } + } + + public void connect(String url)throws QpidException + { + URLParser_0_10 parser = null; + try + { + parser = new URLParser_0_10(url); + } + catch(Exception e) + { + throw new QpidException("Error parsing the URL",ErrorCode.UNDEFINED,e); + } + List brokers = parser.getAllBrokerDetails(); + BrokerDetails brokerDetail = brokers.get(0); + connect(brokerDetail.getHost(), brokerDetail.getPort(), brokerDetail.getProperty("virtualhost"), + brokerDetail.getProperty("username")== null? "guest":brokerDetail.getProperty("username"), + brokerDetail.getProperty("password")== null? "guest":brokerDetail.getProperty("password")); + } + + /* + * Until the dust settles with the URL disucssion + * I am not going to implement this. + */ + public void connect(QpidURL url) throws QpidException + { + throw new UnsupportedOperationException("Not implemented"); + } + + /* { + // temp impl to tests + BrokerDetails details = url.getAllBrokerDetails().get(0); + connect(details.getHost(), + details.getPort(), + details.getVirtualHost(), + details.getUserName(), + details.getPassword()); + } +*/ + + public void close() throws QpidException + { + Channel ch = _conn.getChannel(0); + ch.connectionClose(ConnectionCloseCode.NORMAL, "client is closing"); + _lock.lock(); + try + { + try + { + long start = System.currentTimeMillis(); + long elapsed = 0; + while (!closed && elapsed < timeout) + { + closeOk.await(timeout - elapsed, TimeUnit.MILLISECONDS); + elapsed = System.currentTimeMillis() - start; + } + if(!closed) + { + throw new QpidException("Timed out when closing connection", ErrorCode.CONNECTION_ERROR, null); + } + } + catch (InterruptedException e) + { + throw new QpidException("Interrupted when closing connection", ErrorCode.CONNECTION_ERROR, null); + } + } + finally + { + _lock.unlock(); + } + _conn.close(); + } + + public Session createSession(long expiryInSeconds) + { + Channel ch = _conn.getChannel(); + ClientSession ssn = new ClientSession(UUID.randomUUID().toString().getBytes()); + ssn.attach(ch); + ssn.sessionAttach(ssn.getName()); + ssn.sessionRequestTimeout(expiryInSeconds); + return ssn; + } + + public DtxSession createDTXSession(int expiryInSeconds) + { + ClientSession clientSession = (ClientSession) createSession(expiryInSeconds); + clientSession.dtxSelect(); + return (DtxSession) clientSession; + } + + public void setClosedListener(ClosedListener closedListner) + { + + _closedListner = closedListner; + } + +} diff --git a/java/client/src/main/java/org/apache/qpid/nclient/ClosedListener.java b/java/client/src/main/java/org/apache/qpid/nclient/ClosedListener.java new file mode 100644 index 0000000000..4cf0cab1ec --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/nclient/ClosedListener.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.nclient; + +import org.apache.qpid.ErrorCode; + + +/** + * If the communication layer detects a serious problem with a connection, it + * informs the connection's ExceptionListener + */ +public interface ClosedListener +{ + /** + * If the communication layer detects a serious problem with a connection, it + * informs the connection's ExceptionListener + * @param errorCode TODO + * @param reason TODO + * @param t TODO + * @see Connection + */ + public void onClosed(ErrorCode errorCode, String reason, Throwable t); +} \ No newline at end of file diff --git a/java/client/src/main/java/org/apache/qpid/nclient/Connection.java b/java/client/src/main/java/org/apache/qpid/nclient/Connection.java new file mode 100644 index 0000000000..2d5b50b33a --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/nclient/Connection.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.nclient; + +import org.apache.qpid.QpidException; + +/** + * This represents a physical connection to a broker. + */ +public interface Connection +{ + /** + * Establish the connection using the given parameters + * + * @param host host name + * @param port port number + * @param virtualHost the virtual host name + * @param username user name + * @param password password + * @throws QpidException If the communication layer fails to establish the connection. + */ + public void connect(String host, int port,String virtualHost,String username, String password) throws QpidException; + + /** + * Establish the connection with the broker identified by the URL. + * + * @param url Specifies the URL of the broker. + * @throws QpidException If the communication layer fails to connect with the broker, an exception is thrown. + */ + public void connect(String url) throws QpidException; + + /** + * Close this connection. + * + * @throws QpidException if the communication layer fails to close the connection. + */ + public void close() throws QpidException; + + /** + * Create a session for this connection. + *

The returned session is suspended + * (i.e. this session is not attached to an underlying channel) + * + * @param expiryInSeconds Expiry time expressed in seconds, if the value is less than + * or equal to 0 then the session does not expire. + * @return A newly created (suspended) session. + */ + public Session createSession(long expiryInSeconds); + + /** + * Create a DtxSession for this connection. + *

A Dtx Session must be used when resources have to be manipulated as + * part of a global transaction. + *

The retuned DtxSession is suspended + * (i.e. this session is not attached with an underlying channel) + * + * @param expiryInSeconds Expiry time expressed in seconds, if the value is less than or equal + * to 0 then the session does not expire. + * @return A newly created (suspended) DtxSession. + */ + public DtxSession createDTXSession(int expiryInSeconds); + + /** + * If the communication layer detects a serious problem with a connection, it + * informs the connection's ClosedListener + * + * @param exceptionListner The ClosedListener + */ + public void setClosedListener(ClosedListener exceptionListner); +} diff --git a/java/client/src/main/java/org/apache/qpid/nclient/DtxSession.java b/java/client/src/main/java/org/apache/qpid/nclient/DtxSession.java new file mode 100644 index 0000000000..8a859f2d84 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/nclient/DtxSession.java @@ -0,0 +1,137 @@ +/* + * 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.nclient; + +import org.apache.qpid.transport.Future; +import org.apache.qpid.transport.GetTimeoutResult; +import org.apache.qpid.transport.Option; +import org.apache.qpid.transport.RecoverResult; +import org.apache.qpid.transport.XaResult; +import org.apache.qpid.transport.Xid; + +/** + * The resources for this session are controlled under the scope of a distributed transaction. + */ +public interface DtxSession extends Session +{ + + /** + * This method is called when messages should be produced and consumed on behalf a transaction + * branch identified by xid. + * possible options are: + *

    + *
  • {@link Option#JOIN}: Indicate that the start applies to joining a transaction previously seen. + *
  • {@link Option#RESUME}: Indicate that the start applies to resuming a suspended transaction branch specified. + *
+ * + * @param xid Specifies the xid of the transaction branch to be started. + * @param options Possible options are: {@link Option#JOIN} and {@link Option#RESUME}. + * @return Confirms to the client that the transaction branch is started or specify the error condition. + */ + public Future dtxStart(Xid xid, Option... options); + + /** + * This method is called when the work done on behalf of a transaction branch finishes or needs to + * be suspended. + * possible options are: + *
    + *
  • {@link Option#FAIL}: indicates that this portion of work has failed; + * otherwise this portion of work has + * completed successfully. + *
  • {@link Option#SUSPEND}: Indicates that the transaction branch is + * temporarily suspended in an incomplete state. + *
+ * + * @param xid Specifies the xid of the transaction branch to be ended. + * @param options Available options are: {@link Option#FAIL} and {@link Option#SUSPEND}. + * @return Confirms to the client that the transaction branch is ended or specifies the error condition. + */ + public Future dtxEnd(Xid xid, Option... options); + + /** + * Commit the work done on behalf of a transaction branch. This method commits the work associated + * with xid. Any produced messages are made available and any consumed messages are discarded. + * The only possible option is: + *
    + *
  • {@link Option#ONE_PHASE}: When set, one-phase commit optimization is used. + *
+ * + * @param xid Specifies the xid of the transaction branch to be committed. + * @param options Available option is: {@link Option#ONE_PHASE} + * @return Confirms to the client that the transaction branch is committed or specifies the error condition. + */ + public Future dtxCommit(Xid xid, Option... options); + + /** + * This method is called to forget about a heuristically completed transaction branch. + * + * @param xid Specifies the xid of the transaction branch to be forgotten. + */ + public void dtxForget(Xid xid, Option ... options); + + /** + * This method obtains the current transaction timeout value in seconds. If set-timeout was not + * used prior to invoking this method, the return value is the default timeout value; otherwise, the + * value used in the previous set-timeout call is returned. + * + * @param xid Specifies the xid of the transaction branch used for getting the timeout. + * @return The current transaction timeout value in seconds. + */ + public Future dtxGetTimeout(Xid xid, Option ... options); + + /** + * This method prepares any message produced or consumed on behalf of xid, ready for commitment. + * + * @param xid Specifies the xid of the transaction branch to be prepared. + * @return The status of the prepare operation can be any one of: + * xa-ok: Normal execution. + *

+ * xa-rdonly: The transaction branch was read-only and has been committed. + *

+ * xa-rbrollback: The broker marked the transaction branch rollback-only for an unspecified + * reason. + *

+ * xa-rbtimeout: The work represented by this transaction branch took too long. + */ + public Future dtxPrepare(Xid xid, Option ... options); + + /** + * This method is called to obtain a list of transaction branches that are in a prepared or + * heuristically completed state. + * @return a array of xids to be recovered. + */ + public Future dtxRecover(Option ... options); + + /** + * This method rolls back the work associated with xid. Any produced messages are discarded and + * any consumed messages are re-queued. + * + * @param xid Specifies the xid of the transaction branch to be rolled back. + * @return Confirms to the client that the transaction branch is rolled back or specifies the error condition. + */ + public Future dtxRollback(Xid xid, Option ... options); + + /** + * Sets the specified transaction branch timeout value in seconds. + * + * @param xid Specifies the xid of the transaction branch for setting the timeout. + * @param timeout The transaction timeout value in seconds. + */ + public void dtxSetTimeout(Xid xid, long timeout, Option ... options); +} diff --git a/java/client/src/main/java/org/apache/qpid/nclient/JMSTestCase.java b/java/client/src/main/java/org/apache/qpid/nclient/JMSTestCase.java new file mode 100644 index 0000000000..4e1b9058e6 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/nclient/JMSTestCase.java @@ -0,0 +1,115 @@ + package org.apache.qpid.nclient; + +import java.util.Enumeration; + +import javax.jms.ExceptionListener; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageListener; +import javax.jms.Queue; +import javax.jms.QueueBrowser; + +import org.apache.qpid.client.AMQConnection; +import org.apache.qpid.client.AMQQueue; +import org.apache.qpid.client.AMQTopic; +import org.apache.qpid.framing.AMQShortString; + +public class JMSTestCase +{ + + public static void main(String[] args) + { + + try + { + javax.jms.Connection con = new AMQConnection("qpid:password=pass;username=name@tcp:localhost:5672"); + con.start(); + + javax.jms.Session ssn = con.createSession(false, 1); + + javax.jms.Destination dest = new AMQQueue(new AMQShortString("direct"),"test"); + javax.jms.MessageProducer prod = ssn.createProducer(dest); + QueueBrowser browser = ssn.createBrowser((Queue)dest, "Test = 'test'"); + + javax.jms.TextMessage msg = ssn.createTextMessage(); + msg.setStringProperty("TEST", "test"); + msg.setText("Should get this"); + prod.send(msg); + + javax.jms.TextMessage msg2 = ssn.createTextMessage(); + msg2.setStringProperty("TEST", "test2"); + msg2.setText("Shouldn't get this"); + prod.send(msg2); + + + Enumeration enu = browser.getEnumeration(); + for (;enu.hasMoreElements();) + { + System.out.println(enu.nextElement()); + System.out.println("\n"); + } + + javax.jms.MessageConsumer cons = ssn.createConsumer(dest, "Test = 'test'"); + javax.jms.TextMessage m = null; // (javax.jms.TextMessage)cons.receive(); + cons.setMessageListener(new MessageListener() + { + public void onMessage(Message m) + { + javax.jms.TextMessage m2 = (javax.jms.TextMessage)m; + try + { + System.out.println("headers : " + m2.toString()); + System.out.println("m : " + m2.getText()); + System.out.println("\n\n"); + } + catch(Exception e) + { + e.printStackTrace(); + } + } + + }); + + con.setExceptionListener(new ExceptionListener() + { + public void onException(JMSException e) + { + e.printStackTrace(); + } + }); + + System.out.println("Waiting"); + while (m == null) + { + + } + + System.out.println("Exiting"); + + /*javax.jms.TextMessage msg = ssn.createTextMessage(); + msg.setText("This is a test message"); + msg.setBooleanProperty("targetMessage", false); + prod.send(msg); + + msg.setBooleanProperty("targetMessage", true); + prod.send(msg); + + javax.jms.TextMessage m = (javax.jms.TextMessage)cons.receiveNoWait(); + + if (m == null) + { + System.out.println("message is null"); + } + else + { + System.out.println("message is not null" + m); + }*/ + + } + catch(Exception e) + { + e.printStackTrace(); + } + } + +} diff --git a/java/client/src/main/java/org/apache/qpid/nclient/MessagePartListener.java b/java/client/src/main/java/org/apache/qpid/nclient/MessagePartListener.java new file mode 100644 index 0000000000..2fdc74fc09 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/nclient/MessagePartListener.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.nclient; + +import java.nio.ByteBuffer; + +import org.apache.qpid.transport.Header; + +/** + * Assembles message parts. + *

The sequence of event for transferring a message is as follows: + *

    + *
  • messageHeaders + *
  • n calls to addData + *
  • messageReceived + *
+ * It is up to the implementation to assemble the message once the different parts + * are transferred. + */ +public interface MessagePartListener +{ + /** + * Indicates the Message transfer has started. + * + * @param transferId The message transfer ID. + */ + public void messageTransfer(int transferId); + + /** + * Add the following a header to the message being received. + * + * @param header Either DeliveryProperties or ApplicationProperties + */ + public void messageHeader(Header header); + + /** + * Add the following byte array to the content of the message being received + * + * @param src Data to be added or streamed. + */ + public void data(ByteBuffer src); + + /** + * Indicates that the message has been fully received. + */ + public void messageReceived(); + +} diff --git a/java/client/src/main/java/org/apache/qpid/nclient/Session.java b/java/client/src/main/java/org/apache/qpid/nclient/Session.java new file mode 100644 index 0000000000..e4daaa094e --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/nclient/Session.java @@ -0,0 +1,595 @@ +/* + * 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.nclient; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.Map; + +import org.apache.qpid.transport.*; +import org.apache.qpid.api.Message; + +/** + *

A session is associated with a connection. + * When it is created, a session is not associated with an underlying channel. + * The session is single threaded.

+ *

+ * All the Session commands are asynchronous. Synchronous behavior is achieved through invoking the sync method. + * For example, command1 will be synchronously invoked by using the following sequence: + *

    + *
  • session.command1() + *
  • session.sync() + *
+ */ +public interface Session +{ + public static final short TRANSFER_ACQUIRE_MODE_NO_ACQUIRE = 1; + public static final short TRANSFER_ACQUIRE_MODE_PRE_ACQUIRE = 0; + public static final short TRANSFER_CONFIRM_MODE_REQUIRED = 0; + public static final short TRANSFER_CONFIRM_MODE_NOT_REQUIRED = 1; + public static final short MESSAGE_FLOW_MODE_CREDIT = 0; + public static final short MESSAGE_FLOW_MODE_WINDOW = 1; + public static final short MESSAGE_FLOW_UNIT_MESSAGE = 0; + public static final short MESSAGE_FLOW_UNIT_BYTE = 1; + public static final long MESSAGE_FLOW_MAX_BYTES = 0xFFFFFFFF; + public static final short MESSAGE_REJECT_CODE_GENERIC = 0; + public static final short MESSAGE_REJECT_CODE_IMMEDIATE_DELIVERY_FAILED = 1; + public static final short MESSAGE_ACQUIRE_ANY_AVAILABLE_MESSAGE = 0; + public static final short MESSAGE_ACQUIRE_MESSAGES_IF_ALL_ARE_AVAILABLE = 1; + + //------------------------------------------------------ + // Session housekeeping methods + //------------------------------------------------------ + + /** + * Sync method will block the session until all outstanding commands + * are executed. + */ + public void sync(); + + public void close(); + + public void sessionDetach(byte[] name, Option ... options); + + public void sessionRequestTimeout(long expiry, Option ... options); + + public byte[] getName(); + + public void setAutoSync(boolean value); + + //------------------------------------------------------ + // Messaging methods + // Producer + //------------------------------------------------------ + /** + * Transfer a message to a specified exchange. + *

+ *

This transfer provides a complete message + * using a single method. The method is internally mapped to messageTransfer() and headers() followed + * by data() and endData(). + * This method should only be used by small messages.

+ * + * @param destination The exchange the message is being sent to. + * @param msg The Message to be sent. + * @param confirmMode
    off ({@link Session#TRANSFER_CONFIRM_MODE_NOT_REQUIRED}): confirmation + * is not required. Once a message has been transferred in pre-acquire + * mode (or once acquire has been sent in no-acquire mode) the message is considered + * transferred. + *

    + *

  • on ({@link Session#TRANSFER_CONFIRM_MODE_REQUIRED}): an acquired message + * is not considered transferred until the original + * transfer is complete. A complete transfer is signaled by execution.complete. + *
+ * @param acquireMode
    + *
  • no-acquire ({@link Session#TRANSFER_ACQUIRE_MODE_NO_ACQUIRE}): the message + * must be explicitly acquired. + *
  • pre-acquire ({@link Session#TRANSFER_ACQUIRE_MODE_PRE_ACQUIRE}): the message is + * acquired when the transfer starts. + *
+ * @throws java.io.IOException If transferring a message fails due to some internal communication error, an exception is thrown. + */ + public void messageTransfer(String destination, Message msg, short confirmMode, short acquireMode) + throws IOException; + + + /** + *

This transfer streams a complete message using a single method. + * It uses pull-semantics instead of doing a push.

+ *

Data is pulled from a Message object using read() + * and pushed using messageTransfer() and headers() followed by data() and endData(). + *
This method should only be used by large messages
+ * There are two convenience Message classes to do this. + *

    + *
  • {@link org.apache.qpid.nclient.util.FileMessage} + *
  • {@link org.apache.qpid.nclient.util.StreamingMessage} + *
+ * You can also implement a Message interface to wrap any + * data stream. + *

+ * + * @param destination The exchange the message is being sent to. + * @param msg The Message to be sent. + * @param confirmMode
    off ({@link Session#TRANSFER_CONFIRM_MODE_NOT_REQUIRED}): confirmation + * is not required. Once a message has been transferred in pre-acquire + * mode (or once acquire has been sent in no-acquire mode) the message is considered + * transferred. + *

    + *

  • on ({@link Session#TRANSFER_CONFIRM_MODE_REQUIRED}): an acquired message + * is not considered transferred until the original + * transfer is complete. A complete transfer is signaled by execution.complete. + *
+ * @param acquireMode
    + *
  • no-acquire ({@link Session#TRANSFER_ACQUIRE_MODE_NO_ACQUIRE}): the message + * must be explicitly acquired. + *
  • pre-acquire ({@link Session#TRANSFER_ACQUIRE_MODE_PRE_ACQUIRE}): the message + * is acquired when the transfer starts. + *
+ * @throws java.io.IOException If transferring a message fails due to some internal communication error, an exception is thrown. + */ + public void messageStream(String destination, Message msg, short confirmMode, short acquireMode) throws IOException; + + /** + * This command transfers a message between two peers. + * + * @param destination Specifies the destination to which the message is to be transferred. + * @param acceptMode Indicates whether message.accept, session.complete, + * or nothing at all is required to indicate successful transfer of the message. + * + * @param acquireMode Indicates whether or not the transferred message has been acquired. + */ + public void messageTransfer(String destination, MessageAcceptMode acceptMode, MessageAcquireMode acquireMode, + Option ... options); + + /** + * Make a set of headers to be sent together with a message + * + * @param headers headers to be added + * @see org.apache.qpid.transport.DeliveryProperties + * @see org.apache.qpid.transport.MessageProperties + * @return The added headers. + */ + public Header header(Struct... headers); + + /** + * Add a byte array to the content of the message being sent. + * + * @param data Data to be added. + */ + public void data(byte[] data); + + /** + * A Add a ByteBuffer to the content of the message being sent. + *

Note that only the data between the buffer's current position and the + * buffer limit is added. + * It is therefore recommended to flip the buffer before adding it to the message, + * + * @param buf Data to be added. + */ + public void data(ByteBuffer buf); + + /** + * Add a string to the content of the message being sent. + * + * @param str String to be added. + */ + public void data(String str); + + /** + * Signals the end of data for the message. + */ + public void endData(); + + //------------------------------------------------------ + // Messaging methods + // Consumer + //------------------------------------------------------ + + /** + * Associate a message listener with a destination. + *

The destination is bound to a queue, and messages are filtered based + * on the provider filter map (message filtering is specific to the provider and in some cases might not be handled). + *

The valid options are: + *

    + *
  • {@link Option#EXCLUSIVE}:

    Requests exclusive subscription access, so that only this + * subscription can access the queue. + *

  • {@link Option#NONE}:

    This is an empty option, and has no effect. + *

+ * + * @param queue The queue that the receiver is receiving messages from. + * @param destination The destination, or delivery tag, for the subscriber. + * @param confirmMode
    off ({@link Session#TRANSFER_CONFIRM_MODE_NOT_REQUIRED}): confirmation + * is not required. Once a message has been transferred in pre-acquire + * mode (or once acquire has been sent in no-acquire mode) the message is considered + * transferred. + *

    + *

  • on ({@link Session#TRANSFER_CONFIRM_MODE_REQUIRED}): an acquired message + * is not considered transferred until the original + * transfer is complete. A complete transfer is signaled by execution.complete. + *
+ * @param acquireMode
    + *
  • no-acquire ({@link Session#TRANSFER_ACQUIRE_MODE_NO_ACQUIRE}): the message must + * be explicitly acquired. + *
  • pre-acquire ({@link Session#TRANSFER_ACQUIRE_MODE_PRE_ACQUIRE}): the message is + * acquired when the transfer starts. + *
+ * @param listener The listener for this destination. To transfer large messages + * use a {@link org.apache.qpid.nclient.MessagePartListener}. + * @param options Set of options. Valid options are {{@link Option#EXCLUSIVE} + * and {@link Option#NONE}. + * @param filter A set of filters for the subscription. The syntax and semantics of these filters varies + * according to the provider's implementation. + */ + public void messageSubscribe(String queue, String destination, short confirmMode, short acquireMode, + MessagePartListener listener, Map filter, Option... options); + + /** + * This method cancels a consumer. The server will not send any more messages to the specified destination. + * This does not affect already delivered messages. + * The client may receive a + * number of messages in between sending the cancel method and receiving + * notification that the cancellation has been completed. + * + * @param destination The destination to be cancelled. + */ + public void messageCancel(String destination, Option ... options); + + /** + * Associate a message listener with a destination. + *

Only one listener is permitted for each destination. When a new listener is created, + * it replaces the previous message listener. To prevent message loss, this occurs only when the original listener + * has completed processing a message. + * + * @param destination The destination the listener is associated with. + * @param listener The new listener for this destination. + */ + public void setMessageListener(String destination, MessagePartListener listener); + + /** + * Sets the mode of flow control used for a given destination. + *

With credit based flow control, the broker continually maintains its current + * credit balance with the recipient. The credit balance consists of two values, a message + * count, and a byte count. Whenever message data is sent, both counts must be decremented. + * If either value reaches zero, the flow of message data must stop. Additional credit is + * received via the {@link Session#messageFlow} method. + *

Window based flow control is identical to credit based flow control, however message + * acknowledgment implicitly grants a single unit of message credit, and the size of the + * message in byte credits for each acknowledged message. + * + * @param destination The destination to set the flow mode on. + * @param mode

  • credit ({@link Session#MESSAGE_FLOW_MODE_CREDIT}): choose credit based flow control + *
  • window ({@link Session#MESSAGE_FLOW_MODE_WINDOW}): choose window based flow control
+ */ + public void messageSetFlowMode(String destination, MessageFlowMode mode, Option ... options); + + + /** + * This method controls the flow of message data to a given destination. It is used by the + * recipient of messages to dynamically match the incoming rate of message flow to its + * processing or forwarding capacity. Upon receipt of this method, the sender must add "value" + * number of the specified unit to the available credit balance for the specified destination. + * A value of 0 indicates an infinite amount of credit. This disables any limit for + * the given unit until the credit balance is zeroed with {@link Session#messageStop} + * or {@link Session#messageFlush}. + * + * @param destination The destination to set the flow. + * @param unit Specifies the unit of credit balance. + *

+ * One of:

    + *
  • message ({@link Session#MESSAGE_FLOW_UNIT_MESSAGE}) + *
  • byte ({@link Session#MESSAGE_FLOW_UNIT_BYTE}) + *
+ * @param value Number of credits, a value of 0 indicates an infinite amount of credit. + */ + public void messageFlow(String destination, MessageCreditUnit unit, long value, Option ... options); + + /** + * Forces the broker to exhaust its credit supply. + *

The credit on the broker will remain at zero once + * this method is completed. + * + * @param destination The destination on which the credit supply is to be exhausted. + */ + public void messageFlush(String destination, Option ... options); + + /** + * On receipt of this method, the brokers set credit to zero for a given + * destination. When confirmation of this method + * is issued credit is set to zero. No further messages will be sent until + * further credit is received. + * + * @param destination The destination on which to reset credit. + */ + public void messageStop(String destination, Option ... options); + + /** + * Acknowledge the receipt of a range of messages. + *

Messages must already be acquired, either by receiving them in + * pre-acquire mode or by explicitly acquiring them. + * + * @param ranges Range of messages to be acknowledged. + * @param accept pecify whether to send a message accept to the broker + */ + public void messageAcknowledge(RangeSet ranges, boolean accept); + + /** + * Reject a range of acquired messages. + *

The broker will deliver rejected messages to the + * alternate-exchange on the queue from which it came. If no alternate-exchange is + * defined for that queue the broker will discard the message. + * + * @param ranges Range of messages to be rejected. + * @param code The reject code must be one of {@link Session#MESSAGE_REJECT_CODE_GENERIC} or + * {@link Session#MESSAGE_REJECT_CODE_IMMEDIATE_DELIVERY_FAILED} (immediate delivery was attempted but + * failed). + * @param text String describing the reason for a message transfer rejection. + */ + public void messageReject(RangeSet ranges, MessageRejectCode code, String text, Option ... options); + + /** + * As it is possible that the broker does not manage to reject some messages, after completion of + * {@link Session#messageReject} this method will return the ranges of rejected messages. + *

Note that {@link Session#messageReject} and this methods are asynchronous therefore for accessing to the + * previously rejected messages this method must be invoked in conjunction with {@link Session#sync()}. + *

A recommended invocation sequence would be: + *

    + *
  • {@link Session#messageReject} + *
  • {@link Session#sync()} + *
  • {@link Session#getRejectedMessages()} + *
+ * + * @return The rejected message ranges + */ + public RangeSet getRejectedMessages(); + + /** + * Try to acquire ranges of messages hence releasing them form the queue. + * This means that once acknowledged, a message will not be delivered to any other receiver. + *

As those messages may have been consumed by another receivers hence, + * message acquisition can fail. + * The outcome of the acquisition is returned as an array of ranges of qcquired messages. + *

This method should only be called on non-acquired messages. + * + * @param ranges Ranges of messages to be acquired. + * @return Indicates the acquired messages + */ + public Future messageAcquire(RangeSet ranges, Option ... options); + + /** + * Give up responsibility for processing ranges of messages. + *

Released messages are re-enqueued. + * + * @param ranges Ranges of messages to be released. + * @param options Valid option is: {@link Option#SET_REDELIVERED}) + */ + public void messageRelease(RangeSet ranges, Option ... options); + + // ----------------------------------------------- + // Local transaction methods + // ---------------------------------------------- + /** + * Selects the session for local transaction support. + */ + public void txSelect(Option ... options); + + /** + * Commit the receipt and delivery of all messages exchanged by this session's resources. + * + * @throws IllegalStateException If this session is not transacted, an exception will be thrown. + */ + public void txCommit(Option ... options) throws IllegalStateException; + + /** + * Roll back the receipt and delivery of all messages exchanged by this session's resources. + * + * @throws IllegalStateException If this session is not transacted, an exception will be thrown. + */ + public void txRollback(Option ... options) throws IllegalStateException; + + //--------------------------------------------- + // Queue methods + //--------------------------------------------- + + /** + * Declare a queue with the given queueName + *

Following are the valid options: + *

    + *
  • {@link Option#AUTO_DELETE}:

    If this field is set and the exclusive field is also set, + * then the queue is deleted when the connection closes. + * If this field is set and the exclusive field is not set the queue is deleted when all + * the consumers have finished using it. + *

  • {@link Option#DURABLE}:

    If set when creating a new queue, + * the queue will be marked as durable. Durable queues + * remain active when a server restarts. Non-durable queues (transient queues) are purged + * if/when a server restarts. Note that durable queues do not necessarily hold persistent + * messages, although it does not make sense to send persistent messages to a transient + * queue. + *

  • {@link Option#EXCLUSIVE}:

    Exclusive queues can only be used from one connection at a time. + * Once a connection declares an exclusive queue, that queue cannot be used by any other connections until the + * declaring connection closes. + *

  • {@link Option#PASSIVE}:

    If set, the server will not create the queue. + * This field allows the client to assert the presence of a queue without modifying the server state. + *

  • {@link Option#NONE}:

    Has no effect as it represents an empty option. + *

+ *

In the absence of a particular option, the defaul value is false for each option + * + * @param queueName The name of the delcared queue. + * @param alternateExchange If a message is rejected by a queue, then it is sent to the alternate-exchange. A message + * may be rejected by a queue for the following reasons: + *

  1. The queue is deleted when it is not empty; + *
  2. Immediate delivery of a message is requested, but there are no consumers connected to + * the queue.
+ * @param arguments Used for backward compatibility + * @param options Set of Options ( valide options are: {@link Option#AUTO_DELETE}, {@link Option#DURABLE}, + * {@link Option#EXCLUSIVE}, {@link Option#PASSIVE} and {@link Option#NONE}) + * @see Option + */ + public void queueDeclare(String queueName, String alternateExchange, Map arguments, + Option... options); + + /** + * Bind a queue with an exchange. + * + * @param queueName Specifies the name of the queue to bind. If the queue name is empty, refers to the current + * queue for the session, which is the last declared queue. + * @param exchangeName The exchange name. + * @param routingKey Specifies the routing key for the binding. The routing key is used for routing messages + * depending on the exchange configuration. Not all exchanges use a routing key - refer to + * the specific exchange documentation. If the queue name is empty, the server uses the last + * queue declared on the session. If the routing key is also empty, the server uses this + * queue name for the routing key as well. If the queue name is provided but the routing key + * is empty, the server does the binding with that empty routing key. The meaning of empty + * routing keys depends on the exchange implementation. + * @param arguments Used for backward compatibility + */ + public void exchangeBind(String queueName, String exchangeName, String routingKey, Map arguments, + Option ... options); + + /** + * Unbind a queue from an exchange. + * + * @param queueName Specifies the name of the queue to unbind. + * @param exchangeName The name of the exchange to unbind from. + * @param routingKey Specifies the routing key of the binding to unbind. + */ + public void exchangeUnbind(String queueName, String exchangeName, String routingKey, Option ... options); + + /** + * This method removes all messages from a queue. It does not cancel consumers. Purged messages + * are deleted without any formal "undo" mechanism. + * + * @param queueName Specifies the name of the queue to purge. If the queue name is empty, refers to the + * current queue for the session, which is the last declared queue. + */ + public void queuePurge(String queueName, Option ... options); + + /** + * This method deletes a queue. When a queue is deleted any pending messages are sent to a + * dead-letter queue if this is defined in the server configuration, and all consumers on the + * queue are cancelled. + *

Following are the valid options: + *

    + *
  • {@link Option#IF_EMPTY}:

    If set, the server will only delete the queue if it has no messages. + *

  • {@link Option#IF_UNUSED}:

    If set, the server will only delete the queue if it has no consumers. + * If the queue has consumers the server does does not delete it but raises a channel exception instead. + *

  • {@link Option#NONE}:

    Has no effect as it represents an empty option. + *

+ *

+ *

+ *

In the absence of a particular option, the defaul value is false for each option

+ * + * @param queueName Specifies the name of the queue to delete. If the queue name is empty, refers to the + * current queue for the session, which is the last declared queue. + * @param options Set of options (Valid options are: {@link Option#IF_EMPTY}, {@link Option#IF_UNUSED} + * and {@link Option#NONE}) + * @see Option + */ + public void queueDelete(String queueName, Option... options); + + + /** + * This method is used to request information on a particular queue. + * + * @param queueName The name of the queue for which information is requested. + * @return Information on the specified queue. + */ + public Future queueQuery(String queueName, Option ... options); + + + /** + * This method is used to request information on a particular binding. + * + * @param exchange The exchange name. + * @param queue The queue name. + * @param routingKey The routing key + * @param arguments bacward compatibilties params. + * @return Information on the specified binding. + */ + public Future exchangeBound(String exchange, String queue, String routingKey, + Map arguments, Option ... options); + + // -------------------------------------- + // exhcange methods + // -------------------------------------- + + /** + * This method creates an exchange. If the exchange already exists, + * the method verifies the class and checks the details are correct. + *

Valid options are: + *

    + *
  • {@link Option#AUTO_DELETE}:

    If set, the exchange is deleted when all queues have finished using it. + *

  • {@link Option#DURABLE}:

    If set, the exchange will + * be marked as durable. Durable exchanges remain active when a server restarts. Non-durable exchanges (transient + * exchanges) are purged when a server restarts. + *

  • {@link Option#PASSIVE}:

    If set, the server will not create the exchange. + * The client can use this to check whether an exchange exists without modifying the server state. + *

  • {@link Option#NONE}:

    This option is an empty option, and has no effect. + *

+ *

In the absence of a particular option, the defaul value is false for each option

+ * + * @param exchangeName The exchange name. + * @param type Each exchange belongs to one of a set of exchange types implemented by the server. The + * exchange types define the functionality of the exchange - i.e. how messages are routed + * through it. It is not valid or meaningful to attempt to change the type of an existing + * exchange. Default exchange types are: direct, topic, headers and fanout. + * @param alternateExchange In the event that a message cannot be routed, this is the name of the exchange to which + * the message will be sent. + * @param options Set of options (valid options are: {@link Option#AUTO_DELETE}, {@link Option#DURABLE}, + * {@link Option#PASSIVE}, {@link Option#NONE}) + * @param arguments Used for backward compatibility + * @see Option + */ + public void exchangeDeclare(String exchangeName, String type, String alternateExchange, + Map arguments, Option... options); + + /** + * This method deletes an exchange. When an exchange is deleted all queue bindings on the + * exchange are cancelled. + *

Following are the valid options: + *

    + *
  • {@link Option#IF_UNUSED}:

    If set, the server will only delete the exchange if it has no queue bindings. If the + * exchange has queue bindings the server does not delete it but raises a channel exception + * instead. + *

  • {@link Option#NONE}:

    Has no effect as it represents an empty option. + *

+ *

Note that if an option is not set, it will default to false. + * + * @param exchangeName The name of exchange to be deleted. + * @param options Set of options. Valid options are: {@link Option#IF_UNUSED}, {@link Option#NONE}. + * @see Option + */ + public void exchangeDelete(String exchangeName, Option... options); + + + /** + * This method is used to request information about a particular exchange. + * + * @param exchangeName The name of the exchange about which information is requested. If not set, the method will + * return information about the default exchange. + * @return Information on the specified exchange. + */ + public Future exchangeQuery(String exchangeName, Option ... options); + + /** + * If the session receives a sessionClosed with an error code it + * informs the session's exceptionListener + * + * @param exceptionListner The exceptionListener + */ + public void setClosedListener(ClosedListener exceptionListner); +} diff --git a/java/client/src/main/java/org/apache/qpid/nclient/impl/ClientSession.java b/java/client/src/main/java/org/apache/qpid/nclient/impl/ClientSession.java new file mode 100644 index 0000000000..ffde5336f9 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/nclient/impl/ClientSession.java @@ -0,0 +1,206 @@ +package org.apache.qpid.nclient.impl; + +import java.io.EOFException; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.qpid.QpidException; +import org.apache.qpid.api.Message; +import org.apache.qpid.nclient.ClosedListener; +import org.apache.qpid.nclient.MessagePartListener; +import org.apache.qpid.transport.MessageAcceptMode; +import org.apache.qpid.transport.MessageAcquireMode; +import org.apache.qpid.transport.Option; +import org.apache.qpid.transport.Range; +import org.apache.qpid.transport.RangeSet; + +import static org.apache.qpid.transport.Option.*; + +/** + * Implements a Qpid Sesion. + */ +public class ClientSession extends org.apache.qpid.transport.Session implements org.apache.qpid.nclient.DtxSession +{ + static + { + String max = "message_size_before_sync"; // KB's + try + { + MAX_NOT_SYNC_DATA_LENGH = new Long(System.getProperties().getProperty(max, "200000000")); + } + catch (NumberFormatException e) + { + // use default size + MAX_NOT_SYNC_DATA_LENGH = 200000000; + } + String flush = "message_size_before_flush"; + try + { + MAX_NOT_FLUSH_DATA_LENGH = new Long(System.getProperties().getProperty(flush, "2000000")); + } + catch (NumberFormatException e) + { + // use default size + MAX_NOT_FLUSH_DATA_LENGH = 20000000; + } + } + + private static long MAX_NOT_SYNC_DATA_LENGH; + private static long MAX_NOT_FLUSH_DATA_LENGH; + + private Map _messageListeners = new ConcurrentHashMap(); + private ClosedListener _exceptionListner; + private RangeSet _rejectedMessages; + private long _currentDataSizeNotSynced; + private long _currentDataSizeNotFlushed; + + public ClientSession(byte[] name) + { + super(name); + } + + public void messageAcknowledge(RangeSet ranges, boolean accept) + { + for (Range range : ranges) + { + super.processed(range); + } + super.flushProcessed(accept ? BATCH : NONE); + if (accept) + { + messageAccept(ranges); + } + } + + public void messageSubscribe(String queue, String destination, short acceptMode, short acquireMode, MessagePartListener listener, Map filter, Option... options) + { + setMessageListener(destination,listener); + super.messageSubscribe(queue, destination, MessageAcceptMode.get(acceptMode), + MessageAcquireMode.get(acquireMode), null, 0, filter, + options); + } + + public void messageTransfer(String destination, Message msg, short acceptMode, short acquireMode) throws IOException + { + // The javadoc clearly says that this method is suitable for small messages + // therefore reading the content in one shot. + ByteBuffer data = msg.readData(); + super.messageTransfer(destination, MessageAcceptMode.get(acceptMode), + MessageAcquireMode.get(acquireMode)); + // super.header(msg.getDeliveryProperties(),msg.getMessageProperties() ); + if( msg.getHeader() == null || msg.getDeliveryProperties().isDirty() || msg.getMessageProperties().isDirty() ) + { + msg.setHeader( super.header(msg.getDeliveryProperties(),msg.getMessageProperties()) ); + msg.getDeliveryProperties().setDirty(false); + msg.getMessageProperties().setDirty(false); + } + else + { + super.header(msg.getHeader()); + } + data( data ); + endData(); + } + + public void sync() + { + super.sync(); + _currentDataSizeNotSynced = 0; + } + + /* ------------------------- + * Data methods + * ------------------------*/ + + public void data(ByteBuffer buf) + { + _currentDataSizeNotSynced = _currentDataSizeNotSynced + buf.remaining(); + _currentDataSizeNotFlushed = _currentDataSizeNotFlushed + buf.remaining(); + super.data(buf); + } + + public void data(String str) + { + _currentDataSizeNotSynced = _currentDataSizeNotSynced + str.getBytes().length; + super.data(str); + } + + public void data(byte[] bytes) + { + _currentDataSizeNotSynced = _currentDataSizeNotSynced + bytes.length; + super.data(bytes); + } + + public void messageStream(String destination, Message msg, short acceptMode, short acquireMode) throws IOException + { + super.messageTransfer(destination, MessageAcceptMode.get(acceptMode), + MessageAcquireMode.get(acquireMode)); + super.header(msg.getDeliveryProperties(),msg.getMessageProperties()); + boolean b = true; + int count = 0; + while(b) + { + try + { + System.out.println("count : " + count++); + data(msg.readData()); + } + catch(EOFException e) + { + b = false; + } + } + endData(); + } + + public void endData() + { + super.endData(); + /* if( MAX_NOT_SYNC_DATA_LENGH != -1 && _currentDataSizeNotSynced >= MAX_NOT_SYNC_DATA_LENGH) + { + sync(); + } + if( MAX_NOT_FLUSH_DATA_LENGH != -1 && _currentDataSizeNotFlushed >= MAX_NOT_FLUSH_DATA_LENGH) + { + executionFlush(); + _currentDataSizeNotFlushed = 0; + }*/ + } + + public RangeSet getRejectedMessages() + { + return _rejectedMessages; + } + + public void setMessageListener(String destination, MessagePartListener listener) + { + if (listener == null) + { + throw new IllegalArgumentException("Cannot set message listener to null"); + } + _messageListeners.put(destination, listener); + } + + public void setClosedListener(ClosedListener exceptionListner) + { + _exceptionListner = exceptionListner; + } + + void setRejectedMessages(RangeSet rejectedMessages) + { + _rejectedMessages = rejectedMessages; + } + + void notifyException(QpidException ex) + { + _exceptionListner.onClosed(null, null, null); + } + + Map getMessageListeners() + { + return _messageListeners; + } +} diff --git a/java/client/src/main/java/org/apache/qpid/nclient/impl/ClientSessionDelegate.java b/java/client/src/main/java/org/apache/qpid/nclient/impl/ClientSessionDelegate.java new file mode 100644 index 0000000000..b57fd0a7ed --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/nclient/impl/ClientSessionDelegate.java @@ -0,0 +1,75 @@ +package org.apache.qpid.nclient.impl; + +import java.nio.ByteBuffer; + +import org.apache.qpid.ErrorCode; + +import org.apache.qpid.nclient.MessagePartListener; + +import org.apache.qpid.QpidException; +import org.apache.qpid.transport.Data; +import org.apache.qpid.transport.Header; +import org.apache.qpid.transport.MessageReject; +import org.apache.qpid.transport.MessageTransfer; +import org.apache.qpid.transport.Range; +import org.apache.qpid.transport.Session; +import org.apache.qpid.transport.SessionDetached; +import org.apache.qpid.transport.SessionDelegate; + + +public class ClientSessionDelegate extends SessionDelegate +{ + private MessageTransfer _currentTransfer; + private MessagePartListener _currentMessageListener; + + @Override public void sessionDetached(Session ssn, SessionDetached dtc) + { + ((ClientSession)ssn).notifyException(new QpidException("", ErrorCode.get(dtc.getCode().getValue()),null)); + } + + // -------------------------------------------- + // Message methods + // -------------------------------------------- + @Override public void data(Session ssn, Data data) + { + _currentMessageListener.data(data.getData()); + if (data.isLast()) + { + _currentMessageListener.messageReceived(); + } + } + + @Override public void header(Session ssn, Header header) + { + _currentMessageListener.messageHeader(header); + if( header.hasNoPayload()) + { + _currentMessageListener.data(ByteBuffer.allocate(0)); + _currentMessageListener.messageReceived(); + } + } + + + @Override public void messageTransfer(Session session, MessageTransfer currentTransfer) + { + _currentTransfer = currentTransfer; + _currentMessageListener = ((ClientSession)session).getMessageListeners().get(currentTransfer.getDestination()); + _currentMessageListener.messageTransfer(currentTransfer.getId()); + } + + @Override public void messageReject(Session session, MessageReject struct) + { + for (Range range : struct.getTransfers()) + { + for (long l = range.getLower(); l <= range.getUpper(); l++) + { + System.out.println("message rejected: " + + session.getCommand((int) l)); + } + } + ((ClientSession)session).setRejectedMessages(struct.getTransfers()); + ((ClientSession)session).notifyException(new QpidException("Message Rejected",ErrorCode.MESSAGE_REJECTED,null)); + session.processed(struct); + } + +} diff --git a/java/client/src/main/java/org/apache/qpid/nclient/impl/Constants.java b/java/client/src/main/java/org/apache/qpid/nclient/impl/Constants.java new file mode 100644 index 0000000000..f689e9abde --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/nclient/impl/Constants.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.nclient.impl; + +/** + * This class holds all the 0.10 client constants which value can be set + * through properties. + */ +public class Constants +{ + static + { + + String max="message_size_before_sync";// KB's + try + { + MAX_NOT_SYNC_DATA_LENGH=new Long(System.getProperties().getProperty(max, "200000000")); + } + catch (NumberFormatException e) + { + // use default size + MAX_NOT_SYNC_DATA_LENGH=200000000; + } + String flush="message_size_before_flush"; + try + { + MAX_NOT_FLUSH_DATA_LENGH=new Long(System.getProperties().getProperty(flush, "2000000")); + } + catch (NumberFormatException e) + { + // use default size + MAX_NOT_FLUSH_DATA_LENGH=20000000; + } + } + + /** + * The total message size in KBs that can be transferted before + * client and broker are synchronized. + * A sync will result in the client library releasing the sent messages + * from memory. (messages are kept + * in memory so client can reconnect to a broker in the event of a failure) + *

+ * Property name: message_size_before_sync + *

+ * Default value: 200000000 + */ + public static long MAX_NOT_SYNC_DATA_LENGH; + /** + * The total message size in KBs that can be transferted before + * messages are flushed. + * When a flush returns all messages have reached the broker. + *

+ * Property name: message_size_before_flush + *

+ * Default value: 200000000 + */ + public static long MAX_NOT_FLUSH_DATA_LENGH; + +} diff --git a/java/client/src/main/java/org/apache/qpid/nclient/impl/DemoClient.java b/java/client/src/main/java/org/apache/qpid/nclient/impl/DemoClient.java new file mode 100644 index 0000000000..96e1d2c772 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/nclient/impl/DemoClient.java @@ -0,0 +1,94 @@ +package org.apache.qpid.nclient.impl; + +import org.apache.qpid.ErrorCode; +import org.apache.qpid.api.Message; +import org.apache.qpid.nclient.Client; +import org.apache.qpid.nclient.Connection; +import org.apache.qpid.nclient.ClosedListener; +import org.apache.qpid.nclient.Session; +import org.apache.qpid.nclient.util.MessageListener; +import org.apache.qpid.nclient.util.MessagePartListenerAdapter; +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.MessageAcceptMode; +import org.apache.qpid.transport.MessageAcquireMode; +import org.apache.qpid.transport.MessageProperties; + +import java.util.UUID; + +public class DemoClient +{ + public static MessagePartListenerAdapter createAdapter() + { + return new MessagePartListenerAdapter(new MessageListener() + { + public void onMessage(Message m) + { + System.out.println("\n================== Received Msg =================="); + System.out.println("Message Id : " + m.getMessageProperties().getMessageId()); + System.out.println(m.toString()); + System.out.println("================== End Msg ==================\n"); + } + + }); + } + + public static final void main(String[] args) + { + Connection conn = Client.createConnection(); + try{ + conn.connect("0.0.0.0", 5672, "test", "guest", "guest"); + }catch(Exception e){ + e.printStackTrace(); + } + + Session ssn = conn.createSession(50000); + ssn.setClosedListener(new ClosedListener() + { + public void onClosed(ErrorCode errorCode, String reason, Throwable t) + { + System.out.println("ErrorCode : " + errorCode + " reason : " + reason); + } + }); + ssn.queueDeclare("queue1", null, null); + ssn.exchangeBind("queue1", "amq.direct", "queue1",null); + ssn.sync(); + + ssn.messageSubscribe("queue1", "myDest", (short)0, (short)0,createAdapter(), null); + + // queue + ssn.messageTransfer("amq.direct", MessageAcceptMode.NONE, MessageAcquireMode.PRE_ACQUIRED); + ssn.header(new DeliveryProperties().setRoutingKey("queue1"), + new MessageProperties().setMessageId(UUID.randomUUID())); + ssn.data("this is the data"); + ssn.endData(); + + //reject + ssn.messageTransfer("amq.direct", MessageAcceptMode.NONE, MessageAcquireMode.PRE_ACQUIRED); + ssn.data("this should be rejected"); + ssn.header(new DeliveryProperties().setRoutingKey("stocks")); + ssn.endData(); + ssn.sync(); + + // topic subs + ssn.messageSubscribe("topic1", "myDest2", (short)0, (short)0,createAdapter(), null); + ssn.messageSubscribe("topic2", "myDest3", (short)0, (short)0,createAdapter(), null); + ssn.messageSubscribe("topic3", "myDest4", (short)0, (short)0,createAdapter(), null); + ssn.sync(); + + ssn.queueDeclare("topic1", null, null); + ssn.exchangeBind("topic1", "amq.topic", "stock.*",null); + ssn.queueDeclare("topic2", null, null); + ssn.exchangeBind("topic2", "amq.topic", "stock.us.*",null); + ssn.queueDeclare("topic3", null, null); + ssn.exchangeBind("topic3", "amq.topic", "stock.us.rh",null); + ssn.sync(); + + // topic + ssn.messageTransfer("amq.topic", MessageAcceptMode.NONE, MessageAcquireMode.PRE_ACQUIRED); + ssn.data("Topic message"); + ssn.header(new DeliveryProperties().setRoutingKey("stock.us.ibm"), + new MessageProperties().setMessageId(UUID.randomUUID())); + ssn.endData(); + } + +} diff --git a/java/client/src/main/java/org/apache/qpid/nclient/impl/LargeMsgDemoClient.java b/java/client/src/main/java/org/apache/qpid/nclient/impl/LargeMsgDemoClient.java new file mode 100644 index 0000000000..36c0a4b3be --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/nclient/impl/LargeMsgDemoClient.java @@ -0,0 +1,76 @@ +package org.apache.qpid.nclient.impl; + +import java.io.FileInputStream; + +import org.apache.qpid.ErrorCode; +import org.apache.qpid.api.Message; +import org.apache.qpid.nclient.Client; +import org.apache.qpid.nclient.Connection; +import org.apache.qpid.nclient.ClosedListener; +import org.apache.qpid.nclient.Session; +import org.apache.qpid.nclient.util.FileMessage; +import org.apache.qpid.nclient.util.MessageListener; +import org.apache.qpid.nclient.util.MessagePartListenerAdapter; +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.MessageProperties; + +import java.util.UUID; + +public class LargeMsgDemoClient +{ + public static MessagePartListenerAdapter createAdapter() + { + return new MessagePartListenerAdapter(new MessageListener() + { + public void onMessage(Message m) + { + System.out.println("\n================== Received Msg =================="); + System.out.println("Message Id : " + m.getMessageProperties().getMessageId()); + System.out.println(m.toString()); + System.out.println("================== End Msg ==================\n"); + } + + }); + } + + public static final void main(String[] args) + { + Connection conn = Client.createConnection(); + try{ + conn.connect("0.0.0.0", 5672, "test", "guest", "guest"); + }catch(Exception e){ + e.printStackTrace(); + } + + Session ssn = conn.createSession(50000); + ssn.setClosedListener(new ClosedListener() + { + public void onClosed(ErrorCode errorCode, String reason, Throwable t) + { + System.out.println("ErrorCode : " + errorCode + " reason : " + reason); + } + }); + ssn.queueDeclare("queue1", null, null); + ssn.exchangeBind("queue1", "amq.direct", "queue1",null); + ssn.sync(); + + ssn.messageSubscribe("queue1", "myDest", (short)0, (short)0,createAdapter(), null); + + try + { + FileMessage msg = new FileMessage(new FileInputStream("/home/rajith/TestFile"), + 1024, + new DeliveryProperties().setRoutingKey("queue1"), + new MessageProperties().setMessageId(UUID.randomUUID())); + + // queue + ssn.messageStream("amq.direct",msg, (short) 0, (short) 1); + ssn.sync(); + } + catch(Exception e) + { + e.printStackTrace(); + } + } + +} diff --git a/java/client/src/main/java/org/apache/qpid/nclient/interop/BasicInteropTest.java b/java/client/src/main/java/org/apache/qpid/nclient/interop/BasicInteropTest.java new file mode 100644 index 0000000000..513c1a95de --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/nclient/interop/BasicInteropTest.java @@ -0,0 +1,156 @@ +package org.apache.qpid.nclient.interop; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.qpid.ErrorCode; +import org.apache.qpid.QpidException; +import org.apache.qpid.api.Message; +import org.apache.qpid.nclient.Client; +import org.apache.qpid.nclient.Connection; +import org.apache.qpid.nclient.ClosedListener; +import org.apache.qpid.nclient.Session; +import org.apache.qpid.nclient.util.MessageListener; +import org.apache.qpid.nclient.util.MessagePartListenerAdapter; +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.MessageProperties; +import org.apache.qpid.transport.RangeSet; + +public class BasicInteropTest implements ClosedListener +{ + + private Session session; + private Connection conn; + private String host; + + public BasicInteropTest(String host) + { + this.host = host; + } + + public void close() throws QpidException + { + conn.close(); + } + + public void testCreateConnection(){ + System.out.println("------- Creating connection--------"); + conn = Client.createConnection(); + try{ + conn.connect(host, 5672, "test", "guest", "guest"); + }catch(Exception e){ + System.out.println("------- Error Creating connection--------"); + e.printStackTrace(); + System.exit(1); + } + System.out.println("------- Connection created Suscessfully --------"); + } + + public void testCreateSession(){ + System.out.println("------- Creating session --------"); + session = conn.createSession(0); + System.out.println("------- Session created sucessfully --------"); + } + + public void testExchange(){ + System.out.println("------- Creating an exchange --------"); + session.exchangeDeclare("test", "direct", "", null); + session.sync(); + System.out.println("------- Exchange created --------"); + } + + public void testQueue(){ + System.out.println("------- Creating a queue --------"); + session.queueDeclare("testQueue", "", null); + session.sync(); + System.out.println("------- Queue created --------"); + + System.out.println("------- Binding a queue --------"); + session.exchangeBind("testQueue", "test", "testKey", null); + session.sync(); + System.out.println("------- Queue bound --------"); + } + + public void testSendMessage(){ + System.out.println("------- Sending a message --------"); + session.messageTransfer("test", MessageAcceptMode.NONE, MessageAcquireMode.PRE_ACQUIRED); + + Map props = new HashMap(); + props.put("name", "rajith"); + props.put("age", 10); + props.put("spf", 8.5); + session.header(new DeliveryProperties().setRoutingKey("testKey"),new MessageProperties().setApplicationHeaders(props)); + + //session.header(new DeliveryProperties().setRoutingKey("testKey")); + + session.data("TestMessage"); + session.endData(); + session.sync(); + System.out.println("------- Message sent --------"); + } + + public void testSubscribe() + { + System.out.println("------- Sending a subscribe --------"); + session.messageSubscribe("testQueue", "myDest", + Session.TRANSFER_CONFIRM_MODE_REQUIRED, + Session.TRANSFER_ACQUIRE_MODE_PRE_ACQUIRE, + new MessagePartListenerAdapter(new MessageListener(){ + + public void onMessage(Message message) + { + System.out.println("--------Message Received--------"); + System.out.println(message.toString()); + System.out.println("--------/Message Received--------"); + RangeSet ack = new RangeSet(); + ack.add(message.getMessageTransferId(),message.getMessageTransferId()); + session.messageAcknowledge(ack, true); + } + + }), + null); + + System.out.println("------- Setting Credit mode --------"); + session.messageSetFlowMode("myDest", MessageFlowMode.WINDOW); + System.out.println("------- Setting Credit --------"); + session.messageFlow("myDest", MessageCreditUnit.MESSAGE, 1); + session.messageFlow("myDest", MessageCreditUnit.BYTE, -1); + } + + public void testMessageFlush() + { + session.messageFlush("myDest"); + session.sync(); + } + + public void onClosed(ErrorCode errorCode, String reason, Throwable t) + { + System.out.println("------- Broker Notified an error --------"); + System.out.println("------- " + errorCode + " --------"); + System.out.println("------- " + reason + " --------"); + System.out.println("------- /Broker Notified an error --------"); + } + + public static void main(String[] args) throws QpidException + { + String host = "0.0.0.0"; + if (args.length>0) + { + host = args[0]; + } + + BasicInteropTest t = new BasicInteropTest(host); + t.testCreateConnection(); + t.testCreateSession(); + t.testExchange(); + t.testQueue(); + t.testSubscribe(); + t.testSendMessage(); + t.testMessageFlush(); + t.close(); + } +} diff --git a/java/client/src/main/java/org/apache/qpid/nclient/util/ByteBufferMessage.java b/java/client/src/main/java/org/apache/qpid/nclient/util/ByteBufferMessage.java new file mode 100644 index 0000000000..8973127105 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/nclient/util/ByteBufferMessage.java @@ -0,0 +1,160 @@ +package org.apache.qpid.nclient.util; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.LinkedList; +import java.util.Queue; + +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.MessageProperties; +import org.apache.qpid.transport.Header; +import org.apache.qpid.api.Message; + +/** + *

A Simple implementation of the message interface + * for small messages. When the readData methods are called + * we assume the message is complete. i.e there want be any + * appendData operations after that.

+ * + *

If you need large message support please see + * FileMessage and StreamingMessage + *

+ */ +public class ByteBufferMessage implements Message +{ + private Queue _data = new LinkedList(); + private ByteBuffer _readBuffer; + private int _dataSize; + private DeliveryProperties _currentDeliveryProps; + private MessageProperties _currentMessageProps; + private int _transferId; + private Header _header; + + public void setHeader(Header header) { + _header = header; + } + + public Header getHeader() { + return _header; + } + + public ByteBufferMessage() + { + _currentDeliveryProps = new DeliveryProperties(); + _currentMessageProps = new MessageProperties(); + } + + public ByteBufferMessage(int transferId) + { + _transferId = transferId; + } + + public int getMessageTransferId() + { + return _transferId; + } + + public void clearData() + { + _data = new LinkedList(); + _readBuffer = null; + } + + public void appendData(byte[] src) throws IOException + { + appendData(ByteBuffer.wrap(src)); + } + + /** + * write the data from the current position up to the buffer limit + */ + public void appendData(ByteBuffer src) throws IOException + { + _data.offer(src); + _dataSize += src.remaining(); + } + + public DeliveryProperties getDeliveryProperties() + { + return _currentDeliveryProps; + } + + public MessageProperties getMessageProperties() + { + return _currentMessageProps; + } + + public void setDeliveryProperties(DeliveryProperties props) + { + _currentDeliveryProps = props; + } + + public void setMessageProperties(MessageProperties props) + { + _currentMessageProps = props; + } + + public void readData(byte[] target) throws IOException + { + getReadBuffer().get(target); + } + + public ByteBuffer readData() throws IOException + { + return getReadBuffer(); + } + + private void buildReadBuffer() + { + //optimize for the simple cases + if(_data.size() == 1) + { + _readBuffer = _data.element().duplicate(); + } + else + { + _readBuffer = ByteBuffer.allocate(_dataSize); + for(ByteBuffer buf:_data) + { + _readBuffer.put(buf); + } + _readBuffer.flip(); + } + } + + private ByteBuffer getReadBuffer() throws IOException + { + if (_readBuffer != null ) + { + return _readBuffer.slice(); + } + else + { + if (_data.size() >0) + { + buildReadBuffer(); + return _readBuffer.slice(); + } + else + { + throw new IOException("No Data to read"); + } + } + } + + //hack for testing + @Override public String toString() + { + try + { + ByteBuffer temp = getReadBuffer(); + byte[] b = new byte[temp.remaining()]; + temp.get(b); + return new String(b); + } + catch(IOException e) + { + return "No data"; + } + } +} diff --git a/java/client/src/main/java/org/apache/qpid/nclient/util/FileMessage.java b/java/client/src/main/java/org/apache/qpid/nclient/util/FileMessage.java new file mode 100644 index 0000000000..179c91c2e9 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/nclient/util/FileMessage.java @@ -0,0 +1,96 @@ +package org.apache.qpid.nclient.util; + +import java.io.EOFException; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; + +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.MessageProperties; +import org.apache.qpid.transport.Header; +import org.apache.qpid.api.Message; + +/** + * FileMessage provides pull style semantics for + * larges messages backed by a disk. + * Instead of loading all data into memeory it uses + * FileChannel to map regions of the file into memeory + * at a time. + * + * The write methods are not supported. + * + * From the standpoint of performance it is generally + * only worth mapping relatively large files into memory. + * + * FileMessage msg = new FileMessage(in,delProps,msgProps); + * session.messageTransfer(dest,msg,0,0); + * + * The messageTransfer method will read the file in chunks + * and stream it. + * + */ +public class FileMessage extends ReadOnlyMessage implements Message +{ + private FileChannel _fileChannel; + private int _chunkSize; + private long _fileSize; + private long _pos = 0; + + public FileMessage(FileInputStream in,int chunkSize,DeliveryProperties deliveryProperties,MessageProperties messageProperties)throws IOException + { + _messageProperties = messageProperties; + _deliveryProperties = deliveryProperties; + + _fileChannel = in.getChannel(); + _chunkSize = chunkSize; + _fileSize = _fileChannel.size(); + + if (_fileSize <= _chunkSize) + { + _chunkSize = (int)_fileSize; + } + } + + public void setHeader(Header header) { + //To change body of implemented methods use File | Settings | File Templates. + } + + public Header getHeader() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public void readData(byte[] target) throws IOException + { + throw new UnsupportedOperationException(); + } + + public ByteBuffer readData() throws IOException + { + if (_pos == _fileSize) + { + throw new EOFException(); + } + + if (_pos + _chunkSize > _fileSize) + { + _chunkSize = (int)(_fileSize - _pos); + } + MappedByteBuffer bb = _fileChannel.map(FileChannel.MapMode.READ_ONLY, _pos, _chunkSize); + _pos += _chunkSize; + return bb; + } + + /** + * This message is used by an application user to + * provide data to the client library using pull style + * semantics. Since the message is not transfered yet, it + * does not have a transfer id. Hence this method is not + * applicable to this implementation. + */ + public int getMessageTransferId() + { + throw new UnsupportedOperationException(); + } +} diff --git a/java/client/src/main/java/org/apache/qpid/nclient/util/MessageListener.java b/java/client/src/main/java/org/apache/qpid/nclient/util/MessageListener.java new file mode 100644 index 0000000000..c5edd62143 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/nclient/util/MessageListener.java @@ -0,0 +1,34 @@ +/* + * 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.nclient.util; + +import org.apache.qpid.api.Message; + +/** + *A message listener + */ +public interface MessageListener +{ + /** + * Process an incoming message. + * + * @param message The incoming message. + */ + public void onMessage(Message message); +} diff --git a/java/client/src/main/java/org/apache/qpid/nclient/util/MessagePartListenerAdapter.java b/java/client/src/main/java/org/apache/qpid/nclient/util/MessagePartListenerAdapter.java new file mode 100644 index 0000000000..3f1746f48a --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/nclient/util/MessagePartListenerAdapter.java @@ -0,0 +1,59 @@ +package org.apache.qpid.nclient.util; + +import java.io.IOException; +import java.nio.ByteBuffer; + +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.MessageProperties; +import org.apache.qpid.transport.Header; +import org.apache.qpid.nclient.MessagePartListener; + +/** + * This is a simple message assembler. + * Will call onMessage method of the adaptee + * when all message data is read. + * + * This is a good convinience utility for handling + * small messages + */ +public class MessagePartListenerAdapter implements MessagePartListener +{ + MessageListener _adaptee; + ByteBufferMessage _currentMsg; + + public MessagePartListenerAdapter(MessageListener listener) + { + _adaptee = listener; + } + + public void messageTransfer(int transferId) + { + _currentMsg = new ByteBufferMessage(transferId); + } + + public void data(ByteBuffer src) + { + try + { + _currentMsg.appendData(src); + } + catch(IOException e) + { + // A chance for IO exception + // doesn't occur as we are using + // a ByteBuffer + } + } + + public void messageHeader(Header header) + { + _currentMsg.setDeliveryProperties(header.get(DeliveryProperties.class)); + _currentMsg.setMessageProperties(header.get(MessageProperties.class)); + } + + public void messageReceived() + { + _adaptee.onMessage(_currentMsg); + } + +} diff --git a/java/client/src/main/java/org/apache/qpid/nclient/util/ReadOnlyMessage.java b/java/client/src/main/java/org/apache/qpid/nclient/util/ReadOnlyMessage.java new file mode 100644 index 0000000000..6583a95c7e --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/nclient/util/ReadOnlyMessage.java @@ -0,0 +1,38 @@ +package org.apache.qpid.nclient.util; + +import java.nio.ByteBuffer; + +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.MessageProperties; +import org.apache.qpid.api.Message; + +public abstract class ReadOnlyMessage implements Message +{ + MessageProperties _messageProperties; + DeliveryProperties _deliveryProperties; + + public void appendData(byte[] src) + { + throw new UnsupportedOperationException("This Message is read only after the initial source"); + } + + public void appendData(ByteBuffer src) + { + throw new UnsupportedOperationException("This Message is read only after the initial source"); + } + + public DeliveryProperties getDeliveryProperties() + { + return _deliveryProperties; + } + + public MessageProperties getMessageProperties() + { + return _messageProperties; + } + + public void clearData() + { + throw new UnsupportedOperationException("This Message is read only after the initial source, cannot clear data"); + } +} diff --git a/java/client/src/main/java/org/apache/qpid/nclient/util/StreamingMessage.java b/java/client/src/main/java/org/apache/qpid/nclient/util/StreamingMessage.java new file mode 100644 index 0000000000..a4574438ac --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/nclient/util/StreamingMessage.java @@ -0,0 +1,68 @@ +package org.apache.qpid.nclient.util; + +import java.io.EOFException; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.SocketChannel; + +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.MessageProperties; +import org.apache.qpid.transport.Header; +import org.apache.qpid.api.Message; + +public class StreamingMessage extends ReadOnlyMessage implements Message +{ + SocketChannel _socChannel; + private int _chunkSize; + private ByteBuffer _readBuf; + + public Header getHeader() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public void setHeader(Header header) { + //To change body of implemented methods use File | Settings | File Templates. + } + + public StreamingMessage(SocketChannel in,int chunkSize,DeliveryProperties deliveryProperties,MessageProperties messageProperties)throws IOException + { + _messageProperties = messageProperties; + _deliveryProperties = deliveryProperties; + + _socChannel = in; + _chunkSize = chunkSize; + _readBuf = ByteBuffer.allocate(_chunkSize); + } + + public void readData(byte[] target) throws IOException + { + throw new UnsupportedOperationException(); + } + + public ByteBuffer readData() throws IOException + { + if(_socChannel.isConnected() && _socChannel.isOpen()) + { + _readBuf.clear(); + _socChannel.read(_readBuf); + } + else + { + throw new EOFException("The underlying socket/channel has closed"); + } + + return _readBuf.duplicate(); + } + + /** + * This message is used by an application user to + * provide data to the client library using pull style + * semantics. Since the message is not transfered yet, it + * does not have a transfer id. Hence this method is not + * applicable to this implementation. + */ + public int getMessageTransferId() + { + throw new UnsupportedOperationException(); + } +} diff --git a/java/client/src/main/java/org/apache/qpid/njms/ExceptionHelper.java b/java/client/src/main/java/org/apache/qpid/njms/ExceptionHelper.java new file mode 100644 index 0000000000..ce790a3b24 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/njms/ExceptionHelper.java @@ -0,0 +1,60 @@ +/* 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.njms; + +import org.apache.qpid.QpidException; + +import javax.jms.JMSException; +import javax.transaction.xa.XAException; + +/** + * Helper class for handling exceptions + */ +public class ExceptionHelper +{ + static public JMSException convertQpidExceptionToJMSException(Exception exception) + { + JMSException jmsException = null; + if (!(exception instanceof JMSException)) + { + if (exception instanceof QpidException) + { + jmsException = new JMSException(exception.getMessage(), String.valueOf(((QpidException) exception).getErrorCode())); + } + else + { + jmsException = new JMSException(exception.getMessage()); + } + jmsException.setLinkedException(exception); + jmsException.initCause(exception); + } + else + { + jmsException = (JMSException) exception; + } + return jmsException; + } + + static public XAException convertQpidExceptionToXAException(QpidException exception) + { + String qpidErrorCode = String.valueOf(exception.getErrorCode()); + // todo map this error to an XA code + int xaCode = XAException.XAER_PROTO; + return new XAException(xaCode); + } +} diff --git a/java/client/src/main/java/org/apache/qpidity/filter/ArithmeticExpression.java b/java/client/src/main/java/org/apache/qpidity/filter/ArithmeticExpression.java deleted file mode 100644 index 279716598d..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/filter/ArithmeticExpression.java +++ /dev/null @@ -1,268 +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.qpidity.filter; - -import org.apache.qpidity.QpidException; -import org.apache.qpid.client.message.AbstractJMSMessage; - - -/** - * An expression which performs an operation on two expression values - */ -public abstract class ArithmeticExpression extends BinaryExpression -{ - - protected static final int INTEGER = 1; - protected static final int LONG = 2; - protected static final int DOUBLE = 3; - - - public ArithmeticExpression(Expression left, Expression right) - { - super(left, right); - } - - public static Expression createPlus(Expression left, Expression right) - { - return new ArithmeticExpression(left, right) - { - protected Object evaluate(Object lvalue, Object rvalue) - { - if (lvalue instanceof String) - { - String text = (String) lvalue; - return text + rvalue; - } - else if (lvalue instanceof Number) - { - return plus((Number) lvalue, asNumber(rvalue)); - } - - throw new RuntimeException("Cannot call plus operation on: " + lvalue + " and: " + rvalue); - } - - public String getExpressionSymbol() - { - return "+"; - } - }; - } - - public static Expression createMinus(Expression left, Expression right) - { - return new ArithmeticExpression(left, right) - { - protected Object evaluate(Object lvalue, Object rvalue) - { - if (lvalue instanceof Number) - { - return minus((Number) lvalue, asNumber(rvalue)); - } - - throw new RuntimeException("Cannot call minus operation on: " + lvalue + " and: " + rvalue); - } - - public String getExpressionSymbol() - { - return "-"; - } - }; - } - - public static Expression createMultiply(Expression left, Expression right) - { - return new ArithmeticExpression(left, right) - { - - protected Object evaluate(Object lvalue, Object rvalue) - { - if (lvalue instanceof Number) - { - return multiply((Number) lvalue, asNumber(rvalue)); - } - - throw new RuntimeException("Cannot call multiply operation on: " + lvalue + " and: " + rvalue); - } - - public String getExpressionSymbol() - { - return "*"; - } - }; - } - - public static Expression createDivide(Expression left, Expression right) - { - return new ArithmeticExpression(left, right) - { - - protected Object evaluate(Object lvalue, Object rvalue) - { - if (lvalue instanceof Number) - { - return divide((Number) lvalue, asNumber(rvalue)); - } - - throw new RuntimeException("Cannot call divide operation on: " + lvalue + " and: " + rvalue); - } - - public String getExpressionSymbol() - { - return "/"; - } - }; - } - - public static Expression createMod(Expression left, Expression right) - { - return new ArithmeticExpression(left, right) - { - - protected Object evaluate(Object lvalue, Object rvalue) - { - if (lvalue instanceof Number) - { - return mod((Number) lvalue, asNumber(rvalue)); - } - - throw new RuntimeException("Cannot call mod operation on: " + lvalue + " and: " + rvalue); - } - - public String getExpressionSymbol() - { - return "%"; - } - }; - } - - protected Number plus(Number left, Number right) - { - switch (numberType(left, right)) - { - - case ArithmeticExpression.INTEGER: - return new Integer(left.intValue() + right.intValue()); - - case ArithmeticExpression.LONG: - return new Long(left.longValue() + right.longValue()); - - default: - return new Double(left.doubleValue() + right.doubleValue()); - } - } - - protected Number minus(Number left, Number right) - { - switch (numberType(left, right)) - { - - case ArithmeticExpression.INTEGER: - return new Integer(left.intValue() - right.intValue()); - - case ArithmeticExpression.LONG: - return new Long(left.longValue() - right.longValue()); - - default: - return new Double(left.doubleValue() - right.doubleValue()); - } - } - - protected Number multiply(Number left, Number right) - { - switch (numberType(left, right)) - { - - case ArithmeticExpression.INTEGER: - return new Integer(left.intValue() * right.intValue()); - - case ArithmeticExpression.LONG: - return new Long(left.longValue() * right.longValue()); - - default: - return new Double(left.doubleValue() * right.doubleValue()); - } - } - - protected Number divide(Number left, Number right) - { - return new Double(left.doubleValue() / right.doubleValue()); - } - - protected Number mod(Number left, Number right) - { - return new Double(left.doubleValue() % right.doubleValue()); - } - - private int numberType(Number left, Number right) - { - if (isDouble(left) || isDouble(right)) - { - return ArithmeticExpression.DOUBLE; - } - else if ((left instanceof Long) || (right instanceof Long)) - { - return ArithmeticExpression.LONG; - } - else - { - return ArithmeticExpression.INTEGER; - } - } - - private boolean isDouble(Number n) - { - return (n instanceof Float) || (n instanceof Double); - } - - protected Number asNumber(Object value) - { - if (value instanceof Number) - { - return (Number) value; - } - else - { - throw new RuntimeException("Cannot convert value: " + value + " into a number"); - } - } - - public Object evaluate(AbstractJMSMessage message) throws QpidException - { - Object lvalue = left.evaluate(message); - if (lvalue == null) - { - return null; - } - - Object rvalue = right.evaluate(message); - if (rvalue == null) - { - return null; - } - - return evaluate(lvalue, rvalue); - } - - /** - * @param lvalue - * @param rvalue - * @return - */ - protected abstract Object evaluate(Object lvalue, Object rvalue); - -} diff --git a/java/client/src/main/java/org/apache/qpidity/filter/BinaryExpression.java b/java/client/src/main/java/org/apache/qpidity/filter/BinaryExpression.java deleted file mode 100644 index 465b504ae3..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/filter/BinaryExpression.java +++ /dev/null @@ -1,103 +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.qpidity.filter; - -/** - * An expression which performs an operation on two expression values. - */ -public abstract class BinaryExpression implements Expression -{ - protected Expression left; - protected Expression right; - - public BinaryExpression(Expression left, Expression right) - { - this.left = left; - this.right = right; - } - - public Expression getLeft() - { - return left; - } - - public Expression getRight() - { - return right; - } - - /** - * @see Object#toString() - */ - public String toString() - { - return "(" + left.toString() + " " + getExpressionSymbol() + " " + right.toString() + ")"; - } - - /** - * TODO: more efficient hashCode() - * - * @see Object#hashCode() - */ - public int hashCode() - { - return toString().hashCode(); - } - - /** - * TODO: more efficient hashCode() - * - * @see Object#equals(Object) - */ - public boolean equals(Object o) - { - - if ((o == null) || !this.getClass().equals(o.getClass())) - { - return false; - } - - return toString().equals(o.toString()); - - } - - /** - * Returns the symbol that represents this binary expression. For example, addition is - * represented by "+" - * - * @return - */ - public abstract String getExpressionSymbol(); - - /** - * @param expression - */ - public void setRight(Expression expression) - { - right = expression; - } - - /** - * @param expression - */ - public void setLeft(Expression expression) - { - left = expression; - } - -} diff --git a/java/client/src/main/java/org/apache/qpidity/filter/BooleanExpression.java b/java/client/src/main/java/org/apache/qpidity/filter/BooleanExpression.java deleted file mode 100644 index 9a3b1c3106..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/filter/BooleanExpression.java +++ /dev/null @@ -1,33 +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.qpidity.filter; - -import org.apache.qpidity.QpidException; -import org.apache.qpid.client.message.AbstractJMSMessage; - - -/** - * A BooleanExpression is an expression that always - * produces a Boolean result. - */ -public interface BooleanExpression extends Expression -{ - - public boolean matches(AbstractJMSMessage message) throws QpidException; - -} diff --git a/java/client/src/main/java/org/apache/qpidity/filter/ComparisonExpression.java b/java/client/src/main/java/org/apache/qpidity/filter/ComparisonExpression.java deleted file mode 100644 index 46f387b293..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/filter/ComparisonExpression.java +++ /dev/null @@ -1,589 +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.qpidity.filter; - -import org.apache.qpidity.QpidException; -import org.apache.qpid.client.message.AbstractJMSMessage; - -import java.util.HashSet; -import java.util.List; -import java.util.regex.Pattern; - -/** - * A filter performing a comparison of two objects - */ -public abstract class ComparisonExpression extends BinaryExpression implements BooleanExpression -{ - - public static BooleanExpression createBetween(Expression value, Expression left, Expression right) - { - return LogicExpression.createAND(ComparisonExpression.createGreaterThanEqual(value, left), ComparisonExpression.createLessThanEqual(value, right)); - } - - public static BooleanExpression createNotBetween(Expression value, Expression left, Expression right) - { - return LogicExpression.createOR(ComparisonExpression.createLessThan(value, left), ComparisonExpression.createGreaterThan(value, right)); - } - - private static final HashSet REGEXP_CONTROL_CHARS = new HashSet(); - - static - { - ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('.')); - ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('\\')); - ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('[')); - ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character(']')); - ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('^')); - ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('$')); - ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('?')); - ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('*')); - ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('+')); - ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('{')); - ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('}')); - ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('|')); - ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('(')); - ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character(')')); - ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character(':')); - ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('&')); - ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('<')); - ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('>')); - ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('=')); - ComparisonExpression.REGEXP_CONTROL_CHARS.add(new Character('!')); - } - - static class LikeExpression extends UnaryExpression implements BooleanExpression - { - - Pattern likePattern; - - /** - * @param right - */ - public LikeExpression(Expression right, String like, int escape) - { - super(right); - - StringBuffer regexp = new StringBuffer(like.length() * 2); - regexp.append("\\A"); // The beginning of the input - for (int i = 0; i < like.length(); i++) - { - char c = like.charAt(i); - if (escape == (0xFFFF & c)) - { - i++; - if (i >= like.length()) - { - // nothing left to escape... - break; - } - - char t = like.charAt(i); - regexp.append("\\x"); - regexp.append(Integer.toHexString(0xFFFF & t)); - } - else if (c == '%') - { - regexp.append(".*?"); // Do a non-greedy match - } - else if (c == '_') - { - regexp.append("."); // match one - } - else if (ComparisonExpression.REGEXP_CONTROL_CHARS.contains(new Character(c))) - { - regexp.append("\\x"); - regexp.append(Integer.toHexString(0xFFFF & c)); - } - else - { - regexp.append(c); - } - } - - regexp.append("\\z"); // The end of the input - - likePattern = Pattern.compile(regexp.toString(), Pattern.DOTALL); - } - - /** - * org.apache.activemq.filter.UnaryExpression#getExpressionSymbol() - */ - public String getExpressionSymbol() - { - return "LIKE"; - } - - /** - * org.apache.activemq.filter.Expression#evaluate(MessageEvaluationContext) - */ - public Object evaluate(AbstractJMSMessage message) throws QpidException - { - - Object rv = this.getRight().evaluate(message); - - if (rv == null) - { - return null; - } - - if (!(rv instanceof String)) - { - return - Boolean.FALSE; - // throw new RuntimeException("LIKE can only operate on String identifiers. LIKE attemped on: '" + rv.getClass()); - } - - return likePattern.matcher((String) rv).matches() ? Boolean.TRUE : Boolean.FALSE; - } - - public boolean matches(AbstractJMSMessage message) throws QpidException - { - Object object = evaluate(message); - - return (object != null) && (object == Boolean.TRUE); - } - } - - public static BooleanExpression createLike(Expression left, String right, String escape) - { - if ((escape != null) && (escape.length() != 1)) - { - throw new RuntimeException( - "The ESCAPE string litteral is invalid. It can only be one character. Litteral used: " + escape); - } - - int c = -1; - if (escape != null) - { - c = 0xFFFF & escape.charAt(0); - } - - return new LikeExpression(left, right, c); - } - - public static BooleanExpression createNotLike(Expression left, String right, String escape) - { - return UnaryExpression.createNOT(ComparisonExpression.createLike(left, right, escape)); - } - - public static BooleanExpression createInFilter(Expression left, List elements) - { - - if (!(left instanceof PropertyExpression)) - { - throw new RuntimeException("Expected a property for In expression, got: " + left); - } - - return UnaryExpression.createInExpression((PropertyExpression) left, elements, false); - - } - - public static BooleanExpression createNotInFilter(Expression left, List elements) - { - - if (!(left instanceof PropertyExpression)) - { - throw new RuntimeException("Expected a property for In expression, got: " + left); - } - - return UnaryExpression.createInExpression((PropertyExpression) left, elements, true); - - } - - public static BooleanExpression createIsNull(Expression left) - { - return ComparisonExpression.doCreateEqual(left, ConstantExpression.NULL); - } - - public static BooleanExpression createIsNotNull(Expression left) - { - return UnaryExpression.createNOT(ComparisonExpression.doCreateEqual(left, ConstantExpression.NULL)); - } - - public static BooleanExpression createNotEqual(Expression left, Expression right) - { - return UnaryExpression.createNOT(ComparisonExpression.createEqual(left, right)); - } - - public static BooleanExpression createEqual(Expression left, Expression right) - { - ComparisonExpression.checkEqualOperand(left); - ComparisonExpression.checkEqualOperand(right); - ComparisonExpression.checkEqualOperandCompatability(left, right); - - return ComparisonExpression.doCreateEqual(left, right); - } - - private static BooleanExpression doCreateEqual(Expression left, Expression right) - { - return new ComparisonExpression(left, right) - { - - public Object evaluate(AbstractJMSMessage message) throws QpidException - { - Object lv = left.evaluate(message); - Object rv = right.evaluate(message); - - // Iff one of the values is null - if ((lv == null) ^ (rv == null)) - { - return Boolean.FALSE; - } - - if ((lv == rv) || lv.equals(rv)) - { - return Boolean.TRUE; - } - - if ((lv instanceof Comparable) && (rv instanceof Comparable)) - { - return compare((Comparable) lv, (Comparable) rv); - } - - return Boolean.FALSE; - } - - protected boolean asBoolean(int answer) - { - return answer == 0; - } - - public String getExpressionSymbol() - { - return "="; - } - }; - } - - public static BooleanExpression createGreaterThan(final Expression left, final Expression right) - { - ComparisonExpression.checkLessThanOperand(left); - ComparisonExpression.checkLessThanOperand(right); - - return new ComparisonExpression(left, right) - { - protected boolean asBoolean(int answer) - { - return answer > 0; - } - - public String getExpressionSymbol() - { - return ">"; - } - }; - } - - public static BooleanExpression createGreaterThanEqual(final Expression left, final Expression right) - { - ComparisonExpression.checkLessThanOperand(left); - ComparisonExpression.checkLessThanOperand(right); - - return new ComparisonExpression(left, right) - { - protected boolean asBoolean(int answer) - { - return answer >= 0; - } - - public String getExpressionSymbol() - { - return ">="; - } - }; - } - - public static BooleanExpression createLessThan(final Expression left, final Expression right) - { - ComparisonExpression.checkLessThanOperand(left); - ComparisonExpression.checkLessThanOperand(right); - - return new ComparisonExpression(left, right) - { - - protected boolean asBoolean(int answer) - { - return answer < 0; - } - - public String getExpressionSymbol() - { - return "<"; - } - - }; - } - - public static BooleanExpression createLessThanEqual(final Expression left, final Expression right) - { - ComparisonExpression.checkLessThanOperand(left); - ComparisonExpression.checkLessThanOperand(right); - - return new ComparisonExpression(left, right) - { - - protected boolean asBoolean(int answer) - { - return answer <= 0; - } - - public String getExpressionSymbol() - { - return "<="; - } - }; - } - - /** - * Only Numeric expressions can be used in >, >=, < or <= expressions.s - * - * @param expr - */ - public static void checkLessThanOperand(Expression expr) - { - if (expr instanceof ConstantExpression) - { - Object value = ((ConstantExpression) expr).getValue(); - if (value instanceof Number) - { - return; - } - - // Else it's boolean or a String.. - throw new RuntimeException("Value '" + expr + "' cannot be compared."); - } - - if (expr instanceof BooleanExpression) - { - throw new RuntimeException("Value '" + expr + "' cannot be compared."); - } - } - - /** - * Validates that the expression can be used in == or <> expression. - * Cannot not be NULL TRUE or FALSE litterals. - * - * @param expr - */ - public static void checkEqualOperand(Expression expr) - { - if (expr instanceof ConstantExpression) - { - Object value = ((ConstantExpression) expr).getValue(); - if (value == null) - { - throw new RuntimeException("'" + expr + "' cannot be compared."); - } - } - } - - /** - * - * @param left - * @param right - */ - private static void checkEqualOperandCompatability(Expression left, Expression right) - { - if ((left instanceof ConstantExpression) && (right instanceof ConstantExpression)) - { - if ((left instanceof BooleanExpression) && !(right instanceof BooleanExpression)) - { - throw new RuntimeException("'" + left + "' cannot be compared with '" + right + "'"); - } - } - } - - /** - * @param left - * @param right - */ - public ComparisonExpression(Expression left, Expression right) - { - super(left, right); - } - - public Object evaluate(AbstractJMSMessage message) throws QpidException - { - Comparable lv = (Comparable) left.evaluate(message); - if (lv == null) - { - return null; - } - - Comparable rv = (Comparable) right.evaluate(message); - if (rv == null) - { - return null; - } - - return compare(lv, rv); - } - - protected Boolean compare(Comparable lv, Comparable rv) - { - Class lc = lv.getClass(); - Class rc = rv.getClass(); - // If the the objects are not of the same type, - // try to convert up to allow the comparison. - if (lc != rc) - { - if (lc == Byte.class) - { - if (rc == Short.class) - { - lv = new Short(((Number) lv).shortValue()); - } - else if (rc == Integer.class) - { - lv = new Integer(((Number) lv).intValue()); - } - else if (rc == Long.class) - { - lv = new Long(((Number) lv).longValue()); - } - else if (rc == Float.class) - { - lv = new Float(((Number) lv).floatValue()); - } - else if (rc == Double.class) - { - lv = new Double(((Number) lv).doubleValue()); - } - else - { - return Boolean.FALSE; - } - } - else if (lc == Short.class) - { - if (rc == Integer.class) - { - lv = new Integer(((Number) lv).intValue()); - } - else if (rc == Long.class) - { - lv = new Long(((Number) lv).longValue()); - } - else if (rc == Float.class) - { - lv = new Float(((Number) lv).floatValue()); - } - else if (rc == Double.class) - { - lv = new Double(((Number) lv).doubleValue()); - } - else - { - return Boolean.FALSE; - } - } - else if (lc == Integer.class) - { - if (rc == Long.class) - { - lv = new Long(((Number) lv).longValue()); - } - else if (rc == Float.class) - { - lv = new Float(((Number) lv).floatValue()); - } - else if (rc == Double.class) - { - lv = new Double(((Number) lv).doubleValue()); - } - else - { - return Boolean.FALSE; - } - } - else if (lc == Long.class) - { - if (rc == Integer.class) - { - rv = new Long(((Number) rv).longValue()); - } - else if (rc == Float.class) - { - lv = new Float(((Number) lv).floatValue()); - } - else if (rc == Double.class) - { - lv = new Double(((Number) lv).doubleValue()); - } - else - { - return Boolean.FALSE; - } - } - else if (lc == Float.class) - { - if (rc == Integer.class) - { - rv = new Float(((Number) rv).floatValue()); - } - else if (rc == Long.class) - { - rv = new Float(((Number) rv).floatValue()); - } - else if (rc == Double.class) - { - lv = new Double(((Number) lv).doubleValue()); - } - else - { - return Boolean.FALSE; - } - } - else if (lc == Double.class) - { - if (rc == Integer.class) - { - rv = new Double(((Number) rv).doubleValue()); - } - else if (rc == Long.class) - { - rv = new Double(((Number) rv).doubleValue()); - } - else if (rc == Float.class) - { - rv = new Float(((Number) rv).doubleValue()); - } - else - { - return Boolean.FALSE; - } - } - else - { - return Boolean.FALSE; - } - } - - return asBoolean(lv.compareTo(rv)) ? Boolean.TRUE : Boolean.FALSE; - } - - protected abstract boolean asBoolean(int answer); - - public boolean matches(AbstractJMSMessage message) throws QpidException - { - Object object = evaluate(message); - - return (object != null) && (object == Boolean.TRUE); - } - -} diff --git a/java/client/src/main/java/org/apache/qpidity/filter/ConstantExpression.java b/java/client/src/main/java/org/apache/qpidity/filter/ConstantExpression.java deleted file mode 100644 index 26aeec2de8..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/filter/ConstantExpression.java +++ /dev/null @@ -1,204 +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.qpidity.filter; - -import org.apache.qpidity.QpidException; -import org.apache.qpid.client.message.AbstractJMSMessage; - -import java.math.BigDecimal; - -/** - * Represents a constant expression - */ -public class ConstantExpression implements Expression -{ - - static class BooleanConstantExpression extends ConstantExpression implements BooleanExpression - { - public BooleanConstantExpression(Object value) - { - super(value); - } - - public boolean matches(AbstractJMSMessage message) throws QpidException - { - Object object = evaluate(message); - - return (object != null) && (object == Boolean.TRUE); - } - } - - public static final BooleanConstantExpression NULL = new BooleanConstantExpression(null); - public static final BooleanConstantExpression TRUE = new BooleanConstantExpression(Boolean.TRUE); - public static final BooleanConstantExpression FALSE = new BooleanConstantExpression(Boolean.FALSE); - - private Object value; - - public static ConstantExpression createFromDecimal(String text) - { - - // Strip off the 'l' or 'L' if needed. - if (text.endsWith("l") || text.endsWith("L")) - { - text = text.substring(0, text.length() - 1); - } - - Number value; - try - { - value = new Long(text); - } - catch (NumberFormatException e) - { - // The number may be too big to fit in a long. - value = new BigDecimal(text); - } - - long l = value.longValue(); - if ((Integer.MIN_VALUE <= l) && (l <= Integer.MAX_VALUE)) - { - value = new Integer(value.intValue()); - } - - return new ConstantExpression(value); - } - - public static ConstantExpression createFromHex(String text) - { - Number value = new Long(Long.parseLong(text.substring(2), 16)); - long l = value.longValue(); - if ((Integer.MIN_VALUE <= l) && (l <= Integer.MAX_VALUE)) - { - value = new Integer(value.intValue()); - } - - return new ConstantExpression(value); - } - - public static ConstantExpression createFromOctal(String text) - { - Number value = new Long(Long.parseLong(text, 8)); - long l = value.longValue(); - if ((Integer.MIN_VALUE <= l) && (l <= Integer.MAX_VALUE)) - { - value = new Integer(value.intValue()); - } - - return new ConstantExpression(value); - } - - public static ConstantExpression createFloat(String text) - { - Number value = new Double(text); - - return new ConstantExpression(value); - } - - public ConstantExpression(Object value) - { - this.value = value; - } - - public Object evaluate(AbstractJMSMessage message) throws QpidException - { - return value; - } - - public Object getValue() - { - return value; - } - - /** - * @see Object#toString() - */ - public String toString() - { - if (value == null) - { - return "NULL"; - } - - if (value instanceof Boolean) - { - return ((Boolean) value).booleanValue() ? "TRUE" : "FALSE"; - } - - if (value instanceof String) - { - return ConstantExpression.encodeString((String) value); - } - - return value.toString(); - } - - /** - * TODO: more efficient hashCode() - * - * @see Object#hashCode() - */ - public int hashCode() - { - return toString().hashCode(); - } - - /** - * TODO: more efficient hashCode() - * - * @see Object#equals(Object) - */ - public boolean equals(Object o) - { - - if ((o == null) || !this.getClass().equals(o.getClass())) - { - return false; - } - - return toString().equals(o.toString()); - - } - - /** - * Encodes the value of string so that it looks like it would look like - * when it was provided in a selector. - * - * @param s - * @return - */ - public static String encodeString(String s) - { - StringBuffer b = new StringBuffer(); - b.append('\''); - for (int i = 0; i < s.length(); i++) - { - char c = s.charAt(i); - if (c == '\'') - { - b.append(c); - } - - b.append(c); - } - - b.append('\''); - - return b.toString(); - } - -} diff --git a/java/client/src/main/java/org/apache/qpidity/filter/Expression.java b/java/client/src/main/java/org/apache/qpidity/filter/Expression.java deleted file mode 100644 index bdc3c9cccc..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/filter/Expression.java +++ /dev/null @@ -1,34 +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.qpidity.filter; - -import org.apache.qpidity.QpidException; -import org.apache.qpid.client.message.AbstractJMSMessage; - - -/** - * Represents an expression - */ -public interface Expression -{ - /** - * @param message The message to evaluate - * @return the value of this expression - */ - public Object evaluate(AbstractJMSMessage message) throws QpidException; -} diff --git a/java/client/src/main/java/org/apache/qpidity/filter/JMSSelectorFilter.java b/java/client/src/main/java/org/apache/qpidity/filter/JMSSelectorFilter.java deleted file mode 100644 index c73da1682a..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/filter/JMSSelectorFilter.java +++ /dev/null @@ -1,70 +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.qpidity.filter; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.apache.qpidity.QpidException; -import org.apache.qpidity.filter.selector.SelectorParser; -import org.apache.qpid.client.message.AbstractJMSMessage; - - -public class JMSSelectorFilter implements MessageFilter -{ - /** - * this JMSSelectorFilter's logger - */ - private static final Logger _logger = LoggerFactory.getLogger(JMSSelectorFilter.class); - - private String _selector; - private BooleanExpression _matcher; - - public JMSSelectorFilter(String selector) throws QpidException - { - _selector = selector; - if (JMSSelectorFilter._logger.isDebugEnabled()) - { - JMSSelectorFilter._logger.debug("Created JMSSelectorFilter with selector:" + _selector); - } - _matcher = new SelectorParser().parse(selector); - } - - public boolean matches(AbstractJMSMessage message) - { - try - { - boolean match = _matcher.matches(message); - if (JMSSelectorFilter._logger.isDebugEnabled()) - { - JMSSelectorFilter._logger.debug(message + " match(" + match + ") selector(" + System - .identityHashCode(_selector) + "):" + _selector); - } - return match; - } - catch (QpidException e) - { - JMSSelectorFilter._logger.warn("Caght exception when evaluating message selector for message " + message, e); - } - return false; - } - - public String getSelector() - { - return _selector; - } -} diff --git a/java/client/src/main/java/org/apache/qpidity/filter/LogicExpression.java b/java/client/src/main/java/org/apache/qpidity/filter/LogicExpression.java deleted file mode 100644 index 7f5909df43..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/filter/LogicExpression.java +++ /dev/null @@ -1,108 +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.qpidity.filter; - -import org.apache.qpidity.QpidException; -import org.apache.qpid.client.message.AbstractJMSMessage; - - -/** - * A filter performing a comparison of two objects - */ -public abstract class LogicExpression extends BinaryExpression implements BooleanExpression -{ - - public static BooleanExpression createOR(BooleanExpression lvalue, BooleanExpression rvalue) - { - return new LogicExpression(lvalue, rvalue) - { - - public Object evaluate(AbstractJMSMessage message) throws QpidException - { - - Boolean lv = (Boolean) left.evaluate(message); - // Can we do an OR shortcut?? - if ((lv != null) && lv.booleanValue()) - { - return Boolean.TRUE; - } - - Boolean rv = (Boolean) right.evaluate(message); - - return (rv == null) ? null : rv; - } - - public String getExpressionSymbol() - { - return "OR"; - } - }; - } - - public static BooleanExpression createAND(BooleanExpression lvalue, BooleanExpression rvalue) - { - return new LogicExpression(lvalue, rvalue) - { - - public Object evaluate(AbstractJMSMessage message) throws QpidException - { - - Boolean lv = (Boolean) left.evaluate(message); - - // Can we do an AND shortcut?? - if (lv == null) - { - return null; - } - - if (!lv.booleanValue()) - { - return Boolean.FALSE; - } - - Boolean rv = (Boolean) right.evaluate(message); - - return (rv == null) ? null : rv; - } - - public String getExpressionSymbol() - { - return "AND"; - } - }; - } - - /** - * @param left - * @param right - */ - public LogicExpression(BooleanExpression left, BooleanExpression right) - { - super(left, right); - } - - public abstract Object evaluate(AbstractJMSMessage message) throws QpidException; - - public boolean matches(AbstractJMSMessage message) throws QpidException - { - Object object = evaluate(message); - - return (object != null) && (object == Boolean.TRUE); - } - -} diff --git a/java/client/src/main/java/org/apache/qpidity/filter/MessageFilter.java b/java/client/src/main/java/org/apache/qpidity/filter/MessageFilter.java deleted file mode 100644 index aa1303a373..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/filter/MessageFilter.java +++ /dev/null @@ -1,27 +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.qpidity.filter; - -import org.apache.qpidity.QpidException; -import org.apache.qpid.client.message.AbstractJMSMessage; - - -public interface MessageFilter -{ - boolean matches(AbstractJMSMessage message) throws QpidException; -} diff --git a/java/client/src/main/java/org/apache/qpidity/filter/PropertyExpression.java b/java/client/src/main/java/org/apache/qpidity/filter/PropertyExpression.java deleted file mode 100644 index 5ea2004d75..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/filter/PropertyExpression.java +++ /dev/null @@ -1,303 +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.qpidity.filter; - -import org.apache.qpid.framing.CommonContentHeaderProperties; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.client.message.AbstractJMSMessage; -import org.apache.qpidity.QpidException; -import org.slf4j.LoggerFactory; -import org.slf4j.Logger; - -import javax.jms.JMSException; -import java.util.HashMap; - -/** - * Represents a property expression - */ -public class PropertyExpression implements Expression -{ - // Constants - defined the same as JMS - private static final int NON_PERSISTENT = 1; - private static final int DEFAULT_PRIORITY = 4; - - private static final Logger _logger = LoggerFactory.getLogger(PropertyExpression.class); - - private static final HashMap JMS_PROPERTY_EXPRESSIONS = new HashMap(); - - static - { - JMS_PROPERTY_EXPRESSIONS.put("JMSDestination", new Expression() - { - public Object evaluate(AbstractJMSMessage message) - { - //TODO - return null; - } - }); - JMS_PROPERTY_EXPRESSIONS.put("JMSReplyTo", new Expression() - { - public Object evaluate(AbstractJMSMessage message) - { - try - { - CommonContentHeaderProperties _properties = - message.getContentHeaderProperties(); - AMQShortString replyTo = _properties.getReplyTo(); - - return (replyTo == null) ? null : replyTo.toString(); - } - catch (Exception e) - { - _logger.warn("Error evaluating property", e); - - return null; - } - } - }); - - JMS_PROPERTY_EXPRESSIONS.put("JMSType", new Expression() - { - public Object evaluate(AbstractJMSMessage message) - { - try - { - CommonContentHeaderProperties _properties = - message.getContentHeaderProperties(); - AMQShortString type = _properties.getType(); - - return (type == null) ? null : type.toString(); - } - catch (Exception e) - { - _logger.warn("Error evaluating property", e); - - return null; - } - - } - }); - - JMS_PROPERTY_EXPRESSIONS.put("JMSDeliveryMode", new Expression() - { - public Object evaluate(AbstractJMSMessage message) - { - try - { - int mode = message.getJMSDeliveryMode(); - if (_logger.isDebugEnabled()) - { - _logger.debug("JMSDeliveryMode is :" + mode); - } - - return mode; - } - catch (Exception e) - { - _logger.warn("Error evaluating property",e); - } - - return NON_PERSISTENT; - } - }); - - JMS_PROPERTY_EXPRESSIONS.put("JMSPriority", new Expression() - { - public Object evaluate(AbstractJMSMessage message) - { - try - { - CommonContentHeaderProperties _properties = - message.getContentHeaderProperties(); - return (int) _properties.getPriority(); - } - catch (Exception e) - { - _logger.warn("Error evaluating property",e); - } - - return DEFAULT_PRIORITY; - } - }); - - JMS_PROPERTY_EXPRESSIONS.put("AMQMessageID", new Expression() - { - public Object evaluate(AbstractJMSMessage message) - { - - try - { - CommonContentHeaderProperties _properties = - message.getContentHeaderProperties(); - AMQShortString messageId = _properties.getMessageId(); - - return (messageId == null) ? null : messageId; - } - catch (Exception e) - { - _logger.warn("Error evaluating property",e); - - return null; - } - - } - }); - - JMS_PROPERTY_EXPRESSIONS.put("JMSTimestamp", new Expression() - { - public Object evaluate(AbstractJMSMessage message) - { - try - { - CommonContentHeaderProperties _properties = - message.getContentHeaderProperties(); - return _properties.getTimestamp(); - } - catch (Exception e) - { - _logger.warn("Error evaluating property",e); - - return null; - } - - } - }); - - JMS_PROPERTY_EXPRESSIONS.put("JMSCorrelationID", new Expression() - { - public Object evaluate(AbstractJMSMessage message) - { - - try - { - CommonContentHeaderProperties _properties = - message.getContentHeaderProperties(); - AMQShortString correlationId = _properties.getCorrelationId(); - return (correlationId == null) ? null : correlationId.toString(); - } - catch (Exception e) - { - _logger.warn("Error evaluating property",e); - - return null; - } - - } - }); - - JMS_PROPERTY_EXPRESSIONS.put("JMSExpiration", new Expression() - { - public Object evaluate(AbstractJMSMessage message) - { - - try - { - CommonContentHeaderProperties _properties = - message.getContentHeaderProperties(); - return _properties.getExpiration(); - } - catch (Exception e) - { - _logger.warn("Error evaluating property",e); - return null; - } - - } - }); - - JMS_PROPERTY_EXPRESSIONS.put("JMSRedelivered", new Expression() - { - public Object evaluate(AbstractJMSMessage message) - { - try - { - return message.getJMSRedelivered(); - } - catch (JMSException e) - { - _logger.warn("Error evaluating property",e); - return null; - } - } - }); - - } - - private final String name; - private final Expression jmsPropertyExpression; - - public PropertyExpression(String name) - { - this.name = name; - jmsPropertyExpression = JMS_PROPERTY_EXPRESSIONS.get(name); - } - - public Object evaluate(AbstractJMSMessage message) throws QpidException - { - - if (jmsPropertyExpression != null) - { - return jmsPropertyExpression.evaluate(message); - } - else - { - - CommonContentHeaderProperties _properties = message.getContentHeaderProperties(); - if (_logger.isDebugEnabled()) - { - _logger.debug("Looking up property:" + name); - _logger.debug("Properties are:" + _properties.getHeaders().keySet()); - } - return _properties.getHeaders().getObject(name); - } - } - - public String getName() - { - return name; - } - - /** - * @see java.lang.Object#toString() - */ - public String toString() - { - return name; - } - - /** - * @see java.lang.Object#hashCode() - */ - public int hashCode() - { - return name.hashCode(); - } - - /** - * @see java.lang.Object#equals(java.lang.Object) - */ - public boolean equals(Object o) - { - if ((o == null) || !this.getClass().equals(o.getClass())) - { - return false; - } - return name.equals(((PropertyExpression) o).name); - } - -} diff --git a/java/client/src/main/java/org/apache/qpidity/filter/UnaryExpression.java b/java/client/src/main/java/org/apache/qpidity/filter/UnaryExpression.java deleted file mode 100644 index f73449679c..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/filter/UnaryExpression.java +++ /dev/null @@ -1,321 +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.qpidity.filter; - -import org.apache.qpidity.QpidException; -import org.apache.qpid.client.message.AbstractJMSMessage; - -import java.math.BigDecimal; -import java.util.List; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; - -/** - * An expression which performs an operation on two expression values - */ -public abstract class UnaryExpression implements Expression -{ - - private static final BigDecimal BD_LONG_MIN_VALUE = BigDecimal.valueOf(Long.MIN_VALUE); - protected Expression right; - - public static Expression createNegate(Expression left) - { - return new UnaryExpression(left) - { - public Object evaluate(AbstractJMSMessage message) throws QpidException - { - Object rvalue = right.evaluate(message); - if (rvalue == null) - { - return null; - } - - if (rvalue instanceof Number) - { - return UnaryExpression.negate((Number) rvalue); - } - - return null; - } - - public String getExpressionSymbol() - { - return "-"; - } - }; - } - - public static BooleanExpression createInExpression(PropertyExpression right, List elements, final boolean not) - { - - // Use a HashSet if there are many elements. - Collection t; - if (elements.size() == 0) - { - t = null; - } - else if (elements.size() < 5) - { - t = elements; - } - else - { - t = new HashSet(elements); - } - - final Collection inList = t; - - return new BooleanUnaryExpression(right) - { - public Object evaluate(AbstractJMSMessage message) throws QpidException - { - - Object rvalue = right.evaluate(message); - if (rvalue == null) - { - return null; - } - - if (rvalue.getClass() != String.class) - { - return null; - } - - if (((inList != null) && inList.contains(rvalue)) ^ not) - { - return Boolean.TRUE; - } - else - { - return Boolean.FALSE; - } - - } - - public String toString() - { - StringBuffer answer = new StringBuffer(); - answer.append(right); - answer.append(" "); - answer.append(getExpressionSymbol()); - answer.append(" ( "); - - int count = 0; - for (Iterator i = inList.iterator(); i.hasNext();) - { - Object o = (Object) i.next(); - if (count != 0) - { - answer.append(", "); - } - - answer.append(o); - count++; - } - - answer.append(" )"); - - return answer.toString(); - } - - public String getExpressionSymbol() - { - if (not) - { - return "NOT IN"; - } - else - { - return "IN"; - } - } - }; - } - - abstract static class BooleanUnaryExpression extends UnaryExpression implements BooleanExpression - { - public BooleanUnaryExpression(Expression left) - { - super(left); - } - - public boolean matches(AbstractJMSMessage message) throws QpidException - { - Object object = evaluate(message); - - return (object != null) && (object == Boolean.TRUE); - } - } - - ; - - public static BooleanExpression createNOT(BooleanExpression left) - { - return new BooleanUnaryExpression(left) - { - public Object evaluate(AbstractJMSMessage message) throws QpidException - { - Boolean lvalue = (Boolean) right.evaluate(message); - if (lvalue == null) - { - return null; - } - - return lvalue.booleanValue() ? Boolean.FALSE : Boolean.TRUE; - } - - public String getExpressionSymbol() - { - return "NOT"; - } - }; - } - public static BooleanExpression createBooleanCast(Expression left) - { - return new BooleanUnaryExpression(left) - { - public Object evaluate(AbstractJMSMessage message) throws QpidException - { - Object rvalue = right.evaluate(message); - if (rvalue == null) - { - return null; - } - - if (!rvalue.getClass().equals(Boolean.class)) - { - return Boolean.FALSE; - } - - return ((Boolean) rvalue).booleanValue() ? Boolean.TRUE : Boolean.FALSE; - } - - public String toString() - { - return right.toString(); - } - - public String getExpressionSymbol() - { - return ""; - } - }; - } - - private static Number negate(Number left) - { - Class clazz = left.getClass(); - if (clazz == Integer.class) - { - return new Integer(-left.intValue()); - } - else if (clazz == Long.class) - { - return new Long(-left.longValue()); - } - else if (clazz == Float.class) - { - return new Float(-left.floatValue()); - } - else if (clazz == Double.class) - { - return new Double(-left.doubleValue()); - } - else if (clazz == BigDecimal.class) - { - // We ussually get a big deciamal when we have Long.MIN_VALUE constant in the - // Selector. Long.MIN_VALUE is too big to store in a Long as a positive so we store it - // as a Big decimal. But it gets Negated right away.. to here we try to covert it back - // to a Long. - BigDecimal bd = (BigDecimal) left; - bd = bd.negate(); - - if (UnaryExpression.BD_LONG_MIN_VALUE.compareTo(bd) == 0) - { - return new Long(Long.MIN_VALUE); - } - - return bd; - } - else - { - throw new RuntimeException("Don't know how to negate: " + left); - } - } - - public UnaryExpression(Expression left) - { - this.right = left; - } - - public Expression getRight() - { - return right; - } - - public void setRight(Expression expression) - { - right = expression; - } - - /** - * @see Object#toString() - */ - public String toString() - { - return "(" + getExpressionSymbol() + " " + right.toString() + ")"; - } - - /** - * TODO: more efficient hashCode() - * - * @see Object#hashCode() - */ - public int hashCode() - { - return toString().hashCode(); - } - - /** - * TODO: more efficient hashCode() - * - * @see Object#equals(Object) - */ - public boolean equals(Object o) - { - - if ((o == null) || !this.getClass().equals(o.getClass())) - { - return false; - } - - return toString().equals(o.toString()); - - } - - /** - * Returns the symbol that represents this binary expression. For example, addition is - * represented by "+" - * - * @return - */ - public abstract String getExpressionSymbol(); - -} diff --git a/java/client/src/main/java/org/apache/qpidity/naming/ReadOnlyContext.java b/java/client/src/main/java/org/apache/qpidity/naming/ReadOnlyContext.java deleted file mode 100644 index c73d6e4b35..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/naming/ReadOnlyContext.java +++ /dev/null @@ -1,509 +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.qpidity.naming; - -import org.apache.qpid.jndi.NameParserImpl; - -import javax.naming.*; -import javax.naming.spi.NamingManager; -import java.io.Serializable; -import java.util.*; - -/** - * Based on class from ActiveMQ. - * A read-only Context - *

- * This version assumes it and all its subcontext are read-only and any attempt - * to modify (e.g. through bind) will result in an OperationNotSupportedException. - * Each Context in the tree builds a cache of the entries in all sub-contexts - * to optimise the performance of lookup. - *

- *

This implementation is intended to optimise the performance of lookup(String) - * to about the level of a HashMap get. It has been observed that the scheme - * resolution phase performed by the JVM takes considerably longer, so for - * optimum performance lookups should be coded like:

- * - * Context componentContext = (Context)new InitialContext().lookup("java:comp"); - * String envEntry = (String) componentContext.lookup("env/myEntry"); - * String envEntry2 = (String) componentContext.lookup("env/myEntry2"); - * - */ -public class ReadOnlyContext implements Context, Serializable -{ - private static final long serialVersionUID = -5754338187296859149L; - protected static final NameParser nameParser = new NameParserImpl(); - - protected final Hashtable environment; // environment for this context - protected final Map bindings; // bindings at my level - protected final Map treeBindings; // all bindings under me - - private boolean frozen = false; - private String nameInNamespace = ""; - public static final String SEPARATOR = "/"; - - public ReadOnlyContext() - { - environment = new Hashtable(); - bindings = new HashMap(); - treeBindings = new HashMap(); - } - - public ReadOnlyContext(Hashtable env) - { - if (env == null) - { - this.environment = new Hashtable(); - } - else - { - this.environment = new Hashtable(env); - } - - this.bindings = Collections.EMPTY_MAP; - this.treeBindings = Collections.EMPTY_MAP; - } - - public ReadOnlyContext(Hashtable environment, Map bindings) - { - if (environment == null) - { - this.environment = new Hashtable(); - } - else - { - this.environment = new Hashtable(environment); - } - - this.bindings = bindings; - treeBindings = new HashMap(); - frozen = true; - } - - public ReadOnlyContext(Hashtable environment, Map bindings, String nameInNamespace) - { - this(environment, bindings); - this.nameInNamespace = nameInNamespace; - } - - protected ReadOnlyContext(ReadOnlyContext clone, Hashtable env) - { - this.bindings = clone.bindings; - this.treeBindings = clone.treeBindings; - this.environment = new Hashtable(env); - } - - protected ReadOnlyContext(ReadOnlyContext clone, Hashtable env, String nameInNamespace) - { - this(clone, env); - this.nameInNamespace = nameInNamespace; - } - - public void freeze() - { - frozen = true; - } - - boolean isFrozen() - { - return frozen; - } - - /** - * internalBind is intended for use only during setup or possibly by suitably synchronized superclasses. - * It binds every possible lookup into a map in each context. To do this, each context - * strips off one name segment and if necessary creates a new context for it. Then it asks that context - * to bind the remaining name. It returns a map containing all the bindings from the next context, plus - * the context it just created (if it in fact created it). (the names are suitably extended by the segment - * originally lopped off). - * - * @param name - * @param value - * @return - * @throws javax.naming.NamingException - */ - protected Map internalBind(String name, Object value) throws NamingException - { - assert (name != null) && (name.length() > 0); - assert !frozen; - - Map newBindings = new HashMap(); - int pos = name.indexOf('/'); - if (pos == -1) - { - if (treeBindings.put(name, value) != null) - { - throw new NamingException("Something already bound at " + name); - } - - bindings.put(name, value); - newBindings.put(name, value); - } - else - { - String segment = name.substring(0, pos); - assert segment != null; - assert !segment.equals(""); - Object o = treeBindings.get(segment); - if (o == null) - { - o = newContext(); - treeBindings.put(segment, o); - bindings.put(segment, o); - newBindings.put(segment, o); - } - else if (!(o instanceof ReadOnlyContext)) - { - throw new NamingException("Something already bound where a subcontext should go"); - } - - ReadOnlyContext readOnlyContext = (ReadOnlyContext) o; - String remainder = name.substring(pos + 1); - Map subBindings = readOnlyContext.internalBind(remainder, value); - for (Iterator iterator = subBindings.entrySet().iterator(); iterator.hasNext();) - { - Map.Entry entry = (Map.Entry) iterator.next(); - String subName = segment + "/" + (String) entry.getKey(); - Object bound = entry.getValue(); - treeBindings.put(subName, bound); - newBindings.put(subName, bound); - } - } - - return newBindings; - } - - protected ReadOnlyContext newContext() - { - return new ReadOnlyContext(); - } - - public Object addToEnvironment(String propName, Object propVal) throws NamingException - { - return environment.put(propName, propVal); - } - - public Hashtable getEnvironment() throws NamingException - { - return (Hashtable) environment.clone(); - } - - public Object removeFromEnvironment(String propName) throws NamingException - { - return environment.remove(propName); - } - - public Object lookup(String name) throws NamingException - { - if (name.length() == 0) - { - return this; - } - - Object result = treeBindings.get(name); - if (result == null) - { - result = bindings.get(name); - } - - if (result == null) - { - int pos = name.indexOf(':'); - if (pos > 0) - { - String scheme = name.substring(0, pos); - Context ctx = NamingManager.getURLContext(scheme, environment); - if (ctx == null) - { - throw new NamingException("scheme " + scheme + " not recognized"); - } - - return ctx.lookup(name); - } - else - { - // Split out the first name of the path - // and look for it in the bindings map. - CompositeName path = new CompositeName(name); - - if (path.size() == 0) - { - return this; - } - else - { - String first = path.get(0); - Object obj = bindings.get(first); - if (obj == null) - { - throw new NameNotFoundException(name); - } - else if ((obj instanceof Context) && (path.size() > 1)) - { - Context subContext = (Context) obj; - obj = subContext.lookup(path.getSuffix(1)); - } - - return obj; - } - } - } - - if (result instanceof LinkRef) - { - LinkRef ref = (LinkRef) result; - result = lookup(ref.getLinkName()); - } - - if (result instanceof Reference) - { - try - { - result = NamingManager.getObjectInstance(result, null, null, this.environment); - } - catch (NamingException e) - { - throw e; - } - catch (Exception e) - { - throw (NamingException) new NamingException("could not look up : " + name).initCause(e); - } - } - - if (result instanceof ReadOnlyContext) - { - String prefix = getNameInNamespace(); - if (prefix.length() > 0) - { - prefix = prefix + SEPARATOR; - } - - result = new ReadOnlyContext((ReadOnlyContext) result, environment, prefix + name); - } - - return result; - } - - public Object lookup(Name name) throws NamingException - { - return lookup(name.toString()); - } - - public Object lookupLink(String name) throws NamingException - { - return lookup(name); - } - - public Name composeName(Name name, Name prefix) throws NamingException - { - Name result = (Name) prefix.clone(); - result.addAll(name); - - return result; - } - - public String composeName(String name, String prefix) throws NamingException - { - CompositeName result = new CompositeName(prefix); - result.addAll(new CompositeName(name)); - - return result.toString(); - } - - public NamingEnumeration list(String name) throws NamingException - { - Object o = lookup(name); - if (o == this) - { - return new ReadOnlyContext.ListEnumeration(); - } - else if (o instanceof Context) - { - return ((Context) o).list(""); - } - else - { - throw new NotContextException(); - } - } - - public NamingEnumeration listBindings(String name) throws NamingException - { - Object o = lookup(name); - if (o == this) - { - return new ReadOnlyContext.ListBindingEnumeration(); - } - else if (o instanceof Context) - { - return ((Context) o).listBindings(""); - } - else - { - throw new NotContextException(); - } - } - - public Object lookupLink(Name name) throws NamingException - { - return lookupLink(name.toString()); - } - - public NamingEnumeration list(Name name) throws NamingException - { - return list(name.toString()); - } - - public NamingEnumeration listBindings(Name name) throws NamingException - { - return listBindings(name.toString()); - } - - public void bind(Name name, Object obj) throws NamingException - { - throw new OperationNotSupportedException(); - } - - public void bind(String name, Object obj) throws NamingException - { - throw new OperationNotSupportedException(); - } - - public void close() throws NamingException - { - // ignore - } - - public Context createSubcontext(Name name) throws NamingException - { - throw new OperationNotSupportedException(); - } - - public Context createSubcontext(String name) throws NamingException - { - throw new OperationNotSupportedException(); - } - - public void destroySubcontext(Name name) throws NamingException - { - throw new OperationNotSupportedException(); - } - - public void destroySubcontext(String name) throws NamingException - { - throw new OperationNotSupportedException(); - } - - public String getNameInNamespace() throws NamingException - { - return nameInNamespace; - } - - public NameParser getNameParser(Name name) throws NamingException - { - return nameParser; - } - - public NameParser getNameParser(String name) throws NamingException - { - return nameParser; - } - - public void rebind(Name name, Object obj) throws NamingException - { - throw new OperationNotSupportedException(); - } - - public void rebind(String name, Object obj) throws NamingException - { - throw new OperationNotSupportedException(); - } - - public void rename(Name oldName, Name newName) throws NamingException - { - throw new OperationNotSupportedException(); - } - - public void rename(String oldName, String newName) throws NamingException - { - throw new OperationNotSupportedException(); - } - - public void unbind(Name name) throws NamingException - { - throw new OperationNotSupportedException(); - } - - public void unbind(String name) throws NamingException - { - throw new OperationNotSupportedException(); - } - - private abstract class LocalNamingEnumeration implements NamingEnumeration - { - private Iterator i = bindings.entrySet().iterator(); - - public boolean hasMore() throws NamingException - { - return i.hasNext(); - } - - public boolean hasMoreElements() - { - return i.hasNext(); - } - - protected Map.Entry getNext() - { - return (Map.Entry) i.next(); - } - - public void close() throws NamingException - { } - } - - private class ListEnumeration extends ReadOnlyContext.LocalNamingEnumeration - { - public Object next() throws NamingException - { - return nextElement(); - } - - public Object nextElement() - { - Map.Entry entry = getNext(); - - return new NameClassPair((String) entry.getKey(), entry.getValue().getClass().getName()); - } - } - - private class ListBindingEnumeration extends ReadOnlyContext.LocalNamingEnumeration - { - public Object next() throws NamingException - { - return nextElement(); - } - - public Object nextElement() - { - Map.Entry entry = getNext(); - - return new Binding((String) entry.getKey(), entry.getValue()); - } - } -} diff --git a/java/client/src/main/java/org/apache/qpidity/naming/jndi.properties b/java/client/src/main/java/org/apache/qpidity/naming/jndi.properties deleted file mode 100644 index e451cf53fa..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/naming/jndi.properties +++ /dev/null @@ -1,40 +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. -# -java.naming.factory.initial = org.apache.qpidity.naming.PropertiesFileInitialConextFactory - -# use the following property to configure the default connector -#java.naming.provider.url - ignored. - -# register some connection factories -# connectionfactory.[jndiname] = [ConnectionURL] -# qpid:username=foo;password=password;client_id=id;virtualhost=path@tpc:localhost:1556 -connectionfactory.local = qpid:tcp:localhost' - -# register some queues in JNDI using the form -# queue.[jndiName] = [physicalName] -queue.MyQueue = example.MyQueue - -# register some topics in JNDI using the form -# topic.[jndiName] = [physicalName] -topic.ibmStocks = stocks.nyse.ibm - -# Register an AMQP destination in JNDI -# NOTE: Qpid currently only supports direct,topics and headers -# destination.[jniName] = [BindingURL] -destination.direct = direct://amq.direct//directQueue diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/Client.java b/java/client/src/main/java/org/apache/qpidity/nclient/Client.java deleted file mode 100644 index eb0e370560..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/nclient/Client.java +++ /dev/null @@ -1,294 +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.qpidity.nclient; - -import java.util.List; -import java.util.UUID; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -import org.apache.qpid.client.url.URLParser_0_10; -import org.apache.qpid.jms.BrokerDetails; -import org.apache.qpid.url.QpidURL; -import org.apache.qpidity.ErrorCode; -import org.apache.qpidity.QpidException; -import org.apache.qpidity.nclient.impl.ClientSession; -import org.apache.qpidity.nclient.impl.ClientSessionDelegate; -import org.apache.qpidity.transport.Channel; -import org.apache.qpidity.transport.ClientDelegate; -import org.apache.qpidity.transport.Connection; -import org.apache.qpidity.transport.ConnectionClose; -import org.apache.qpidity.transport.ConnectionCloseCode; -import org.apache.qpidity.transport.ConnectionCloseOk; -import org.apache.qpidity.transport.ProtocolHeader; -import org.apache.qpidity.transport.ProtocolVersionException; -import org.apache.qpidity.transport.SessionDelegate; -import org.apache.qpidity.transport.network.io.IoTransport; -import org.apache.qpidity.transport.network.mina.MinaHandler; -import org.apache.qpidity.transport.network.nio.NioHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -public class Client implements org.apache.qpidity.nclient.Connection -{ - private Connection _conn; - private ClosedListener _closedListner; - private final Lock _lock = new ReentrantLock(); - private static Logger _logger = LoggerFactory.getLogger(Client.class); - private Condition closeOk; - private boolean closed = false; - private long timeout = 60000; - - private ProtocolHeader header = null; - - /** - * - * @return returns a new connection to the broker. - */ - public static org.apache.qpidity.nclient.Connection createConnection() - { - return new Client(); - } - - public void connect(String host, int port,String virtualHost,String username, String password) throws QpidException - { - - final Condition negotiationComplete = _lock.newCondition(); - closeOk = _lock.newCondition(); - _lock.lock(); - - ClientDelegate connectionDelegate = new ClientDelegate() - { - private boolean receivedClose = false; - public SessionDelegate getSessionDelegate() - { - return new ClientSessionDelegate(); - } - - public void exception(Throwable t) - { - if (_closedListner != null) - { - _closedListner.onClosed(ErrorCode.CONNECTION_ERROR,ErrorCode.CONNECTION_ERROR.getDesc(),t); - } - else - { - throw new RuntimeException("connection closed",t); - } - } - - public void closed() - { - if (_closedListner != null && !this.receivedClose) - { - _closedListner.onClosed(ErrorCode.CONNECTION_ERROR,ErrorCode.CONNECTION_ERROR.getDesc(),null); - } - } - - @Override public void connectionCloseOk(Channel context, ConnectionCloseOk struct) - { - _lock.lock(); - try - { - closed = true; - this.receivedClose = true; - closeOk.signalAll(); - } - finally - { - _lock.unlock(); - } - } - - @Override public void connectionClose(Channel context, ConnectionClose connectionClose) - { - ErrorCode errorCode = ErrorCode.get(connectionClose.getReplyCode().getValue()); - if (_closedListner == null && errorCode != ErrorCode.NO_ERROR) - { - throw new RuntimeException - (new QpidException("Server closed the connection: Reason " + - connectionClose.getReplyText(), - errorCode, - null)); - } - else - { - _closedListner.onClosed(errorCode, connectionClose.getReplyText(),null); - } - - this.receivedClose = true; - } - @Override public void init(Channel ch, ProtocolHeader hdr) - { - // TODO: once the merge is done we'll need to update this code - // for handling 0.8 protocol version type i.e. major=8 and mino - if (hdr.getMajor() != 0 || hdr.getMinor() != 10) - { - Client.this.header = hdr; - _lock.lock(); - negotiationComplete.signalAll(); - _lock.unlock(); - } - } - }; - - connectionDelegate.setCondition(_lock,negotiationComplete); - connectionDelegate.setUsername(username); - connectionDelegate.setPassword(password); - connectionDelegate.setVirtualHost(virtualHost); - - String transport = System.getProperty("transport","io"); - if (transport.equalsIgnoreCase("nio")) - { - _logger.info("using NIO Transport"); - _conn = NioHandler.connect(host, port,connectionDelegate); - } - else if (transport.equalsIgnoreCase("io")) - { - _logger.info("using Plain IO Transport"); - _conn = IoTransport.connect(host, port,connectionDelegate); - } - else - { - _logger.info("using MINA Transport"); - _conn = MinaHandler.connect(host, port,connectionDelegate); - // _conn = NativeHandler.connect(host, port,connectionDelegate); - } - - // XXX: hardcoded version numbers - _conn.send(new ProtocolHeader(1, 0, 10)); - - try - { - negotiationComplete.await(timeout, TimeUnit.MILLISECONDS); - if (header != null) - { - _conn.close(); - throw new ProtocolVersionException(header.getMajor(), header.getMinor()); - } - } - catch (InterruptedException e) - { - throw new RuntimeException(e); - } - finally - { - _lock.unlock(); - } - } - - public void connect(String url)throws QpidException - { - URLParser_0_10 parser = null; - try - { - parser = new URLParser_0_10(url); - } - catch(Exception e) - { - throw new QpidException("Error parsing the URL",ErrorCode.UNDEFINED,e); - } - List brokers = parser.getAllBrokerDetails(); - BrokerDetails brokerDetail = brokers.get(0); - connect(brokerDetail.getHost(), brokerDetail.getPort(), brokerDetail.getProperty("virtualhost"), - brokerDetail.getProperty("username")== null? "guest":brokerDetail.getProperty("username"), - brokerDetail.getProperty("password")== null? "guest":brokerDetail.getProperty("password")); - } - - /* - * Until the dust settles with the URL disucssion - * I am not going to implement this. - */ - public void connect(QpidURL url) throws QpidException - { - throw new UnsupportedOperationException("Not implemented"); - } - - /* { - // temp impl to tests - BrokerDetails details = url.getAllBrokerDetails().get(0); - connect(details.getHost(), - details.getPort(), - details.getVirtualHost(), - details.getUserName(), - details.getPassword()); - } -*/ - - public void close() throws QpidException - { - Channel ch = _conn.getChannel(0); - ch.connectionClose(ConnectionCloseCode.NORMAL, "client is closing"); - _lock.lock(); - try - { - try - { - long start = System.currentTimeMillis(); - long elapsed = 0; - while (!closed && elapsed < timeout) - { - closeOk.await(timeout - elapsed, TimeUnit.MILLISECONDS); - elapsed = System.currentTimeMillis() - start; - } - if(!closed) - { - throw new QpidException("Timed out when closing connection", ErrorCode.CONNECTION_ERROR, null); - } - } - catch (InterruptedException e) - { - throw new QpidException("Interrupted when closing connection", ErrorCode.CONNECTION_ERROR, null); - } - } - finally - { - _lock.unlock(); - } - _conn.close(); - } - - public Session createSession(long expiryInSeconds) - { - Channel ch = _conn.getChannel(); - ClientSession ssn = new ClientSession(UUID.randomUUID().toString().getBytes()); - ssn.attach(ch); - ssn.sessionAttach(ssn.getName()); - ssn.sessionRequestTimeout(expiryInSeconds); - return ssn; - } - - public DtxSession createDTXSession(int expiryInSeconds) - { - ClientSession clientSession = (ClientSession) createSession(expiryInSeconds); - clientSession.dtxSelect(); - return (DtxSession) clientSession; - } - - public void setClosedListener(ClosedListener closedListner) - { - - _closedListner = closedListner; - } - -} diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/ClosedListener.java b/java/client/src/main/java/org/apache/qpidity/nclient/ClosedListener.java deleted file mode 100644 index c0c6978a14..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/nclient/ClosedListener.java +++ /dev/null @@ -1,39 +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.qpidity.nclient; - -import org.apache.qpidity.ErrorCode; - - -/** - * If the communication layer detects a serious problem with a connection, it - * informs the connection's ExceptionListener - */ -public interface ClosedListener -{ - /** - * If the communication layer detects a serious problem with a connection, it - * informs the connection's ExceptionListener - * @param errorCode TODO - * @param reason TODO - * @param t TODO - * @see Connection - */ - public void onClosed(ErrorCode errorCode, String reason, Throwable t); -} \ No newline at end of file diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/Connection.java b/java/client/src/main/java/org/apache/qpidity/nclient/Connection.java deleted file mode 100644 index 49167750d1..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/nclient/Connection.java +++ /dev/null @@ -1,86 +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.qpidity.nclient; - -import org.apache.qpidity.QpidException; - -/** - * This represents a physical connection to a broker. - */ -public interface Connection -{ - /** - * Establish the connection using the given parameters - * - * @param host host name - * @param port port number - * @param virtualHost the virtual host name - * @param username user name - * @param password password - * @throws QpidException If the communication layer fails to establish the connection. - */ - public void connect(String host, int port,String virtualHost,String username, String password) throws QpidException; - - /** - * Establish the connection with the broker identified by the URL. - * - * @param url Specifies the URL of the broker. - * @throws QpidException If the communication layer fails to connect with the broker, an exception is thrown. - */ - public void connect(String url) throws QpidException; - - /** - * Close this connection. - * - * @throws QpidException if the communication layer fails to close the connection. - */ - public void close() throws QpidException; - - /** - * Create a session for this connection. - *

The returned session is suspended - * (i.e. this session is not attached to an underlying channel) - * - * @param expiryInSeconds Expiry time expressed in seconds, if the value is less than - * or equal to 0 then the session does not expire. - * @return A newly created (suspended) session. - */ - public Session createSession(long expiryInSeconds); - - /** - * Create a DtxSession for this connection. - *

A Dtx Session must be used when resources have to be manipulated as - * part of a global transaction. - *

The retuned DtxSession is suspended - * (i.e. this session is not attached with an underlying channel) - * - * @param expiryInSeconds Expiry time expressed in seconds, if the value is less than or equal - * to 0 then the session does not expire. - * @return A newly created (suspended) DtxSession. - */ - public DtxSession createDTXSession(int expiryInSeconds); - - /** - * If the communication layer detects a serious problem with a connection, it - * informs the connection's ClosedListener - * - * @param exceptionListner The ClosedListener - */ - public void setClosedListener(ClosedListener exceptionListner); -} diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/DtxSession.java b/java/client/src/main/java/org/apache/qpidity/nclient/DtxSession.java deleted file mode 100644 index 1d9c63df4f..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/nclient/DtxSession.java +++ /dev/null @@ -1,137 +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.qpidity.nclient; - -import org.apache.qpidity.transport.Future; -import org.apache.qpidity.transport.GetTimeoutResult; -import org.apache.qpidity.transport.Option; -import org.apache.qpidity.transport.RecoverResult; -import org.apache.qpidity.transport.XaResult; -import org.apache.qpidity.transport.Xid; - -/** - * The resources for this session are controlled under the scope of a distributed transaction. - */ -public interface DtxSession extends Session -{ - - /** - * This method is called when messages should be produced and consumed on behalf a transaction - * branch identified by xid. - * possible options are: - *

    - *
  • {@link Option#JOIN}: Indicate that the start applies to joining a transaction previously seen. - *
  • {@link Option#RESUME}: Indicate that the start applies to resuming a suspended transaction branch specified. - *
- * - * @param xid Specifies the xid of the transaction branch to be started. - * @param options Possible options are: {@link Option#JOIN} and {@link Option#RESUME}. - * @return Confirms to the client that the transaction branch is started or specify the error condition. - */ - public Future dtxStart(Xid xid, Option... options); - - /** - * This method is called when the work done on behalf of a transaction branch finishes or needs to - * be suspended. - * possible options are: - *
    - *
  • {@link Option#FAIL}: indicates that this portion of work has failed; - * otherwise this portion of work has - * completed successfully. - *
  • {@link Option#SUSPEND}: Indicates that the transaction branch is - * temporarily suspended in an incomplete state. - *
- * - * @param xid Specifies the xid of the transaction branch to be ended. - * @param options Available options are: {@link Option#FAIL} and {@link Option#SUSPEND}. - * @return Confirms to the client that the transaction branch is ended or specifies the error condition. - */ - public Future dtxEnd(Xid xid, Option... options); - - /** - * Commit the work done on behalf of a transaction branch. This method commits the work associated - * with xid. Any produced messages are made available and any consumed messages are discarded. - * The only possible option is: - *
    - *
  • {@link Option#ONE_PHASE}: When set, one-phase commit optimization is used. - *
- * - * @param xid Specifies the xid of the transaction branch to be committed. - * @param options Available option is: {@link Option#ONE_PHASE} - * @return Confirms to the client that the transaction branch is committed or specifies the error condition. - */ - public Future dtxCommit(Xid xid, Option... options); - - /** - * This method is called to forget about a heuristically completed transaction branch. - * - * @param xid Specifies the xid of the transaction branch to be forgotten. - */ - public void dtxForget(Xid xid, Option ... options); - - /** - * This method obtains the current transaction timeout value in seconds. If set-timeout was not - * used prior to invoking this method, the return value is the default timeout value; otherwise, the - * value used in the previous set-timeout call is returned. - * - * @param xid Specifies the xid of the transaction branch used for getting the timeout. - * @return The current transaction timeout value in seconds. - */ - public Future dtxGetTimeout(Xid xid, Option ... options); - - /** - * This method prepares any message produced or consumed on behalf of xid, ready for commitment. - * - * @param xid Specifies the xid of the transaction branch to be prepared. - * @return The status of the prepare operation can be any one of: - * xa-ok: Normal execution. - *

- * xa-rdonly: The transaction branch was read-only and has been committed. - *

- * xa-rbrollback: The broker marked the transaction branch rollback-only for an unspecified - * reason. - *

- * xa-rbtimeout: The work represented by this transaction branch took too long. - */ - public Future dtxPrepare(Xid xid, Option ... options); - - /** - * This method is called to obtain a list of transaction branches that are in a prepared or - * heuristically completed state. - * @return a array of xids to be recovered. - */ - public Future dtxRecover(Option ... options); - - /** - * This method rolls back the work associated with xid. Any produced messages are discarded and - * any consumed messages are re-queued. - * - * @param xid Specifies the xid of the transaction branch to be rolled back. - * @return Confirms to the client that the transaction branch is rolled back or specifies the error condition. - */ - public Future dtxRollback(Xid xid, Option ... options); - - /** - * Sets the specified transaction branch timeout value in seconds. - * - * @param xid Specifies the xid of the transaction branch for setting the timeout. - * @param timeout The transaction timeout value in seconds. - */ - public void dtxSetTimeout(Xid xid, long timeout, Option ... options); -} diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/JMSTestCase.java b/java/client/src/main/java/org/apache/qpidity/nclient/JMSTestCase.java deleted file mode 100644 index feb4c1c94d..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/nclient/JMSTestCase.java +++ /dev/null @@ -1,115 +0,0 @@ - package org.apache.qpidity.nclient; - -import java.util.Enumeration; - -import javax.jms.ExceptionListener; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.Queue; -import javax.jms.QueueBrowser; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQTopic; -import org.apache.qpid.framing.AMQShortString; - -public class JMSTestCase -{ - - public static void main(String[] args) - { - - try - { - javax.jms.Connection con = new AMQConnection("qpid:password=pass;username=name@tcp:localhost:5672"); - con.start(); - - javax.jms.Session ssn = con.createSession(false, 1); - - javax.jms.Destination dest = new AMQQueue(new AMQShortString("direct"),"test"); - javax.jms.MessageProducer prod = ssn.createProducer(dest); - QueueBrowser browser = ssn.createBrowser((Queue)dest, "Test = 'test'"); - - javax.jms.TextMessage msg = ssn.createTextMessage(); - msg.setStringProperty("TEST", "test"); - msg.setText("Should get this"); - prod.send(msg); - - javax.jms.TextMessage msg2 = ssn.createTextMessage(); - msg2.setStringProperty("TEST", "test2"); - msg2.setText("Shouldn't get this"); - prod.send(msg2); - - - Enumeration enu = browser.getEnumeration(); - for (;enu.hasMoreElements();) - { - System.out.println(enu.nextElement()); - System.out.println("\n"); - } - - javax.jms.MessageConsumer cons = ssn.createConsumer(dest, "Test = 'test'"); - javax.jms.TextMessage m = null; // (javax.jms.TextMessage)cons.receive(); - cons.setMessageListener(new MessageListener() - { - public void onMessage(Message m) - { - javax.jms.TextMessage m2 = (javax.jms.TextMessage)m; - try - { - System.out.println("headers : " + m2.toString()); - System.out.println("m : " + m2.getText()); - System.out.println("\n\n"); - } - catch(Exception e) - { - e.printStackTrace(); - } - } - - }); - - con.setExceptionListener(new ExceptionListener() - { - public void onException(JMSException e) - { - e.printStackTrace(); - } - }); - - System.out.println("Waiting"); - while (m == null) - { - - } - - System.out.println("Exiting"); - - /*javax.jms.TextMessage msg = ssn.createTextMessage(); - msg.setText("This is a test message"); - msg.setBooleanProperty("targetMessage", false); - prod.send(msg); - - msg.setBooleanProperty("targetMessage", true); - prod.send(msg); - - javax.jms.TextMessage m = (javax.jms.TextMessage)cons.receiveNoWait(); - - if (m == null) - { - System.out.println("message is null"); - } - else - { - System.out.println("message is not null" + m); - }*/ - - } - catch(Exception e) - { - e.printStackTrace(); - } - } - -} diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/MessagePartListener.java b/java/client/src/main/java/org/apache/qpidity/nclient/MessagePartListener.java deleted file mode 100644 index 7c7881502a..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/nclient/MessagePartListener.java +++ /dev/null @@ -1,63 +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.qpidity.nclient; - -import java.nio.ByteBuffer; - -import org.apache.qpidity.transport.Header; - -/** - * Assembles message parts. - *

The sequence of event for transferring a message is as follows: - *

    - *
  • messageHeaders - *
  • n calls to addData - *
  • messageReceived - *
- * It is up to the implementation to assemble the message once the different parts - * are transferred. - */ -public interface MessagePartListener -{ - /** - * Indicates the Message transfer has started. - * - * @param transferId The message transfer ID. - */ - public void messageTransfer(int transferId); - - /** - * Add the following a header to the message being received. - * - * @param header Either DeliveryProperties or ApplicationProperties - */ - public void messageHeader(Header header); - - /** - * Add the following byte array to the content of the message being received - * - * @param src Data to be added or streamed. - */ - public void data(ByteBuffer src); - - /** - * Indicates that the message has been fully received. - */ - public void messageReceived(); - -} diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/Session.java b/java/client/src/main/java/org/apache/qpidity/nclient/Session.java deleted file mode 100644 index 218a7ed571..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/nclient/Session.java +++ /dev/null @@ -1,595 +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.qpidity.nclient; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.Map; - -import org.apache.qpidity.transport.*; -import org.apache.qpidity.api.Message; - -/** - *

A session is associated with a connection. - * When it is created, a session is not associated with an underlying channel. - * The session is single threaded.

- *

- * All the Session commands are asynchronous. Synchronous behavior is achieved through invoking the sync method. - * For example, command1 will be synchronously invoked by using the following sequence: - *

    - *
  • session.command1() - *
  • session.sync() - *
- */ -public interface Session -{ - public static final short TRANSFER_ACQUIRE_MODE_NO_ACQUIRE = 1; - public static final short TRANSFER_ACQUIRE_MODE_PRE_ACQUIRE = 0; - public static final short TRANSFER_CONFIRM_MODE_REQUIRED = 0; - public static final short TRANSFER_CONFIRM_MODE_NOT_REQUIRED = 1; - public static final short MESSAGE_FLOW_MODE_CREDIT = 0; - public static final short MESSAGE_FLOW_MODE_WINDOW = 1; - public static final short MESSAGE_FLOW_UNIT_MESSAGE = 0; - public static final short MESSAGE_FLOW_UNIT_BYTE = 1; - public static final long MESSAGE_FLOW_MAX_BYTES = 0xFFFFFFFF; - public static final short MESSAGE_REJECT_CODE_GENERIC = 0; - public static final short MESSAGE_REJECT_CODE_IMMEDIATE_DELIVERY_FAILED = 1; - public static final short MESSAGE_ACQUIRE_ANY_AVAILABLE_MESSAGE = 0; - public static final short MESSAGE_ACQUIRE_MESSAGES_IF_ALL_ARE_AVAILABLE = 1; - - //------------------------------------------------------ - // Session housekeeping methods - //------------------------------------------------------ - - /** - * Sync method will block the session until all outstanding commands - * are executed. - */ - public void sync(); - - public void close(); - - public void sessionDetach(byte[] name, Option ... options); - - public void sessionRequestTimeout(long expiry, Option ... options); - - public byte[] getName(); - - public void setAutoSync(boolean value); - - //------------------------------------------------------ - // Messaging methods - // Producer - //------------------------------------------------------ - /** - * Transfer a message to a specified exchange. - *

- *

This transfer provides a complete message - * using a single method. The method is internally mapped to messageTransfer() and headers() followed - * by data() and endData(). - * This method should only be used by small messages.

- * - * @param destination The exchange the message is being sent to. - * @param msg The Message to be sent. - * @param confirmMode
    off ({@link Session#TRANSFER_CONFIRM_MODE_NOT_REQUIRED}): confirmation - * is not required. Once a message has been transferred in pre-acquire - * mode (or once acquire has been sent in no-acquire mode) the message is considered - * transferred. - *

    - *

  • on ({@link Session#TRANSFER_CONFIRM_MODE_REQUIRED}): an acquired message - * is not considered transferred until the original - * transfer is complete. A complete transfer is signaled by execution.complete. - *
- * @param acquireMode
    - *
  • no-acquire ({@link Session#TRANSFER_ACQUIRE_MODE_NO_ACQUIRE}): the message - * must be explicitly acquired. - *
  • pre-acquire ({@link Session#TRANSFER_ACQUIRE_MODE_PRE_ACQUIRE}): the message is - * acquired when the transfer starts. - *
- * @throws java.io.IOException If transferring a message fails due to some internal communication error, an exception is thrown. - */ - public void messageTransfer(String destination, Message msg, short confirmMode, short acquireMode) - throws IOException; - - - /** - *

This transfer streams a complete message using a single method. - * It uses pull-semantics instead of doing a push.

- *

Data is pulled from a Message object using read() - * and pushed using messageTransfer() and headers() followed by data() and endData(). - *
This method should only be used by large messages
- * There are two convenience Message classes to do this. - *

    - *
  • {@link org.apache.qpidity.nclient.util.FileMessage} - *
  • {@link org.apache.qpidity.nclient.util.StreamingMessage} - *
- * You can also implement a Message interface to wrap any - * data stream. - *

- * - * @param destination The exchange the message is being sent to. - * @param msg The Message to be sent. - * @param confirmMode
    off ({@link Session#TRANSFER_CONFIRM_MODE_NOT_REQUIRED}): confirmation - * is not required. Once a message has been transferred in pre-acquire - * mode (or once acquire has been sent in no-acquire mode) the message is considered - * transferred. - *

    - *

  • on ({@link Session#TRANSFER_CONFIRM_MODE_REQUIRED}): an acquired message - * is not considered transferred until the original - * transfer is complete. A complete transfer is signaled by execution.complete. - *
- * @param acquireMode
    - *
  • no-acquire ({@link Session#TRANSFER_ACQUIRE_MODE_NO_ACQUIRE}): the message - * must be explicitly acquired. - *
  • pre-acquire ({@link Session#TRANSFER_ACQUIRE_MODE_PRE_ACQUIRE}): the message - * is acquired when the transfer starts. - *
- * @throws java.io.IOException If transferring a message fails due to some internal communication error, an exception is thrown. - */ - public void messageStream(String destination, Message msg, short confirmMode, short acquireMode) throws IOException; - - /** - * This command transfers a message between two peers. - * - * @param destination Specifies the destination to which the message is to be transferred. - * @param acceptMode Indicates whether message.accept, session.complete, - * or nothing at all is required to indicate successful transfer of the message. - * - * @param acquireMode Indicates whether or not the transferred message has been acquired. - */ - public void messageTransfer(String destination, MessageAcceptMode acceptMode, MessageAcquireMode acquireMode, - Option ... options); - - /** - * Make a set of headers to be sent together with a message - * - * @param headers headers to be added - * @see org.apache.qpidity.transport.DeliveryProperties - * @see org.apache.qpidity.transport.MessageProperties - * @return The added headers. - */ - public Header header(Struct... headers); - - /** - * Add a byte array to the content of the message being sent. - * - * @param data Data to be added. - */ - public void data(byte[] data); - - /** - * A Add a ByteBuffer to the content of the message being sent. - *

Note that only the data between the buffer's current position and the - * buffer limit is added. - * It is therefore recommended to flip the buffer before adding it to the message, - * - * @param buf Data to be added. - */ - public void data(ByteBuffer buf); - - /** - * Add a string to the content of the message being sent. - * - * @param str String to be added. - */ - public void data(String str); - - /** - * Signals the end of data for the message. - */ - public void endData(); - - //------------------------------------------------------ - // Messaging methods - // Consumer - //------------------------------------------------------ - - /** - * Associate a message listener with a destination. - *

The destination is bound to a queue, and messages are filtered based - * on the provider filter map (message filtering is specific to the provider and in some cases might not be handled). - *

The valid options are: - *

    - *
  • {@link Option#EXCLUSIVE}:

    Requests exclusive subscription access, so that only this - * subscription can access the queue. - *

  • {@link Option#NONE}:

    This is an empty option, and has no effect. - *

- * - * @param queue The queue that the receiver is receiving messages from. - * @param destination The destination, or delivery tag, for the subscriber. - * @param confirmMode
    off ({@link Session#TRANSFER_CONFIRM_MODE_NOT_REQUIRED}): confirmation - * is not required. Once a message has been transferred in pre-acquire - * mode (or once acquire has been sent in no-acquire mode) the message is considered - * transferred. - *

    - *

  • on ({@link Session#TRANSFER_CONFIRM_MODE_REQUIRED}): an acquired message - * is not considered transferred until the original - * transfer is complete. A complete transfer is signaled by execution.complete. - *
- * @param acquireMode
    - *
  • no-acquire ({@link Session#TRANSFER_ACQUIRE_MODE_NO_ACQUIRE}): the message must - * be explicitly acquired. - *
  • pre-acquire ({@link Session#TRANSFER_ACQUIRE_MODE_PRE_ACQUIRE}): the message is - * acquired when the transfer starts. - *
- * @param listener The listener for this destination. To transfer large messages - * use a {@link org.apache.qpidity.nclient.MessagePartListener}. - * @param options Set of options. Valid options are {{@link Option#EXCLUSIVE} - * and {@link Option#NONE}. - * @param filter A set of filters for the subscription. The syntax and semantics of these filters varies - * according to the provider's implementation. - */ - public void messageSubscribe(String queue, String destination, short confirmMode, short acquireMode, - MessagePartListener listener, Map filter, Option... options); - - /** - * This method cancels a consumer. The server will not send any more messages to the specified destination. - * This does not affect already delivered messages. - * The client may receive a - * number of messages in between sending the cancel method and receiving - * notification that the cancellation has been completed. - * - * @param destination The destination to be cancelled. - */ - public void messageCancel(String destination, Option ... options); - - /** - * Associate a message listener with a destination. - *

Only one listener is permitted for each destination. When a new listener is created, - * it replaces the previous message listener. To prevent message loss, this occurs only when the original listener - * has completed processing a message. - * - * @param destination The destination the listener is associated with. - * @param listener The new listener for this destination. - */ - public void setMessageListener(String destination, MessagePartListener listener); - - /** - * Sets the mode of flow control used for a given destination. - *

With credit based flow control, the broker continually maintains its current - * credit balance with the recipient. The credit balance consists of two values, a message - * count, and a byte count. Whenever message data is sent, both counts must be decremented. - * If either value reaches zero, the flow of message data must stop. Additional credit is - * received via the {@link Session#messageFlow} method. - *

Window based flow control is identical to credit based flow control, however message - * acknowledgment implicitly grants a single unit of message credit, and the size of the - * message in byte credits for each acknowledged message. - * - * @param destination The destination to set the flow mode on. - * @param mode

  • credit ({@link Session#MESSAGE_FLOW_MODE_CREDIT}): choose credit based flow control - *
  • window ({@link Session#MESSAGE_FLOW_MODE_WINDOW}): choose window based flow control
- */ - public void messageSetFlowMode(String destination, MessageFlowMode mode, Option ... options); - - - /** - * This method controls the flow of message data to a given destination. It is used by the - * recipient of messages to dynamically match the incoming rate of message flow to its - * processing or forwarding capacity. Upon receipt of this method, the sender must add "value" - * number of the specified unit to the available credit balance for the specified destination. - * A value of 0 indicates an infinite amount of credit. This disables any limit for - * the given unit until the credit balance is zeroed with {@link Session#messageStop} - * or {@link Session#messageFlush}. - * - * @param destination The destination to set the flow. - * @param unit Specifies the unit of credit balance. - *

- * One of:

    - *
  • message ({@link Session#MESSAGE_FLOW_UNIT_MESSAGE}) - *
  • byte ({@link Session#MESSAGE_FLOW_UNIT_BYTE}) - *
- * @param value Number of credits, a value of 0 indicates an infinite amount of credit. - */ - public void messageFlow(String destination, MessageCreditUnit unit, long value, Option ... options); - - /** - * Forces the broker to exhaust its credit supply. - *

The credit on the broker will remain at zero once - * this method is completed. - * - * @param destination The destination on which the credit supply is to be exhausted. - */ - public void messageFlush(String destination, Option ... options); - - /** - * On receipt of this method, the brokers set credit to zero for a given - * destination. When confirmation of this method - * is issued credit is set to zero. No further messages will be sent until - * further credit is received. - * - * @param destination The destination on which to reset credit. - */ - public void messageStop(String destination, Option ... options); - - /** - * Acknowledge the receipt of a range of messages. - *

Messages must already be acquired, either by receiving them in - * pre-acquire mode or by explicitly acquiring them. - * - * @param ranges Range of messages to be acknowledged. - * @param accept pecify whether to send a message accept to the broker - */ - public void messageAcknowledge(RangeSet ranges, boolean accept); - - /** - * Reject a range of acquired messages. - *

The broker will deliver rejected messages to the - * alternate-exchange on the queue from which it came. If no alternate-exchange is - * defined for that queue the broker will discard the message. - * - * @param ranges Range of messages to be rejected. - * @param code The reject code must be one of {@link Session#MESSAGE_REJECT_CODE_GENERIC} or - * {@link Session#MESSAGE_REJECT_CODE_IMMEDIATE_DELIVERY_FAILED} (immediate delivery was attempted but - * failed). - * @param text String describing the reason for a message transfer rejection. - */ - public void messageReject(RangeSet ranges, MessageRejectCode code, String text, Option ... options); - - /** - * As it is possible that the broker does not manage to reject some messages, after completion of - * {@link Session#messageReject} this method will return the ranges of rejected messages. - *

Note that {@link Session#messageReject} and this methods are asynchronous therefore for accessing to the - * previously rejected messages this method must be invoked in conjunction with {@link Session#sync()}. - *

A recommended invocation sequence would be: - *

    - *
  • {@link Session#messageReject} - *
  • {@link Session#sync()} - *
  • {@link Session#getRejectedMessages()} - *
- * - * @return The rejected message ranges - */ - public RangeSet getRejectedMessages(); - - /** - * Try to acquire ranges of messages hence releasing them form the queue. - * This means that once acknowledged, a message will not be delivered to any other receiver. - *

As those messages may have been consumed by another receivers hence, - * message acquisition can fail. - * The outcome of the acquisition is returned as an array of ranges of qcquired messages. - *

This method should only be called on non-acquired messages. - * - * @param ranges Ranges of messages to be acquired. - * @return Indicates the acquired messages - */ - public Future messageAcquire(RangeSet ranges, Option ... options); - - /** - * Give up responsibility for processing ranges of messages. - *

Released messages are re-enqueued. - * - * @param ranges Ranges of messages to be released. - * @param options Valid option is: {@link Option#SET_REDELIVERED}) - */ - public void messageRelease(RangeSet ranges, Option ... options); - - // ----------------------------------------------- - // Local transaction methods - // ---------------------------------------------- - /** - * Selects the session for local transaction support. - */ - public void txSelect(Option ... options); - - /** - * Commit the receipt and delivery of all messages exchanged by this session's resources. - * - * @throws IllegalStateException If this session is not transacted, an exception will be thrown. - */ - public void txCommit(Option ... options) throws IllegalStateException; - - /** - * Roll back the receipt and delivery of all messages exchanged by this session's resources. - * - * @throws IllegalStateException If this session is not transacted, an exception will be thrown. - */ - public void txRollback(Option ... options) throws IllegalStateException; - - //--------------------------------------------- - // Queue methods - //--------------------------------------------- - - /** - * Declare a queue with the given queueName - *

Following are the valid options: - *

    - *
  • {@link Option#AUTO_DELETE}:

    If this field is set and the exclusive field is also set, - * then the queue is deleted when the connection closes. - * If this field is set and the exclusive field is not set the queue is deleted when all - * the consumers have finished using it. - *

  • {@link Option#DURABLE}:

    If set when creating a new queue, - * the queue will be marked as durable. Durable queues - * remain active when a server restarts. Non-durable queues (transient queues) are purged - * if/when a server restarts. Note that durable queues do not necessarily hold persistent - * messages, although it does not make sense to send persistent messages to a transient - * queue. - *

  • {@link Option#EXCLUSIVE}:

    Exclusive queues can only be used from one connection at a time. - * Once a connection declares an exclusive queue, that queue cannot be used by any other connections until the - * declaring connection closes. - *

  • {@link Option#PASSIVE}:

    If set, the server will not create the queue. - * This field allows the client to assert the presence of a queue without modifying the server state. - *

  • {@link Option#NONE}:

    Has no effect as it represents an empty option. - *

- *

In the absence of a particular option, the defaul value is false for each option - * - * @param queueName The name of the delcared queue. - * @param alternateExchange If a message is rejected by a queue, then it is sent to the alternate-exchange. A message - * may be rejected by a queue for the following reasons: - *

  1. The queue is deleted when it is not empty; - *
  2. Immediate delivery of a message is requested, but there are no consumers connected to - * the queue.
- * @param arguments Used for backward compatibility - * @param options Set of Options ( valide options are: {@link Option#AUTO_DELETE}, {@link Option#DURABLE}, - * {@link Option#EXCLUSIVE}, {@link Option#PASSIVE} and {@link Option#NONE}) - * @see Option - */ - public void queueDeclare(String queueName, String alternateExchange, Map arguments, - Option... options); - - /** - * Bind a queue with an exchange. - * - * @param queueName Specifies the name of the queue to bind. If the queue name is empty, refers to the current - * queue for the session, which is the last declared queue. - * @param exchangeName The exchange name. - * @param routingKey Specifies the routing key for the binding. The routing key is used for routing messages - * depending on the exchange configuration. Not all exchanges use a routing key - refer to - * the specific exchange documentation. If the queue name is empty, the server uses the last - * queue declared on the session. If the routing key is also empty, the server uses this - * queue name for the routing key as well. If the queue name is provided but the routing key - * is empty, the server does the binding with that empty routing key. The meaning of empty - * routing keys depends on the exchange implementation. - * @param arguments Used for backward compatibility - */ - public void exchangeBind(String queueName, String exchangeName, String routingKey, Map arguments, - Option ... options); - - /** - * Unbind a queue from an exchange. - * - * @param queueName Specifies the name of the queue to unbind. - * @param exchangeName The name of the exchange to unbind from. - * @param routingKey Specifies the routing key of the binding to unbind. - */ - public void exchangeUnbind(String queueName, String exchangeName, String routingKey, Option ... options); - - /** - * This method removes all messages from a queue. It does not cancel consumers. Purged messages - * are deleted without any formal "undo" mechanism. - * - * @param queueName Specifies the name of the queue to purge. If the queue name is empty, refers to the - * current queue for the session, which is the last declared queue. - */ - public void queuePurge(String queueName, Option ... options); - - /** - * This method deletes a queue. When a queue is deleted any pending messages are sent to a - * dead-letter queue if this is defined in the server configuration, and all consumers on the - * queue are cancelled. - *

Following are the valid options: - *

    - *
  • {@link Option#IF_EMPTY}:

    If set, the server will only delete the queue if it has no messages. - *

  • {@link Option#IF_UNUSED}:

    If set, the server will only delete the queue if it has no consumers. - * If the queue has consumers the server does does not delete it but raises a channel exception instead. - *

  • {@link Option#NONE}:

    Has no effect as it represents an empty option. - *

- *

- *

- *

In the absence of a particular option, the defaul value is false for each option

- * - * @param queueName Specifies the name of the queue to delete. If the queue name is empty, refers to the - * current queue for the session, which is the last declared queue. - * @param options Set of options (Valid options are: {@link Option#IF_EMPTY}, {@link Option#IF_UNUSED} - * and {@link Option#NONE}) - * @see Option - */ - public void queueDelete(String queueName, Option... options); - - - /** - * This method is used to request information on a particular queue. - * - * @param queueName The name of the queue for which information is requested. - * @return Information on the specified queue. - */ - public Future queueQuery(String queueName, Option ... options); - - - /** - * This method is used to request information on a particular binding. - * - * @param exchange The exchange name. - * @param queue The queue name. - * @param routingKey The routing key - * @param arguments bacward compatibilties params. - * @return Information on the specified binding. - */ - public Future exchangeBound(String exchange, String queue, String routingKey, - Map arguments, Option ... options); - - // -------------------------------------- - // exhcange methods - // -------------------------------------- - - /** - * This method creates an exchange. If the exchange already exists, - * the method verifies the class and checks the details are correct. - *

Valid options are: - *

    - *
  • {@link Option#AUTO_DELETE}:

    If set, the exchange is deleted when all queues have finished using it. - *

  • {@link Option#DURABLE}:

    If set, the exchange will - * be marked as durable. Durable exchanges remain active when a server restarts. Non-durable exchanges (transient - * exchanges) are purged when a server restarts. - *

  • {@link Option#PASSIVE}:

    If set, the server will not create the exchange. - * The client can use this to check whether an exchange exists without modifying the server state. - *

  • {@link Option#NONE}:

    This option is an empty option, and has no effect. - *

- *

In the absence of a particular option, the defaul value is false for each option

- * - * @param exchangeName The exchange name. - * @param type Each exchange belongs to one of a set of exchange types implemented by the server. The - * exchange types define the functionality of the exchange - i.e. how messages are routed - * through it. It is not valid or meaningful to attempt to change the type of an existing - * exchange. Default exchange types are: direct, topic, headers and fanout. - * @param alternateExchange In the event that a message cannot be routed, this is the name of the exchange to which - * the message will be sent. - * @param options Set of options (valid options are: {@link Option#AUTO_DELETE}, {@link Option#DURABLE}, - * {@link Option#PASSIVE}, {@link Option#NONE}) - * @param arguments Used for backward compatibility - * @see Option - */ - public void exchangeDeclare(String exchangeName, String type, String alternateExchange, - Map arguments, Option... options); - - /** - * This method deletes an exchange. When an exchange is deleted all queue bindings on the - * exchange are cancelled. - *

Following are the valid options: - *

    - *
  • {@link Option#IF_UNUSED}:

    If set, the server will only delete the exchange if it has no queue bindings. If the - * exchange has queue bindings the server does not delete it but raises a channel exception - * instead. - *

  • {@link Option#NONE}:

    Has no effect as it represents an empty option. - *

- *

Note that if an option is not set, it will default to false. - * - * @param exchangeName The name of exchange to be deleted. - * @param options Set of options. Valid options are: {@link Option#IF_UNUSED}, {@link Option#NONE}. - * @see Option - */ - public void exchangeDelete(String exchangeName, Option... options); - - - /** - * This method is used to request information about a particular exchange. - * - * @param exchangeName The name of the exchange about which information is requested. If not set, the method will - * return information about the default exchange. - * @return Information on the specified exchange. - */ - public Future exchangeQuery(String exchangeName, Option ... options); - - /** - * If the session receives a sessionClosed with an error code it - * informs the session's exceptionListener - * - * @param exceptionListner The exceptionListener - */ - public void setClosedListener(ClosedListener exceptionListner); -} diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/impl/ClientSession.java b/java/client/src/main/java/org/apache/qpidity/nclient/impl/ClientSession.java deleted file mode 100644 index f7978d0d98..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/nclient/impl/ClientSession.java +++ /dev/null @@ -1,206 +0,0 @@ -package org.apache.qpidity.nclient.impl; - -import java.io.EOFException; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.apache.qpidity.QpidException; -import org.apache.qpidity.api.Message; -import org.apache.qpidity.nclient.ClosedListener; -import org.apache.qpidity.nclient.MessagePartListener; -import org.apache.qpidity.transport.MessageAcceptMode; -import org.apache.qpidity.transport.MessageAcquireMode; -import org.apache.qpidity.transport.Option; -import org.apache.qpidity.transport.Range; -import org.apache.qpidity.transport.RangeSet; - -import static org.apache.qpidity.transport.Option.*; - -/** - * Implements a Qpid Sesion. - */ -public class ClientSession extends org.apache.qpidity.transport.Session implements org.apache.qpidity.nclient.DtxSession -{ - static - { - String max = "message_size_before_sync"; // KB's - try - { - MAX_NOT_SYNC_DATA_LENGH = new Long(System.getProperties().getProperty(max, "200000000")); - } - catch (NumberFormatException e) - { - // use default size - MAX_NOT_SYNC_DATA_LENGH = 200000000; - } - String flush = "message_size_before_flush"; - try - { - MAX_NOT_FLUSH_DATA_LENGH = new Long(System.getProperties().getProperty(flush, "2000000")); - } - catch (NumberFormatException e) - { - // use default size - MAX_NOT_FLUSH_DATA_LENGH = 20000000; - } - } - - private static long MAX_NOT_SYNC_DATA_LENGH; - private static long MAX_NOT_FLUSH_DATA_LENGH; - - private Map _messageListeners = new ConcurrentHashMap(); - private ClosedListener _exceptionListner; - private RangeSet _rejectedMessages; - private long _currentDataSizeNotSynced; - private long _currentDataSizeNotFlushed; - - public ClientSession(byte[] name) - { - super(name); - } - - public void messageAcknowledge(RangeSet ranges, boolean accept) - { - for (Range range : ranges) - { - super.processed(range); - } - super.flushProcessed(accept ? BATCH : NONE); - if (accept) - { - messageAccept(ranges); - } - } - - public void messageSubscribe(String queue, String destination, short acceptMode, short acquireMode, MessagePartListener listener, Map filter, Option... options) - { - setMessageListener(destination,listener); - super.messageSubscribe(queue, destination, MessageAcceptMode.get(acceptMode), - MessageAcquireMode.get(acquireMode), null, 0, filter, - options); - } - - public void messageTransfer(String destination, Message msg, short acceptMode, short acquireMode) throws IOException - { - // The javadoc clearly says that this method is suitable for small messages - // therefore reading the content in one shot. - ByteBuffer data = msg.readData(); - super.messageTransfer(destination, MessageAcceptMode.get(acceptMode), - MessageAcquireMode.get(acquireMode)); - // super.header(msg.getDeliveryProperties(),msg.getMessageProperties() ); - if( msg.getHeader() == null || msg.getDeliveryProperties().isDirty() || msg.getMessageProperties().isDirty() ) - { - msg.setHeader( super.header(msg.getDeliveryProperties(),msg.getMessageProperties()) ); - msg.getDeliveryProperties().setDirty(false); - msg.getMessageProperties().setDirty(false); - } - else - { - super.header(msg.getHeader()); - } - data( data ); - endData(); - } - - public void sync() - { - super.sync(); - _currentDataSizeNotSynced = 0; - } - - /* ------------------------- - * Data methods - * ------------------------*/ - - public void data(ByteBuffer buf) - { - _currentDataSizeNotSynced = _currentDataSizeNotSynced + buf.remaining(); - _currentDataSizeNotFlushed = _currentDataSizeNotFlushed + buf.remaining(); - super.data(buf); - } - - public void data(String str) - { - _currentDataSizeNotSynced = _currentDataSizeNotSynced + str.getBytes().length; - super.data(str); - } - - public void data(byte[] bytes) - { - _currentDataSizeNotSynced = _currentDataSizeNotSynced + bytes.length; - super.data(bytes); - } - - public void messageStream(String destination, Message msg, short acceptMode, short acquireMode) throws IOException - { - super.messageTransfer(destination, MessageAcceptMode.get(acceptMode), - MessageAcquireMode.get(acquireMode)); - super.header(msg.getDeliveryProperties(),msg.getMessageProperties()); - boolean b = true; - int count = 0; - while(b) - { - try - { - System.out.println("count : " + count++); - data(msg.readData()); - } - catch(EOFException e) - { - b = false; - } - } - endData(); - } - - public void endData() - { - super.endData(); - /* if( MAX_NOT_SYNC_DATA_LENGH != -1 && _currentDataSizeNotSynced >= MAX_NOT_SYNC_DATA_LENGH) - { - sync(); - } - if( MAX_NOT_FLUSH_DATA_LENGH != -1 && _currentDataSizeNotFlushed >= MAX_NOT_FLUSH_DATA_LENGH) - { - executionFlush(); - _currentDataSizeNotFlushed = 0; - }*/ - } - - public RangeSet getRejectedMessages() - { - return _rejectedMessages; - } - - public void setMessageListener(String destination, MessagePartListener listener) - { - if (listener == null) - { - throw new IllegalArgumentException("Cannot set message listener to null"); - } - _messageListeners.put(destination, listener); - } - - public void setClosedListener(ClosedListener exceptionListner) - { - _exceptionListner = exceptionListner; - } - - void setRejectedMessages(RangeSet rejectedMessages) - { - _rejectedMessages = rejectedMessages; - } - - void notifyException(QpidException ex) - { - _exceptionListner.onClosed(null, null, null); - } - - Map getMessageListeners() - { - return _messageListeners; - } -} diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/impl/ClientSessionDelegate.java b/java/client/src/main/java/org/apache/qpidity/nclient/impl/ClientSessionDelegate.java deleted file mode 100644 index da6f5e7d45..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/nclient/impl/ClientSessionDelegate.java +++ /dev/null @@ -1,75 +0,0 @@ -package org.apache.qpidity.nclient.impl; - -import java.nio.ByteBuffer; - -import org.apache.qpidity.ErrorCode; - -import org.apache.qpidity.nclient.MessagePartListener; - -import org.apache.qpidity.QpidException; -import org.apache.qpidity.transport.Data; -import org.apache.qpidity.transport.Header; -import org.apache.qpidity.transport.MessageReject; -import org.apache.qpidity.transport.MessageTransfer; -import org.apache.qpidity.transport.Range; -import org.apache.qpidity.transport.Session; -import org.apache.qpidity.transport.SessionDetached; -import org.apache.qpidity.transport.SessionDelegate; - - -public class ClientSessionDelegate extends SessionDelegate -{ - private MessageTransfer _currentTransfer; - private MessagePartListener _currentMessageListener; - - @Override public void sessionDetached(Session ssn, SessionDetached dtc) - { - ((ClientSession)ssn).notifyException(new QpidException("", ErrorCode.get(dtc.getCode().getValue()),null)); - } - - // -------------------------------------------- - // Message methods - // -------------------------------------------- - @Override public void data(Session ssn, Data data) - { - _currentMessageListener.data(data.getData()); - if (data.isLast()) - { - _currentMessageListener.messageReceived(); - } - } - - @Override public void header(Session ssn, Header header) - { - _currentMessageListener.messageHeader(header); - if( header.hasNoPayload()) - { - _currentMessageListener.data(ByteBuffer.allocate(0)); - _currentMessageListener.messageReceived(); - } - } - - - @Override public void messageTransfer(Session session, MessageTransfer currentTransfer) - { - _currentTransfer = currentTransfer; - _currentMessageListener = ((ClientSession)session).getMessageListeners().get(currentTransfer.getDestination()); - _currentMessageListener.messageTransfer(currentTransfer.getId()); - } - - @Override public void messageReject(Session session, MessageReject struct) - { - for (Range range : struct.getTransfers()) - { - for (long l = range.getLower(); l <= range.getUpper(); l++) - { - System.out.println("message rejected: " + - session.getCommand((int) l)); - } - } - ((ClientSession)session).setRejectedMessages(struct.getTransfers()); - ((ClientSession)session).notifyException(new QpidException("Message Rejected",ErrorCode.MESSAGE_REJECTED,null)); - session.processed(struct); - } - -} diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/impl/Constants.java b/java/client/src/main/java/org/apache/qpidity/nclient/impl/Constants.java deleted file mode 100644 index 83d491baad..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/nclient/impl/Constants.java +++ /dev/null @@ -1,78 +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.qpidity.nclient.impl; - -/** - * This class holds all the 0.10 client constants which value can be set - * through properties. - */ -public class Constants -{ - static - { - - String max="message_size_before_sync";// KB's - try - { - MAX_NOT_SYNC_DATA_LENGH=new Long(System.getProperties().getProperty(max, "200000000")); - } - catch (NumberFormatException e) - { - // use default size - MAX_NOT_SYNC_DATA_LENGH=200000000; - } - String flush="message_size_before_flush"; - try - { - MAX_NOT_FLUSH_DATA_LENGH=new Long(System.getProperties().getProperty(flush, "2000000")); - } - catch (NumberFormatException e) - { - // use default size - MAX_NOT_FLUSH_DATA_LENGH=20000000; - } - } - - /** - * The total message size in KBs that can be transferted before - * client and broker are synchronized. - * A sync will result in the client library releasing the sent messages - * from memory. (messages are kept - * in memory so client can reconnect to a broker in the event of a failure) - *

- * Property name: message_size_before_sync - *

- * Default value: 200000000 - */ - public static long MAX_NOT_SYNC_DATA_LENGH; - /** - * The total message size in KBs that can be transferted before - * messages are flushed. - * When a flush returns all messages have reached the broker. - *

- * Property name: message_size_before_flush - *

- * Default value: 200000000 - */ - public static long MAX_NOT_FLUSH_DATA_LENGH; - -} diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/impl/DemoClient.java b/java/client/src/main/java/org/apache/qpidity/nclient/impl/DemoClient.java deleted file mode 100644 index 05b99a3cf1..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/nclient/impl/DemoClient.java +++ /dev/null @@ -1,94 +0,0 @@ -package org.apache.qpidity.nclient.impl; - -import org.apache.qpidity.ErrorCode; -import org.apache.qpidity.api.Message; -import org.apache.qpidity.nclient.Client; -import org.apache.qpidity.nclient.Connection; -import org.apache.qpidity.nclient.ClosedListener; -import org.apache.qpidity.nclient.Session; -import org.apache.qpidity.nclient.util.MessageListener; -import org.apache.qpidity.nclient.util.MessagePartListenerAdapter; -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.MessageAcceptMode; -import org.apache.qpidity.transport.MessageAcquireMode; -import org.apache.qpidity.transport.MessageProperties; - -import java.util.UUID; - -public class DemoClient -{ - public static MessagePartListenerAdapter createAdapter() - { - return new MessagePartListenerAdapter(new MessageListener() - { - public void onMessage(Message m) - { - System.out.println("\n================== Received Msg =================="); - System.out.println("Message Id : " + m.getMessageProperties().getMessageId()); - System.out.println(m.toString()); - System.out.println("================== End Msg ==================\n"); - } - - }); - } - - public static final void main(String[] args) - { - Connection conn = Client.createConnection(); - try{ - conn.connect("0.0.0.0", 5672, "test", "guest", "guest"); - }catch(Exception e){ - e.printStackTrace(); - } - - Session ssn = conn.createSession(50000); - ssn.setClosedListener(new ClosedListener() - { - public void onClosed(ErrorCode errorCode, String reason, Throwable t) - { - System.out.println("ErrorCode : " + errorCode + " reason : " + reason); - } - }); - ssn.queueDeclare("queue1", null, null); - ssn.exchangeBind("queue1", "amq.direct", "queue1",null); - ssn.sync(); - - ssn.messageSubscribe("queue1", "myDest", (short)0, (short)0,createAdapter(), null); - - // queue - ssn.messageTransfer("amq.direct", MessageAcceptMode.NONE, MessageAcquireMode.PRE_ACQUIRED); - ssn.header(new DeliveryProperties().setRoutingKey("queue1"), - new MessageProperties().setMessageId(UUID.randomUUID())); - ssn.data("this is the data"); - ssn.endData(); - - //reject - ssn.messageTransfer("amq.direct", MessageAcceptMode.NONE, MessageAcquireMode.PRE_ACQUIRED); - ssn.data("this should be rejected"); - ssn.header(new DeliveryProperties().setRoutingKey("stocks")); - ssn.endData(); - ssn.sync(); - - // topic subs - ssn.messageSubscribe("topic1", "myDest2", (short)0, (short)0,createAdapter(), null); - ssn.messageSubscribe("topic2", "myDest3", (short)0, (short)0,createAdapter(), null); - ssn.messageSubscribe("topic3", "myDest4", (short)0, (short)0,createAdapter(), null); - ssn.sync(); - - ssn.queueDeclare("topic1", null, null); - ssn.exchangeBind("topic1", "amq.topic", "stock.*",null); - ssn.queueDeclare("topic2", null, null); - ssn.exchangeBind("topic2", "amq.topic", "stock.us.*",null); - ssn.queueDeclare("topic3", null, null); - ssn.exchangeBind("topic3", "amq.topic", "stock.us.rh",null); - ssn.sync(); - - // topic - ssn.messageTransfer("amq.topic", MessageAcceptMode.NONE, MessageAcquireMode.PRE_ACQUIRED); - ssn.data("Topic message"); - ssn.header(new DeliveryProperties().setRoutingKey("stock.us.ibm"), - new MessageProperties().setMessageId(UUID.randomUUID())); - ssn.endData(); - } - -} diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/impl/LargeMsgDemoClient.java b/java/client/src/main/java/org/apache/qpidity/nclient/impl/LargeMsgDemoClient.java deleted file mode 100644 index 64ffe17fe0..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/nclient/impl/LargeMsgDemoClient.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.apache.qpidity.nclient.impl; - -import java.io.FileInputStream; - -import org.apache.qpidity.ErrorCode; -import org.apache.qpidity.api.Message; -import org.apache.qpidity.nclient.Client; -import org.apache.qpidity.nclient.Connection; -import org.apache.qpidity.nclient.ClosedListener; -import org.apache.qpidity.nclient.Session; -import org.apache.qpidity.nclient.util.FileMessage; -import org.apache.qpidity.nclient.util.MessageListener; -import org.apache.qpidity.nclient.util.MessagePartListenerAdapter; -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.MessageProperties; - -import java.util.UUID; - -public class LargeMsgDemoClient -{ - public static MessagePartListenerAdapter createAdapter() - { - return new MessagePartListenerAdapter(new MessageListener() - { - public void onMessage(Message m) - { - System.out.println("\n================== Received Msg =================="); - System.out.println("Message Id : " + m.getMessageProperties().getMessageId()); - System.out.println(m.toString()); - System.out.println("================== End Msg ==================\n"); - } - - }); - } - - public static final void main(String[] args) - { - Connection conn = Client.createConnection(); - try{ - conn.connect("0.0.0.0", 5672, "test", "guest", "guest"); - }catch(Exception e){ - e.printStackTrace(); - } - - Session ssn = conn.createSession(50000); - ssn.setClosedListener(new ClosedListener() - { - public void onClosed(ErrorCode errorCode, String reason, Throwable t) - { - System.out.println("ErrorCode : " + errorCode + " reason : " + reason); - } - }); - ssn.queueDeclare("queue1", null, null); - ssn.exchangeBind("queue1", "amq.direct", "queue1",null); - ssn.sync(); - - ssn.messageSubscribe("queue1", "myDest", (short)0, (short)0,createAdapter(), null); - - try - { - FileMessage msg = new FileMessage(new FileInputStream("/home/rajith/TestFile"), - 1024, - new DeliveryProperties().setRoutingKey("queue1"), - new MessageProperties().setMessageId(UUID.randomUUID())); - - // queue - ssn.messageStream("amq.direct",msg, (short) 0, (short) 1); - ssn.sync(); - } - catch(Exception e) - { - e.printStackTrace(); - } - } - -} diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/interop/BasicInteropTest.java b/java/client/src/main/java/org/apache/qpidity/nclient/interop/BasicInteropTest.java deleted file mode 100644 index e452091622..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/nclient/interop/BasicInteropTest.java +++ /dev/null @@ -1,156 +0,0 @@ -package org.apache.qpidity.nclient.interop; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.qpidity.ErrorCode; -import org.apache.qpidity.QpidException; -import org.apache.qpidity.api.Message; -import org.apache.qpidity.nclient.Client; -import org.apache.qpidity.nclient.Connection; -import org.apache.qpidity.nclient.ClosedListener; -import org.apache.qpidity.nclient.Session; -import org.apache.qpidity.nclient.util.MessageListener; -import org.apache.qpidity.nclient.util.MessagePartListenerAdapter; -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.MessageAcceptMode; -import org.apache.qpidity.transport.MessageAcquireMode; -import org.apache.qpidity.transport.MessageCreditUnit; -import org.apache.qpidity.transport.MessageFlowMode; -import org.apache.qpidity.transport.MessageProperties; -import org.apache.qpidity.transport.RangeSet; - -public class BasicInteropTest implements ClosedListener -{ - - private Session session; - private Connection conn; - private String host; - - public BasicInteropTest(String host) - { - this.host = host; - } - - public void close() throws QpidException - { - conn.close(); - } - - public void testCreateConnection(){ - System.out.println("------- Creating connection--------"); - conn = Client.createConnection(); - try{ - conn.connect(host, 5672, "test", "guest", "guest"); - }catch(Exception e){ - System.out.println("------- Error Creating connection--------"); - e.printStackTrace(); - System.exit(1); - } - System.out.println("------- Connection created Suscessfully --------"); - } - - public void testCreateSession(){ - System.out.println("------- Creating session --------"); - session = conn.createSession(0); - System.out.println("------- Session created sucessfully --------"); - } - - public void testExchange(){ - System.out.println("------- Creating an exchange --------"); - session.exchangeDeclare("test", "direct", "", null); - session.sync(); - System.out.println("------- Exchange created --------"); - } - - public void testQueue(){ - System.out.println("------- Creating a queue --------"); - session.queueDeclare("testQueue", "", null); - session.sync(); - System.out.println("------- Queue created --------"); - - System.out.println("------- Binding a queue --------"); - session.exchangeBind("testQueue", "test", "testKey", null); - session.sync(); - System.out.println("------- Queue bound --------"); - } - - public void testSendMessage(){ - System.out.println("------- Sending a message --------"); - session.messageTransfer("test", MessageAcceptMode.NONE, MessageAcquireMode.PRE_ACQUIRED); - - Map props = new HashMap(); - props.put("name", "rajith"); - props.put("age", 10); - props.put("spf", 8.5); - session.header(new DeliveryProperties().setRoutingKey("testKey"),new MessageProperties().setApplicationHeaders(props)); - - //session.header(new DeliveryProperties().setRoutingKey("testKey")); - - session.data("TestMessage"); - session.endData(); - session.sync(); - System.out.println("------- Message sent --------"); - } - - public void testSubscribe() - { - System.out.println("------- Sending a subscribe --------"); - session.messageSubscribe("testQueue", "myDest", - Session.TRANSFER_CONFIRM_MODE_REQUIRED, - Session.TRANSFER_ACQUIRE_MODE_PRE_ACQUIRE, - new MessagePartListenerAdapter(new MessageListener(){ - - public void onMessage(Message message) - { - System.out.println("--------Message Received--------"); - System.out.println(message.toString()); - System.out.println("--------/Message Received--------"); - RangeSet ack = new RangeSet(); - ack.add(message.getMessageTransferId(),message.getMessageTransferId()); - session.messageAcknowledge(ack, true); - } - - }), - null); - - System.out.println("------- Setting Credit mode --------"); - session.messageSetFlowMode("myDest", MessageFlowMode.WINDOW); - System.out.println("------- Setting Credit --------"); - session.messageFlow("myDest", MessageCreditUnit.MESSAGE, 1); - session.messageFlow("myDest", MessageCreditUnit.BYTE, -1); - } - - public void testMessageFlush() - { - session.messageFlush("myDest"); - session.sync(); - } - - public void onClosed(ErrorCode errorCode, String reason, Throwable t) - { - System.out.println("------- Broker Notified an error --------"); - System.out.println("------- " + errorCode + " --------"); - System.out.println("------- " + reason + " --------"); - System.out.println("------- /Broker Notified an error --------"); - } - - public static void main(String[] args) throws QpidException - { - String host = "0.0.0.0"; - if (args.length>0) - { - host = args[0]; - } - - BasicInteropTest t = new BasicInteropTest(host); - t.testCreateConnection(); - t.testCreateSession(); - t.testExchange(); - t.testQueue(); - t.testSubscribe(); - t.testSendMessage(); - t.testMessageFlush(); - t.close(); - } -} diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/util/ByteBufferMessage.java b/java/client/src/main/java/org/apache/qpidity/nclient/util/ByteBufferMessage.java deleted file mode 100644 index 833f905b58..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/nclient/util/ByteBufferMessage.java +++ /dev/null @@ -1,160 +0,0 @@ -package org.apache.qpidity.nclient.util; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.LinkedList; -import java.util.Queue; - -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.MessageProperties; -import org.apache.qpidity.transport.Header; -import org.apache.qpidity.api.Message; - -/** - *

A Simple implementation of the message interface - * for small messages. When the readData methods are called - * we assume the message is complete. i.e there want be any - * appendData operations after that.

- * - *

If you need large message support please see - * FileMessage and StreamingMessage - *

- */ -public class ByteBufferMessage implements Message -{ - private Queue _data = new LinkedList(); - private ByteBuffer _readBuffer; - private int _dataSize; - private DeliveryProperties _currentDeliveryProps; - private MessageProperties _currentMessageProps; - private int _transferId; - private Header _header; - - public void setHeader(Header header) { - _header = header; - } - - public Header getHeader() { - return _header; - } - - public ByteBufferMessage() - { - _currentDeliveryProps = new DeliveryProperties(); - _currentMessageProps = new MessageProperties(); - } - - public ByteBufferMessage(int transferId) - { - _transferId = transferId; - } - - public int getMessageTransferId() - { - return _transferId; - } - - public void clearData() - { - _data = new LinkedList(); - _readBuffer = null; - } - - public void appendData(byte[] src) throws IOException - { - appendData(ByteBuffer.wrap(src)); - } - - /** - * write the data from the current position up to the buffer limit - */ - public void appendData(ByteBuffer src) throws IOException - { - _data.offer(src); - _dataSize += src.remaining(); - } - - public DeliveryProperties getDeliveryProperties() - { - return _currentDeliveryProps; - } - - public MessageProperties getMessageProperties() - { - return _currentMessageProps; - } - - public void setDeliveryProperties(DeliveryProperties props) - { - _currentDeliveryProps = props; - } - - public void setMessageProperties(MessageProperties props) - { - _currentMessageProps = props; - } - - public void readData(byte[] target) throws IOException - { - getReadBuffer().get(target); - } - - public ByteBuffer readData() throws IOException - { - return getReadBuffer(); - } - - private void buildReadBuffer() - { - //optimize for the simple cases - if(_data.size() == 1) - { - _readBuffer = _data.element().duplicate(); - } - else - { - _readBuffer = ByteBuffer.allocate(_dataSize); - for(ByteBuffer buf:_data) - { - _readBuffer.put(buf); - } - _readBuffer.flip(); - } - } - - private ByteBuffer getReadBuffer() throws IOException - { - if (_readBuffer != null ) - { - return _readBuffer.slice(); - } - else - { - if (_data.size() >0) - { - buildReadBuffer(); - return _readBuffer.slice(); - } - else - { - throw new IOException("No Data to read"); - } - } - } - - //hack for testing - @Override public String toString() - { - try - { - ByteBuffer temp = getReadBuffer(); - byte[] b = new byte[temp.remaining()]; - temp.get(b); - return new String(b); - } - catch(IOException e) - { - return "No data"; - } - } -} diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/util/FileMessage.java b/java/client/src/main/java/org/apache/qpidity/nclient/util/FileMessage.java deleted file mode 100644 index 289d03574d..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/nclient/util/FileMessage.java +++ /dev/null @@ -1,96 +0,0 @@ -package org.apache.qpidity.nclient.util; - -import java.io.EOFException; -import java.io.FileInputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.MappedByteBuffer; -import java.nio.channels.FileChannel; - -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.MessageProperties; -import org.apache.qpidity.transport.Header; -import org.apache.qpidity.api.Message; - -/** - * FileMessage provides pull style semantics for - * larges messages backed by a disk. - * Instead of loading all data into memeory it uses - * FileChannel to map regions of the file into memeory - * at a time. - * - * The write methods are not supported. - * - * From the standpoint of performance it is generally - * only worth mapping relatively large files into memory. - * - * FileMessage msg = new FileMessage(in,delProps,msgProps); - * session.messageTransfer(dest,msg,0,0); - * - * The messageTransfer method will read the file in chunks - * and stream it. - * - */ -public class FileMessage extends ReadOnlyMessage implements Message -{ - private FileChannel _fileChannel; - private int _chunkSize; - private long _fileSize; - private long _pos = 0; - - public FileMessage(FileInputStream in,int chunkSize,DeliveryProperties deliveryProperties,MessageProperties messageProperties)throws IOException - { - _messageProperties = messageProperties; - _deliveryProperties = deliveryProperties; - - _fileChannel = in.getChannel(); - _chunkSize = chunkSize; - _fileSize = _fileChannel.size(); - - if (_fileSize <= _chunkSize) - { - _chunkSize = (int)_fileSize; - } - } - - public void setHeader(Header header) { - //To change body of implemented methods use File | Settings | File Templates. - } - - public Header getHeader() { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - public void readData(byte[] target) throws IOException - { - throw new UnsupportedOperationException(); - } - - public ByteBuffer readData() throws IOException - { - if (_pos == _fileSize) - { - throw new EOFException(); - } - - if (_pos + _chunkSize > _fileSize) - { - _chunkSize = (int)(_fileSize - _pos); - } - MappedByteBuffer bb = _fileChannel.map(FileChannel.MapMode.READ_ONLY, _pos, _chunkSize); - _pos += _chunkSize; - return bb; - } - - /** - * This message is used by an application user to - * provide data to the client library using pull style - * semantics. Since the message is not transfered yet, it - * does not have a transfer id. Hence this method is not - * applicable to this implementation. - */ - public int getMessageTransferId() - { - throw new UnsupportedOperationException(); - } -} diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/util/MessageListener.java b/java/client/src/main/java/org/apache/qpidity/nclient/util/MessageListener.java deleted file mode 100644 index 43c20eb6b5..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/nclient/util/MessageListener.java +++ /dev/null @@ -1,34 +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.qpidity.nclient.util; - -import org.apache.qpidity.api.Message; - -/** - *A message listener - */ -public interface MessageListener -{ - /** - * Process an incoming message. - * - * @param message The incoming message. - */ - public void onMessage(Message message); -} diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/util/MessagePartListenerAdapter.java b/java/client/src/main/java/org/apache/qpidity/nclient/util/MessagePartListenerAdapter.java deleted file mode 100644 index 757d44fbbb..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/nclient/util/MessagePartListenerAdapter.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.apache.qpidity.nclient.util; - -import java.io.IOException; -import java.nio.ByteBuffer; - -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.MessageProperties; -import org.apache.qpidity.transport.Header; -import org.apache.qpidity.nclient.MessagePartListener; - -/** - * This is a simple message assembler. - * Will call onMessage method of the adaptee - * when all message data is read. - * - * This is a good convinience utility for handling - * small messages - */ -public class MessagePartListenerAdapter implements MessagePartListener -{ - MessageListener _adaptee; - ByteBufferMessage _currentMsg; - - public MessagePartListenerAdapter(MessageListener listener) - { - _adaptee = listener; - } - - public void messageTransfer(int transferId) - { - _currentMsg = new ByteBufferMessage(transferId); - } - - public void data(ByteBuffer src) - { - try - { - _currentMsg.appendData(src); - } - catch(IOException e) - { - // A chance for IO exception - // doesn't occur as we are using - // a ByteBuffer - } - } - - public void messageHeader(Header header) - { - _currentMsg.setDeliveryProperties(header.get(DeliveryProperties.class)); - _currentMsg.setMessageProperties(header.get(MessageProperties.class)); - } - - public void messageReceived() - { - _adaptee.onMessage(_currentMsg); - } - -} diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/util/ReadOnlyMessage.java b/java/client/src/main/java/org/apache/qpidity/nclient/util/ReadOnlyMessage.java deleted file mode 100644 index 8ff5c62a25..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/nclient/util/ReadOnlyMessage.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.apache.qpidity.nclient.util; - -import java.nio.ByteBuffer; - -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.MessageProperties; -import org.apache.qpidity.api.Message; - -public abstract class ReadOnlyMessage implements Message -{ - MessageProperties _messageProperties; - DeliveryProperties _deliveryProperties; - - public void appendData(byte[] src) - { - throw new UnsupportedOperationException("This Message is read only after the initial source"); - } - - public void appendData(ByteBuffer src) - { - throw new UnsupportedOperationException("This Message is read only after the initial source"); - } - - public DeliveryProperties getDeliveryProperties() - { - return _deliveryProperties; - } - - public MessageProperties getMessageProperties() - { - return _messageProperties; - } - - public void clearData() - { - throw new UnsupportedOperationException("This Message is read only after the initial source, cannot clear data"); - } -} diff --git a/java/client/src/main/java/org/apache/qpidity/nclient/util/StreamingMessage.java b/java/client/src/main/java/org/apache/qpidity/nclient/util/StreamingMessage.java deleted file mode 100644 index 6c7f9e9db7..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/nclient/util/StreamingMessage.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.apache.qpidity.nclient.util; - -import java.io.EOFException; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.channels.SocketChannel; - -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.MessageProperties; -import org.apache.qpidity.transport.Header; -import org.apache.qpidity.api.Message; - -public class StreamingMessage extends ReadOnlyMessage implements Message -{ - SocketChannel _socChannel; - private int _chunkSize; - private ByteBuffer _readBuf; - - public Header getHeader() { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - public void setHeader(Header header) { - //To change body of implemented methods use File | Settings | File Templates. - } - - public StreamingMessage(SocketChannel in,int chunkSize,DeliveryProperties deliveryProperties,MessageProperties messageProperties)throws IOException - { - _messageProperties = messageProperties; - _deliveryProperties = deliveryProperties; - - _socChannel = in; - _chunkSize = chunkSize; - _readBuf = ByteBuffer.allocate(_chunkSize); - } - - public void readData(byte[] target) throws IOException - { - throw new UnsupportedOperationException(); - } - - public ByteBuffer readData() throws IOException - { - if(_socChannel.isConnected() && _socChannel.isOpen()) - { - _readBuf.clear(); - _socChannel.read(_readBuf); - } - else - { - throw new EOFException("The underlying socket/channel has closed"); - } - - return _readBuf.duplicate(); - } - - /** - * This message is used by an application user to - * provide data to the client library using pull style - * semantics. Since the message is not transfered yet, it - * does not have a transfer id. Hence this method is not - * applicable to this implementation. - */ - public int getMessageTransferId() - { - throw new UnsupportedOperationException(); - } -} diff --git a/java/client/src/main/java/org/apache/qpidity/njms/ExceptionHelper.java b/java/client/src/main/java/org/apache/qpidity/njms/ExceptionHelper.java deleted file mode 100644 index e00f9008d3..0000000000 --- a/java/client/src/main/java/org/apache/qpidity/njms/ExceptionHelper.java +++ /dev/null @@ -1,60 +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.qpidity.njms; - -import org.apache.qpidity.QpidException; - -import javax.jms.JMSException; -import javax.transaction.xa.XAException; - -/** - * Helper class for handling exceptions - */ -public class ExceptionHelper -{ - static public JMSException convertQpidExceptionToJMSException(Exception exception) - { - JMSException jmsException = null; - if (!(exception instanceof JMSException)) - { - if (exception instanceof QpidException) - { - jmsException = new JMSException(exception.getMessage(), String.valueOf(((QpidException) exception).getErrorCode())); - } - else - { - jmsException = new JMSException(exception.getMessage()); - } - jmsException.setLinkedException(exception); - jmsException.initCause(exception); - } - else - { - jmsException = (JMSException) exception; - } - return jmsException; - } - - static public XAException convertQpidExceptionToXAException(QpidException exception) - { - String qpidErrorCode = String.valueOf(exception.getErrorCode()); - // todo map this error to an XA code - int xaCode = XAException.XAER_PROTO; - return new XAException(xaCode); - } -} diff --git a/java/common/Composite.tpl b/java/common/Composite.tpl index 5df1ef44fb..37e3bf8853 100644 --- a/java/common/Composite.tpl +++ b/java/common/Composite.tpl @@ -1,4 +1,4 @@ -package org.apache.qpidity.transport; +package org.apache.qpid.transport; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -6,12 +6,12 @@ import java.util.List; import java.util.Map; import java.util.UUID; -import org.apache.qpidity.transport.codec.Decoder; -import org.apache.qpidity.transport.codec.Encodable; -import org.apache.qpidity.transport.codec.Encoder; -import org.apache.qpidity.transport.codec.Validator; +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encodable; +import org.apache.qpid.transport.codec.Encoder; +import org.apache.qpid.transport.codec.Validator; -import org.apache.qpidity.transport.network.Frame; +import org.apache.qpid.transport.network.Frame; ${ from genutil import * diff --git a/java/common/Constant.tpl b/java/common/Constant.tpl index 695812ea75..7194a61dfc 100644 --- a/java/common/Constant.tpl +++ b/java/common/Constant.tpl @@ -1,4 +1,4 @@ -package org.apache.qpidity.transport; +package org.apache.qpid.transport; ${from genutil import *} diff --git a/java/common/Enum.tpl b/java/common/Enum.tpl index 337feb7065..2ec1d22522 100644 --- a/java/common/Enum.tpl +++ b/java/common/Enum.tpl @@ -1,4 +1,4 @@ -package org.apache.qpidity.transport; +package org.apache.qpid.transport; public enum $name { ${ diff --git a/java/common/Invoker.tpl b/java/common/Invoker.tpl index 4e174619f0..21a17624a6 100644 --- a/java/common/Invoker.tpl +++ b/java/common/Invoker.tpl @@ -1,4 +1,4 @@ -package org.apache.qpidity.transport; +package org.apache.qpid.transport; import java.util.List; import java.util.Map; diff --git a/java/common/MethodDelegate.tpl b/java/common/MethodDelegate.tpl index e5ab1ae1e7..84fa0e43da 100644 --- a/java/common/MethodDelegate.tpl +++ b/java/common/MethodDelegate.tpl @@ -1,4 +1,4 @@ -package org.apache.qpidity.transport; +package org.apache.qpid.transport; public abstract class MethodDelegate { diff --git a/java/common/Option.tpl b/java/common/Option.tpl index 3228949d87..d45c004f6f 100644 --- a/java/common/Option.tpl +++ b/java/common/Option.tpl @@ -1,4 +1,4 @@ -package org.apache.qpidity.transport; +package org.apache.qpid.transport; public enum Option { diff --git a/java/common/StructFactory.tpl b/java/common/StructFactory.tpl index b27621b1d2..f3dcbbd68a 100644 --- a/java/common/StructFactory.tpl +++ b/java/common/StructFactory.tpl @@ -1,4 +1,4 @@ -package org.apache.qpidity.transport; +package org.apache.qpid.transport; class StructFactory { diff --git a/java/common/Type.tpl b/java/common/Type.tpl index c869934538..c58e08a342 100644 --- a/java/common/Type.tpl +++ b/java/common/Type.tpl @@ -1,4 +1,4 @@ -package org.apache.qpidity.transport; +package org.apache.qpid.transport; ${from genutil import *} diff --git a/java/common/codegen b/java/common/codegen index ab1ab1c542..6cd51565ea 100755 --- a/java/common/codegen +++ b/java/common/codegen @@ -7,7 +7,7 @@ from genutil import * out_dir = sys.argv[1] spec_file = sys.argv[2] tpl_dir = sys.argv[3] -pkg_dir = os.path.join(out_dir, "org/apache/qpidity/transport") +pkg_dir = os.path.join(out_dir, "org/apache/qpid/transport") if not os.path.exists(pkg_dir): os.makedirs(pkg_dir) diff --git a/java/common/pom.xml b/java/common/pom.xml index 714087d843..894ca26710 100644 --- a/java/common/pom.xml +++ b/java/common/pom.xml @@ -61,7 +61,7 @@ diff --git a/java/common/src/main/java/log4j.properties b/java/common/src/main/java/log4j.properties index 0b3b96933e..44f89dc805 100644 --- a/java/common/src/main/java/log4j.properties +++ b/java/common/src/main/java/log4j.properties @@ -23,8 +23,6 @@ log4j.logger.qpid.protocol=${amqj.protocol.logging.level}, console log4j.additivity.qpid.protocol=false log4j.logger.org.apache.qpid=${amqj.logging.level}, console log4j.additivity.org.apache.qpid=false -log4j.logger.org.apache.qpidity=${amqj.logging.level}, console -log4j.additivity.org.apache.qpidity=false log4j.appender.console=org.apache.log4j.ConsoleAppender diff --git a/java/common/src/main/java/org/apache/qpid/BrokerDetails.java b/java/common/src/main/java/org/apache/qpid/BrokerDetails.java new file mode 100644 index 0000000000..63f67a7857 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/BrokerDetails.java @@ -0,0 +1,138 @@ +/* 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; + +import java.util.Map; + +/** + * This interface represents a broker and provides the basic information + * required for opening a connection with a broker. + */ +public interface BrokerDetails +{ + /** + * Those are the supported protocols + */ + public static final String PROTOCOL_TCP = "tcp"; + public static final String PROTOCOL_TLS = "tls"; + + public static final String VIRTUAL_HOST = "virtualhost"; + public static final String CLIENT_ID = "client_id"; + public static final String USERNAME = "username"; + public static final String PASSWORD = "password"; + + /** + * Get the broker host name. + * + * @return The broker host name. + */ + public String getHost(); + + /** + * Get the broker port number. + * + * @return The broker port number. + */ + public int getPort(); + + /** + * Get the virtual host to connect to. + * + * @return The virtual host of this broker. + */ + public String getVirtualHost(); + + /** + * Get the user name. + * + * @return The user name + */ + public String getUserName(); + + /** + * Get the user password + * + * @return The user password + */ + public String getPassword(); + + /** + * Get the protocol used to connect to hise broker. + * + * @return the protocol used to connect to the broker. + */ + public String getProtocol(); + + /** + * Set the broker host name. + * + * @param host The broker host name. + */ + public void setHost(String host); + + /** + * Set the broker port number. + * + * @param port The broker port number. + */ + public void setPort(int port); + + /** + * Set the virtual host to connect to. + * + * @param virtualHost The virtual host of this broker. + */ + public void setVirtualHost(String virtualHost); + + /** + * Set the user name. + * + * @param userName The user name + */ + public void setUserName(String userName); + + /** + * Set the user password + * + * @param password The user password + */ + public void setPassword(String password); + + /** + * Set the protocol used to connect to hise broker. + * + * @param protocol the protocol used to connect to the broker. + */ + public void setProtocol(String protocol); + + /** + * Ex: keystore path + * + * @return the Properties associated with this connection. + */ + public Map getProperties(); + + /** + * Sets the properties associated with this connection + * + * @param props the new p[roperties. + */ + public void setProperties(Map props); + + public void setProperty(String key,String value); +} diff --git a/java/common/src/main/java/org/apache/qpid/BrokerDetailsImpl.java b/java/common/src/main/java/org/apache/qpid/BrokerDetailsImpl.java new file mode 100644 index 0000000000..201d43e21f --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/BrokerDetailsImpl.java @@ -0,0 +1,264 @@ +/* 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; + +import java.util.HashMap; +import java.util.Map; + +/** + * Implements the interface BrokerDetails + */ +public class BrokerDetailsImpl implements BrokerDetails +{ + //--- Those are the default values + private final String DEFAULT_USERNAME = "guest"; + private final String DEFAULT_PASSWORD = "guest"; + private final String DEFAULT_VIRTUALHOST = ""; + + //---- The brker details + private String _host; + private int _port = 0; + private String _virtualHost; + private String _userName = DEFAULT_USERNAME; + private String _password = DEFAULT_PASSWORD; + private String _protocol; + private Map _props = new HashMap(); + ; + + //--- Constructors + + public BrokerDetailsImpl() + { + } + + /** + * Create a new broker details given all the reuqired information + * + * @param protocol The protocol used for this broker connection + * @param host The host name. + * @param port The port number. + * @param virtualHost The virtual host. + * @param userName The user name. + * @param password The user password. + */ + public BrokerDetailsImpl(String protocol, String host, int port, String virtualHost, String userName, + String password, Map props) + { + _protocol = protocol; + _host = host; + _port = port; + _virtualHost = virtualHost; + _userName = userName; + _password = password; + _props = props; + } + + /** + * Create a new broker details given the host name and the procol type, + * default values are used for the other details. + * + * @param protocol The protocol used for this broker connection + * @param host The host name. + */ + public BrokerDetailsImpl(String protocol, String host) + { + _protocol = protocol; + _host = host; + _virtualHost = DEFAULT_VIRTUALHOST; + _userName = DEFAULT_USERNAME; + _password = DEFAULT_PASSWORD; + } + + //--- API BrokerDetails + /** + * Get the user password + * + * @return The user password + */ + public String getPassword() + { + return _password; + } + + /** + * Get the broker host name. + * + * @return The broker host name. + */ + public String getHost() + { + return _host; + } + + /** + * Get the broker port number. + * + * @return The broker port number. + */ + public int getPort() + { + if (_port == 0) + { + if (getProtocol().equals(BrokerDetails.PROTOCOL_TCP)) + { + _port = 5672; + } + else if (getProtocol().equals(BrokerDetails.PROTOCOL_TLS)) + { + _port = 5555; + } + } + return _port; + } + + /** + * Get the virtual host to connect to. + * + * @return The virtual host of this broker. + */ + public String getVirtualHost() + { + return _virtualHost; + } + + /** + * Get the user name. + * + * @return The user name + */ + public String getUserName() + { + return _userName; + } + + /** + * Get the protocol used to connect to hise broker. + * + * @return the protocol used to connect to the broker. + */ + public String getProtocol() + { + return _protocol; + } + + /** + * Set the broker host name. + * + * @param host The broker host name. + */ + public void setHost(String host) + { + _host = host; + } + + /** + * Set the broker port number. + * + * @param port The broker port number. + */ + public void setPort(int port) + { + _port = port; + } + + /** + * Set the virtual host to connect to. + * + * @param virtualHost The virtual host of this broker. + */ + public void setVirtualHost(String virtualHost) + { + _virtualHost = virtualHost; + } + + /** + * Set the user name. + * + * @param userName The user name + */ + public void setUserName(String userName) + { + _userName = userName; + } + + /** + * Set the user password + * + * @param password The user password + */ + public void setPassword(String password) + { + _password = password; + } + + /** + * Set the protocol used to connect to hise broker. + * + * @param protocol the protocol used to connect to the broker. + */ + public void setProtocol(String protocol) + { + _protocol = protocol; + } + + /** + * Ex: keystore path + * + * @return the Properties associated with this connection. + */ + public Map getProperties() + { + return _props; + } + + /** + * Sets the properties associated with this connection + * + * @param props + */ + public void setProperties(Map props) + { + _props = props; + } + + public void setProperty(String key, String value) + { + _props.put(key, value); + } + + public String toString() + { + StringBuilder b = new StringBuilder(); + b.append("[username=" + _userName); + b.append(",password=" + _password); + b.append(",transport=" + _protocol); + b.append(",host=" + _host); + b.append(",port=" + getPort() + "]"); + b.append(" - Properties["); + if (_props != null) + { + for (String k : _props.keySet()) + { + b.append(k + "=" + _props.get(k) + ","); + } + } + b.append("]"); + + return b.toString(); + } +} diff --git a/java/common/src/main/java/org/apache/qpid/ConsoleOutput.java b/java/common/src/main/java/org/apache/qpid/ConsoleOutput.java new file mode 100644 index 0000000000..f17782ebf4 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/ConsoleOutput.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; + +import java.nio.ByteBuffer; + +import org.apache.qpid.transport.Sender; + +import static org.apache.qpid.transport.util.Functions.*; + + +/** + * ConsoleOutput + * + * @author Rafael H. Schloming + */ + +public class ConsoleOutput implements Sender +{ + + public void send(ByteBuffer buf) + { + System.out.println(str(buf)); + } + + public void flush() + { + // pass + } + + public void close() + { + System.out.println("CLOSED"); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/ErrorCode.java b/java/common/src/main/java/org/apache/qpid/ErrorCode.java new file mode 100644 index 0000000000..be1ad16dd5 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/ErrorCode.java @@ -0,0 +1,102 @@ +package org.apache.qpid; + +public enum ErrorCode +{ + //Qpid specific - for the time being + UNDEFINED(1,"undefined",true), + MESSAGE_REJECTED(2,"message_rejected",true), + CONNECTION_ERROR(3,"connection was closed",true), + UNSUPPORTED_PROTOCOL(4, "protocol version is unsupported", true), + + //This might change in the spec, the error class is not applicable + NO_ERROR(200,"reply-success",true), + + //From the spec + CONTENT_TOO_LARGE(311,"content-too-large",false), + NO_ROUTE(312,"no-route",false), + NO_CONSUMERS(313,"content-consumers",false), + CONNECTION_FORCED(320,"connection-forced",true), + INVALID_PATH(402,"invalid-path",true), + ACCESS_REFUSED(403,"access-refused",false), + NOT_FOUND(404,"not-found",false), + RESOURCE_LOCKED(405,"resource-locked",false), + PRE_CONDITION_FAILED(406,"precondition-failed",false), + + FRAME_ERROR(501,"frame_error",true), + SYNTAX_ERROR(502,"syntax_error",true), + COMMAND_INVALID(503,"command_invalid",true), + SESSION_ERROR(504,"sesion_error",true), + NOT_ALLOWED(530,"not_allowed",true), + NOT_IMPLEMENTED(540,"not_implemented",true), + INTERNAL_ERROR(541,"internal_error",true), + INVALID_ARGUMENT(542,"invalid_argument",true); + + private int _code; + private String _desc; + private boolean _hardError; + + private ErrorCode(int code,String desc,boolean hardError) + { + _code = code; + _desc= desc; + _hardError = hardError; + } + + public int getCode() + { + return _code; + } + + public String getDesc() + { + return _desc; + } + + private boolean isHardError() + { + return _hardError; + } + + public static ErrorCode get(int code) + { + switch(code) + { + case 200 : return NO_ERROR; + case 311 : return CONTENT_TOO_LARGE; + case 312 : return NO_ROUTE; + case 313 : return NO_CONSUMERS; + case 320 : return CONNECTION_FORCED; + case 402 : return INVALID_PATH; + case 403 : return ACCESS_REFUSED; + case 404 : return NOT_FOUND; + case 405 : return RESOURCE_LOCKED; + case 406 : return PRE_CONDITION_FAILED; + case 501 : return FRAME_ERROR; + case 502 : return SYNTAX_ERROR; + case 503 : return COMMAND_INVALID; + case 504 : return SESSION_ERROR; + case 530 : return NOT_ALLOWED; + case 540 : return NOT_IMPLEMENTED; + case 541 : return INTERNAL_ERROR; + case 542 : return INVALID_ARGUMENT; + + default : return UNDEFINED; + } + } + } + +/* + + + + The server could not complete the method because of an internal error. The server may require + intervention by an operator in order to resume normal operations. + + + + + + An invalid or illegal argument was passed to a method, and the operation could not proceed. + + +*/ \ No newline at end of file diff --git a/java/common/src/main/java/org/apache/qpid/QpidConfig.java b/java/common/src/main/java/org/apache/qpid/QpidConfig.java new file mode 100644 index 0000000000..e8d42fdf83 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/QpidConfig.java @@ -0,0 +1,90 @@ +package org.apache.qpid; + +/** + * API to configure the Security parameters of the client. + * The user can choose to pick the config from any source + * and set it using this class. + * + */ +public class QpidConfig +{ + private static QpidConfig _instance = new QpidConfig(); + + private SecurityMechanism[] securityMechanisms = + new SecurityMechanism[]{new SecurityMechanism("PLAIN","org.apache.qpid.security.UsernamePasswordCallbackHandler"), + new SecurityMechanism("CRAM_MD5","org.apache.qpid.security.UsernamePasswordCallbackHandler")}; + + private SaslClientFactory[] saslClientFactories = + new SaslClientFactory[]{new SaslClientFactory("AMQPLAIN","org.apache.qpid.security.amqplain.AmqPlainSaslClientFactory")}; + + private QpidConfig(){} + + public static QpidConfig get() + { + return _instance; + } + + public void setSecurityMechanisms(SecurityMechanism... securityMechanisms) + { + this.securityMechanisms = securityMechanisms; + } + + public SecurityMechanism[] getSecurityMechanisms() + { + return securityMechanisms; + } + + public void setSaslClientFactories(SaslClientFactory... saslClientFactories) + { + this.saslClientFactories = saslClientFactories; + } + + public SaslClientFactory[] getSaslClientFactories() + { + return saslClientFactories; + } + + public class SecurityMechanism + { + String type; + String handler; + + SecurityMechanism(String type,String handler) + { + this.type = type; + this.handler = handler; + } + + public String getHandler() + { + return handler; + } + + public String getType() + { + return type; + } + } + + public class SaslClientFactory + { + String type; + String factoryClass; + + SaslClientFactory(String type,String factoryClass) + { + this.type = type; + this.factoryClass = factoryClass; + } + + public String getFactoryClass() + { + return factoryClass; + } + + public String getType() + { + return type; + } + } +} diff --git a/java/common/src/main/java/org/apache/qpid/QpidException.java b/java/common/src/main/java/org/apache/qpid/QpidException.java new file mode 100644 index 0000000000..8503adaef8 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/QpidException.java @@ -0,0 +1,58 @@ +/* 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; + +public class QpidException extends Exception +{ + /** + * AMQP error code + */ + private ErrorCode _errorCode; + + /** + * Constructor for a Qpid Exception. + *

This is the only provided constructor and the parameters have to be set to null when + * they are unknown. + * @param message A description of the reason of this exception . + * @param errorCode A string specifyin the error code of this exception. + * @param cause The linked Execption. * + * + */ + public QpidException(String message, ErrorCode errorCode, Throwable cause) + { + super(message, cause); + _errorCode = errorCode; + } + + /*hack to get rid of a compile error from a generated class + public QpidException(String message, String errorCode, Throwable cause) + { + + }*/ + + /** + * Get this execption error code. + * + * @return This exception error code. + */ + public ErrorCode getErrorCode() + { + return _errorCode; + } +} + diff --git a/java/common/src/main/java/org/apache/qpid/SecurityHelper.java b/java/common/src/main/java/org/apache/qpid/SecurityHelper.java new file mode 100644 index 0000000000..dda5a6506d --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/SecurityHelper.java @@ -0,0 +1,71 @@ +/* + * + * 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; + +import java.io.UnsupportedEncodingException; +import java.util.HashSet; +import java.util.List; +import java.util.StringTokenizer; + +import org.apache.qpid.security.AMQPCallbackHandler; +import org.apache.qpid.security.CallbackHandlerRegistry; + +public class SecurityHelper +{ + public static String chooseMechanism(List mechanisms) throws UnsupportedEncodingException + { + HashSet mechanismSet = new HashSet(); + for (Object m : mechanisms) + { + mechanismSet.add(m); + } + + String preferredMechanisms = CallbackHandlerRegistry.getInstance().getMechanisms(); + StringTokenizer prefTokenizer = new StringTokenizer(preferredMechanisms, " "); + while (prefTokenizer.hasMoreTokens()) + { + String mech = prefTokenizer.nextToken(); + if (mechanismSet.contains(mech)) + { + return mech; + } + } + return null; + } + + public static AMQPCallbackHandler createCallbackHandler(String mechanism, String username,String password) + throws QpidException + { + Class mechanismClass = CallbackHandlerRegistry.getInstance().getCallbackHandlerClass(mechanism); + try + { + Object instance = mechanismClass.newInstance(); + AMQPCallbackHandler cbh = (AMQPCallbackHandler) instance; + cbh.initialise(username,password); + return cbh; + } + catch (Exception e) + { + throw new QpidException("Unable to create callback handler: " + e,ErrorCode.UNDEFINED, e.getCause()); + } + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/ToyBroker.java b/java/common/src/main/java/org/apache/qpid/ToyBroker.java new file mode 100644 index 0000000000..56286a9b01 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/ToyBroker.java @@ -0,0 +1,286 @@ +/* + * + * 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; + +import org.apache.qpid.transport.*; +import org.apache.qpid.transport.network.mina.MinaHandler; + +import static org.apache.qpid.transport.util.Functions.str; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.LinkedBlockingQueue; + + +/** + * ToyBroker + * + * @author Rafael H. Schloming + */ + +class ToyBroker extends SessionDelegate +{ + + private ToyExchange exchange; + private MessageTransfer xfr = null; + private DeliveryProperties props = null; + private Header header = null; + private List body = null; + private Map consumers = new ConcurrentHashMap(); + + public ToyBroker(ToyExchange exchange) + { + this.exchange = exchange; + } + + public void messageAcquire(Session context, MessageAcquire struct) + { + System.out.println("\n==================> messageAcquire " ); + context.executionResult((int) struct.getId(), new Acquired(struct.getTransfers())); + } + + @Override public void queueDeclare(Session ssn, QueueDeclare qd) + { + exchange.createQueue(qd.getQueue()); + System.out.println("\n==================> declared queue: " + qd.getQueue() + "\n"); + } + + @Override public void exchangeBind(Session ssn, ExchangeBind qb) + { + exchange.bindQueue(qb.getExchange(), qb.getBindingKey(),qb.getQueue()); + System.out.println("\n==================> bound queue: " + qb.getQueue() + " with binding key " + qb.getBindingKey() + "\n"); + } + + @Override public void queueQuery(Session ssn, QueueQuery qq) + { + QueueQueryResult result = new QueueQueryResult().queue(qq.getQueue()); + ssn.executionResult((int) qq.getId(), result); + } + + @Override public void messageSubscribe(Session ssn, MessageSubscribe ms) + { + Consumer c = new Consumer(); + c._queueName = ms.getQueue(); + consumers.put(ms.getDestination(),c); + System.out.println("\n==================> message subscribe : " + ms.getDestination() + " queue: " + ms.getQueue() + "\n"); + } + + @Override public void messageFlow(Session ssn,MessageFlow struct) + { + Consumer c = consumers.get(struct.getDestination()); + c._credit = struct.getValue(); + System.out.println("\n==================> message flow : " + struct.getDestination() + " credit: " + struct.getValue() + "\n"); + } + + @Override public void messageFlush(Session ssn,MessageFlush struct) + { + System.out.println("\n==================> message flush for consumer : " + struct.getDestination() + "\n"); + checkAndSendMessagesToConsumer(ssn,struct.getDestination()); + } + + @Override public void messageTransfer(Session ssn, MessageTransfer xfr) + { + this.xfr = xfr; + body = new ArrayList(); + System.out.println("received transfer " + xfr.getDestination()); + } + + @Override public void header(Session ssn, Header header) + { + if (xfr == null || body == null) + { + ssn.connectionClose(ConnectionCloseCode.FRAMING_ERROR, + "no method segment"); + ssn.close(); + return; + } + + props = header.get(DeliveryProperties.class); + if (props != null) + { + System.out.println("received headers routing_key " + props.getRoutingKey()); + } + MessageProperties mp = header.get(MessageProperties.class); + System.out.println("MP: " + mp); + if (mp != null) + { + System.out.println(mp.getApplicationHeaders()); + } + + this.header = header; + } + + @Override public void data(Session ssn, Data data) + { + if (xfr == null || body == null) + { + ssn.connectionClose(ConnectionCloseCode.FRAMING_ERROR, "no method segment"); + ssn.close(); + return; + } + + body.add(data); + + if (data.isLast()) + { + String dest = xfr.getDestination(); + Message m = new Message(header, body); + + if (exchange.route(dest,props.getRoutingKey(),m)) + { + System.out.println("queued " + m); + dispatchMessages(ssn); + } + else + { + + reject(ssn); + } + ssn.processed(xfr); + xfr = null; + body = null; + } + } + + private void reject(Session ssn) + { + if (props != null && props.getDiscardUnroutable()) + { + return; + } + else + { + RangeSet ranges = new RangeSet(); + ranges.add(xfr.getId()); + ssn.messageReject(ranges, MessageRejectCode.UNROUTABLE, + "no such destination"); + } + } + + private void transferMessageToPeer(Session ssn,String dest, Message m) + { + System.out.println("\n==================> Transfering message to: " +dest + "\n"); + ssn.messageTransfer(dest, MessageAcceptMode.EXPLICIT, + MessageAcquireMode.PRE_ACQUIRED); + ssn.header(m.header); + for (Data d : m.body) + { + ssn.data(d.getData()); + } + ssn.endData(); + } + + private void dispatchMessages(Session ssn) + { + for (String dest: consumers.keySet()) + { + checkAndSendMessagesToConsumer(ssn,dest); + } + } + + private void checkAndSendMessagesToConsumer(Session ssn,String dest) + { + Consumer c = consumers.get(dest); + LinkedBlockingQueue queue = exchange.getQueue(c._queueName); + Message m = queue.poll(); + while (m != null && c._credit>0) + { + transferMessageToPeer(ssn,dest,m); + c._credit--; + m = queue.poll(); + } + } + + class Message + { + private final Header header; + private final List body; + + public Message(Header header, List body) + { + this.header = header; + this.body = body; + } + + public String toString() + { + StringBuilder sb = new StringBuilder(); + + if (header != null) + { + boolean first = true; + for (Struct st : header.getStructs()) + { + if (first) { first = false; } + else { sb.append(" "); } + sb.append(st); + } + } + + for (Data d : body) + { + sb.append(" | "); + sb.append(d); + } + + return sb.toString(); + } + + } + + // ugly, but who cares :) + // assumes unit is always no of messages, not bytes + // assumes it's credit mode and not window + private class Consumer + { + long _credit; + String _queueName; + } + + public static final void main(String[] args) throws IOException + { + final ToyExchange exchange = new ToyExchange(); + ConnectionDelegate delegate = new ConnectionDelegate() + { + public SessionDelegate getSessionDelegate() + { + return new ToyBroker(exchange); + } + public void exception(Throwable t) + { + t.printStackTrace(); + } + public void closed() {} + }; + + //hack + delegate.setUsername("guest"); + delegate.setPassword("guest"); + + MinaHandler.accept("0.0.0.0", 5672, delegate); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/ToyClient.java b/java/common/src/main/java/org/apache/qpid/ToyClient.java new file mode 100644 index 0000000000..27a48fb760 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/ToyClient.java @@ -0,0 +1,133 @@ +/* + * + * 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; + +import java.util.*; + +import org.apache.qpid.transport.*; +import org.apache.qpid.transport.network.mina.MinaHandler; + + +/** + * ToyClient + * + * @author Rafael H. Schloming + */ + +class ToyClient extends SessionDelegate +{ + + @Override public void messageReject(Session ssn, MessageReject reject) + { + for (Range range : reject.getTransfers()) + { + for (long l = range.getLower(); l <= range.getUpper(); l++) + { + System.out.println("message rejected: " + + ssn.getCommand((int) l)); + } + } + } + + @Override public void header(Session ssn, Header header) + { + for (Struct st : header.getStructs()) + { + System.out.println("header: " + st); + } + } + + @Override public void data(Session ssn, Data data) + { + System.out.println("got data: " + data); + } + + public static final void main(String[] args) + { + Connection conn = MinaHandler.connect("0.0.0.0", 5672, + new ClientDelegate() + { + public SessionDelegate getSessionDelegate() + { + return new ToyClient(); + } + public void exception(Throwable t) + { + t.printStackTrace(); + } + public void closed() {} + }); + conn.send(new ProtocolHeader + (1, 0, 10)); + + Channel ch = conn.getChannel(0); + Session ssn = new Session("my-session".getBytes()); + ssn.attach(ch); + ssn.sessionAttach(ssn.getName()); + + ssn.queueDeclare("asdf", null, null); + ssn.sync(); + + Map nested = new LinkedHashMap(); + nested.put("list", Arrays.asList("one", "two", "three")); + Map map = new LinkedHashMap(); + + map.put("str", "this is a string"); + + map.put("+int", 3); + map.put("-int", -3); + map.put("maxint", Integer.MAX_VALUE); + map.put("minint", Integer.MIN_VALUE); + + map.put("+short", (short) 1); + map.put("-short", (short) -1); + map.put("maxshort", (short) Short.MAX_VALUE); + map.put("minshort", (short) Short.MIN_VALUE); + + map.put("float", (float) 3.3); + map.put("double", 4.9); + map.put("char", 'c'); + + map.put("table", nested); + map.put("list", Arrays.asList(1, 2, 3)); + map.put("binary", new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); + + ssn.messageTransfer("asdf", MessageAcceptMode.EXPLICIT, + MessageAcquireMode.PRE_ACQUIRED); + ssn.header(new DeliveryProperties(), + new MessageProperties().setApplicationHeaders(map)); + ssn.data("this is the data"); + ssn.endData(); + + ssn.messageTransfer("fdsa", MessageAcceptMode.EXPLICIT, + MessageAcquireMode.PRE_ACQUIRED); + ssn.data("this should be rejected"); + ssn.endData(); + ssn.sync(); + + Future future = ssn.queueQuery("asdf"); + System.out.println(future.get().getQueue()); + ssn.sync(); + ssn.close(); + conn.close(); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/ToyExchange.java b/java/common/src/main/java/org/apache/qpid/ToyExchange.java new file mode 100644 index 0000000000..5c3c0ac0fb --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/ToyExchange.java @@ -0,0 +1,132 @@ +package org.apache.qpid; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.qpid.ToyBroker.Message; + +public class ToyExchange +{ + final static String DIRECT = "amq.direct"; + final static String TOPIC = "amq.topic"; + + private Map>> directEx = new HashMap>>(); + private Map>> topicEx = new HashMap>>(); + private Map> queues = new HashMap>(); + + public void createQueue(String name) + { + queues.put(name, new LinkedBlockingQueue()); + } + + public LinkedBlockingQueue getQueue(String name) + { + return queues.get(name); + } + + public void bindQueue(String type,String binding,String queueName) + { + LinkedBlockingQueue queue = queues.get(queueName); + binding = normalizeKey(binding); + if(DIRECT.equals(type)) + { + + if (directEx.containsKey(binding)) + { + List> list = directEx.get(binding); + list.add(queue); + } + else + { + List> list = new LinkedList>(); + list.add(queue); + directEx.put(binding,list); + } + } + else + { + if (topicEx.containsKey(binding)) + { + List> list = topicEx.get(binding); + list.add(queue); + } + else + { + List> list = new LinkedList>(); + list.add(queue); + topicEx.put(binding,list); + } + } + } + + public boolean route(String dest,String routingKey,Message msg) + { + List> queues; + if(DIRECT.equals(dest)) + { + queues = directEx.get(routingKey); + } + else + { + queues = matchWildCard(routingKey); + } + if(queues != null && queues.size()>0) + { + System.out.println("Message stored in " + queues.size() + " queues"); + storeMessage(msg,queues); + return true; + } + else + { + System.out.println("Message unroutable " + msg); + return false; + } + } + + private String normalizeKey(String routingKey) + { + if(routingKey.indexOf(".*")>1) + { + return routingKey.substring(0,routingKey.indexOf(".*")); + } + else + { + return routingKey; + } + } + + private List> matchWildCard(String routingKey) + { + List> selected = new ArrayList>(); + + for(String key: topicEx.keySet()) + { + Pattern p = Pattern.compile(key); + Matcher m = p.matcher(routingKey); + if (m.find()) + { + for(LinkedBlockingQueue queue : topicEx.get(key)) + { + selected.add(queue); + } + } + } + + return selected; + } + + private void storeMessage(Message msg,List> selected) + { + for(LinkedBlockingQueue queue : selected) + { + queue.offer(msg); + } + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/api/Message.java b/java/common/src/main/java/org/apache/qpid/api/Message.java new file mode 100644 index 0000000000..df6f279026 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/api/Message.java @@ -0,0 +1,126 @@ +package org.apache.qpid.api; + +import java.io.IOException; +import java.nio.ByteBuffer; + +import org.apache.qpid.transport.MessageProperties; +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.Header; + +/* + * 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. + */ + +public interface Message +{ + public Header getHeader(); + + public void setHeader(Header header); + + public MessageProperties getMessageProperties(); + + public DeliveryProperties getDeliveryProperties(); + + /** + * This will abstract the underlying message data. + * The Message implementation may not hold all message + * data in memory (especially in the case of large messages) + * + * The appendData function might write data to + *
    + *
  • Memory (Ex: ByteBuffer) + *
  • To Disk + *
  • To Socket (Stream) + *
+ * @param src - the data to append + */ + public void appendData(byte[] src) throws IOException; + + + /** + * This will abstract the underlying message data. + * The Message implementation may not hold all message + * data in memory (especially in the case of large messages) + * + * The appendData function might write data to + *
    + *
  • Memory (Ex: ByteBuffer) + *
  • To Disk + *
  • To Socket (Stream) + *
+ * @param src - the data to append + */ + public void appendData(ByteBuffer src) throws IOException; + + /** + * This will abstract the underlying message data. + * The Message implementation may not hold all message + * data in memory (especially in the case of large messages) + * + * The read function might copy data from + *
    + *
  • From memory (Ex: ByteBuffer) + *
  • From Disk + *
  • From Socket as and when it gets streamed + *
+ * @param target The target byte[] which the data gets copied to + */ + public void readData(byte[] target) throws IOException; + + /** + * * This will abstract the underlying message data. + * The Message implementation may not hold all message + * data in memory (especially in the case of large messages) + * + * The read function might copy data from + *
    + *
  • From memory (Ex: ByteBuffer) + *
  • From Disk + *
  • From Socket as and when it gets streamed + *
+ * + * @return A ByteBuffer containing data + * @throws IOException + */ + public ByteBuffer readData() throws IOException; + + /** + * This should clear the body of the message. + */ + public void clearData(); + + /** + * The provides access to the command Id assigned to the + * message transfer. + * This id is useful when you do + *
    + *
  • For message acquiring - If the transfer happend in no-acquire mode + * you could use this id to accquire it. + *
  • For releasing a message. You can use this id to release an acquired + * message + *
  • For Acknowledging a message - You need to pass this ID, in order to + * acknowledge the message + *
  • For Rejecting a message - You need to pass this ID, in order to reject + * the message. + *
+ * + * @return the message transfer id. + */ + public int getMessageTransferId(); + +} diff --git a/java/common/src/main/java/org/apache/qpid/dtx/XidImpl.java b/java/common/src/main/java/org/apache/qpid/dtx/XidImpl.java new file mode 100644 index 0000000000..49effc2dae --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/dtx/XidImpl.java @@ -0,0 +1,250 @@ +/* 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.dtx; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.apache.qpid.QpidException; + +import javax.transaction.xa.Xid; + +import java.io.*; + +/** + * Implements javax.transaction.dtx.Xid + */ +public class XidImpl implements Xid +{ + /** + * this session's logger + */ + private static final Logger _logger = LoggerFactory.getLogger(XidImpl.class); + + /** + * the transaction branch identifier part of XID as an array of bytes + */ + private byte[] _branchQualifier; + + /** + * the format identifier part of the XID. + */ + private int _formatID; + + /** + * the global transaction identifier part of XID as an array of bytes. + */ + private byte[] _globalTransactionID; + + //--- Constructors + + /** + * Create new Xid. + * this is an empty constructor. + */ + public XidImpl() + { + + } + + /** + * Create a new XidImpl from an existing Xid. + *

Usefull for casting external Xids + * + * @param xid Foreign Xid. + */ + public XidImpl(Xid xid) + { + _branchQualifier = xid.getBranchQualifier(); + _formatID = xid.getFormatId(); + _globalTransactionID = xid.getGlobalTransactionId(); + } + + /** + * Create a new Xid. + * + * @param branchQualifier The transaction branch identifier part of XID as an array of bytes. + * @param format The format identifier part of the XID. + * @param globalTransactionID The global transaction identifier part of XID as an array of bytes. + */ + public XidImpl(byte[] branchQualifier, int format, byte[] globalTransactionID) + { + _branchQualifier = branchQualifier; + _formatID = format; + _globalTransactionID = globalTransactionID; + } + + /** + * Create a new Xid form its String form + * 4 1 1 g b + * +---+---+---+---+---+---+---+- -+---+---+- -+---+ + * | format_id | g | b | txn-id | br-id | + * +---+---+---+---+---+---+---+- -+---+---+- -+---+ + * 0 4 5 6 6+g 6+g+b + * format_id: an implementation specific format identifier + *

+ * gtrid_length: how many bytes of this form the transaction id + *

+ * bqual_length: how many bytes of this form the branch id + *

+ * data: a sequence of octets of at most 128 bytes containing the txn id and the + * branch id + *

+ * Note - The sum of the two lengths must equal the length of the data field. + * + * @param xid an XID STring Form + * @throws QpidException If the string does not represent a valid Xid + */ + public XidImpl(String xid) throws QpidException + { + if (_logger.isDebugEnabled()) + { + _logger.debug("converting string " + xid + " into XidImpl"); + } + try + { + DataInputStream input = new DataInputStream(new ByteArrayInputStream(xid.getBytes())); + _formatID = (int) input.readLong(); + int g = input.readByte(); + int b = input.readByte(); + _globalTransactionID = new byte[g]; + _branchQualifier = new byte[b]; + if (input.read(_globalTransactionID, 0, g) != g) + { + throw new QpidException("Cannot convert the string " + xid + " into an Xid", null, null); + } + if (input.read(_branchQualifier, 0, b) != b) + { + throw new QpidException("Cannot convert the string " + xid + " into an Xid", null, null); + } + } + catch (IOException e) + { + throw new QpidException("cannot convert the string " + xid + " into an Xid", null, e); + } + } + + //--- Xid interface implementation + + /** + * Format identifier. O means the OSI CCR format. + * + * @return Global transaction identifier. + */ + public byte[] getGlobalTransactionId() + { + return _globalTransactionID; + } + + /** + * Obtain the transaction branch identifier part of XID as an array of bytes. + * + * @return Branch identifier part of XID. + */ + public byte[] getBranchQualifier() + { + return _branchQualifier; + } + + /** + * Obtain the format identifier part of the XID. + * + * @return Format identifier. O means the OSI CCR format. + */ + public int getFormatId() + { + return _formatID; + } + + //--- Object operations + + /** + * Indicates whether some other Xid is "equal to" this one. + *

Two Xids are equal if and only if their three elementary parts are equal + * + * @param o the object to compare this XidImpl against. + * @return true if the XidImpl are equal, false otherwise. + */ + public boolean equals(Object o) + { + if (this == o) + { + return true; + } + if (o instanceof XidImpl) + { + XidImpl other = (XidImpl) o; + if (_formatID == other.getFormatId()) + { + if (_branchQualifier.length == other.getBranchQualifier().length) + { + for (int i = 0; i < _branchQualifier.length; i++) + { + if (_branchQualifier[i] != other.getBranchQualifier()[i]) + { + return false; + } + } + if (_globalTransactionID.length == other.getGlobalTransactionId().length) + { + for (int i = 0; i < _globalTransactionID.length; i++) + { + if (_globalTransactionID[i] != other.getGlobalTransactionId()[i]) + { + return false; + } + } + // everithing is equal + return true; + } + } + } + } + return false; + } + + //-- Static helper method + /** + * Convert an Xid into the AMQP String format. + * + * 4 1 1 g b + * +---+---+---+---+---+---+---+- -+---+---+- -+---+ + * | format_id | g | b | txn-id | br-id | + * +---+---+---+---+---+---+---+- -+---+---+- -+---+ + * 0 4 5 6 6+g 6+g+b + * format_id: an implementation specific format identifier + *

+ * gtrid_length: how many bytes of this form the transaction id + *

+ * bqual_length: how many bytes of this form the branch id + *

+ * data: a sequence of octets of at most 128 bytes containing the txn id and the + * branch id + *

+ * Note - The sum of the two lengths must equal the length of the data field. + * + * @param xid an Xid to convert. + * @return The String representation of this Xid + * @throws QpidException In case of problem when converting this Xid into a string. + */ + public static org.apache.qpid.transport.Xid convert(Xid xid) throws QpidException + { + return new org.apache.qpid.transport.Xid(xid.getFormatId(), + xid.getGlobalTransactionId(), + xid.getBranchQualifier()); + } +} diff --git a/java/common/src/main/java/org/apache/qpid/security/AMQPCallbackHandler.java b/java/common/src/main/java/org/apache/qpid/security/AMQPCallbackHandler.java new file mode 100644 index 0000000000..a3dad9acdc --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/security/AMQPCallbackHandler.java @@ -0,0 +1,28 @@ +/* + * + * 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.security; + +import javax.security.auth.callback.CallbackHandler; + +public interface AMQPCallbackHandler extends CallbackHandler +{ + void initialise(String username,String password); +} diff --git a/java/common/src/main/java/org/apache/qpid/security/CallbackHandlerRegistry.java b/java/common/src/main/java/org/apache/qpid/security/CallbackHandlerRegistry.java new file mode 100644 index 0000000000..8c80a1b5b7 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/security/CallbackHandlerRegistry.java @@ -0,0 +1,94 @@ +/* + * + * 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.security; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.qpid.QpidConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CallbackHandlerRegistry +{ + private static final Logger _logger = LoggerFactory.getLogger(CallbackHandlerRegistry.class); + private static CallbackHandlerRegistry _instance = new CallbackHandlerRegistry(); + + private Map _mechanismToHandlerClassMap = new HashMap(); + + private StringBuilder _mechanisms; + + public static CallbackHandlerRegistry getInstance() + { + return _instance; + } + + public Class getCallbackHandlerClass(String mechanism) + { + return _mechanismToHandlerClassMap.get(mechanism); + } + + public String getMechanisms() + { + return _mechanisms.toString(); + } + + private CallbackHandlerRegistry() + { + // first we register any Sasl client factories + DynamicSaslRegistrar.registerSaslProviders(); + registerMechanisms(); + } + + private void registerMechanisms() + { + for (QpidConfig.SecurityMechanism securityMechanism: QpidConfig.get().getSecurityMechanisms() ) + { + Class clazz = null; + try + { + clazz = Class.forName(securityMechanism.getHandler()); + if (!AMQPCallbackHandler.class.isAssignableFrom(clazz)) + { + _logger.debug("SASL provider " + clazz + " does not implement " + AMQPCallbackHandler.class + + ". Skipping"); + continue; + } + _mechanismToHandlerClassMap.put(securityMechanism.getType(), clazz); + if (_mechanisms == null) + { + + _mechanisms = new StringBuilder(); + _mechanisms.append(securityMechanism.getType()); + } + else + { + _mechanisms.append(" " + securityMechanism.getType()); + } + } + catch (ClassNotFoundException ex) + { + _logger.debug("Unable to load class " + securityMechanism.getHandler() + ". Skipping that SASL provider"); + continue; + } + } + } +} diff --git a/java/common/src/main/java/org/apache/qpid/security/DynamicSaslRegistrar.java b/java/common/src/main/java/org/apache/qpid/security/DynamicSaslRegistrar.java new file mode 100644 index 0000000000..9f48ac96a3 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/security/DynamicSaslRegistrar.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.security; + +import java.security.Security; +import java.util.Map; +import java.util.TreeMap; + +import javax.security.sasl.SaslClientFactory; + +import org.apache.qpid.QpidConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DynamicSaslRegistrar +{ + private static final Logger _logger = LoggerFactory.getLogger(DynamicSaslRegistrar.class); + + public static void registerSaslProviders() + { + Map factories = registerSaslClientFactories(); + if (factories.size() > 0) + { + Security.addProvider(new JCAProvider(factories)); + _logger.debug("Dynamic SASL provider added as a security provider"); + } + } + + private static Map registerSaslClientFactories() + { + TreeMap factoriesToRegister = + new TreeMap(); + + for (QpidConfig.SaslClientFactory factory: QpidConfig.get().getSaslClientFactories()) + { + String className = factory.getFactoryClass(); + try + { + Class clazz = Class.forName(className); + if (!(SaslClientFactory.class.isAssignableFrom(clazz))) + { + _logger.debug("Class " + clazz + " does not implement " + SaslClientFactory.class + " - skipping"); + continue; + } + factoriesToRegister.put(factory.getType(), clazz); + } + catch (Exception ex) + { + _logger.debug("Error instantiating SaslClientFactory calss " + className + " - skipping"); + } + } + return factoriesToRegister; + } + + +} diff --git a/java/common/src/main/java/org/apache/qpid/security/JCAProvider.java b/java/common/src/main/java/org/apache/qpid/security/JCAProvider.java new file mode 100644 index 0000000000..033deb550c --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/security/JCAProvider.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.security; + +import java.security.Provider; +import java.security.Security; +import java.util.Map; + +public class JCAProvider extends Provider +{ + public JCAProvider(Map providerMap) + { + super("AMQSASLProvider", 1.0, "A JCA provider that registers all " + + "AMQ SASL providers that want to be registered"); + register(providerMap); + Security.addProvider(this); + } + + private void register(Map providerMap) + { + for (Map.Entry me :providerMap.entrySet()) + { + put("SaslClientFactory." + me.getKey(), me.getValue().getName()); + } + } +} \ No newline at end of file diff --git a/java/common/src/main/java/org/apache/qpid/security/UsernamePasswordCallbackHandler.java b/java/common/src/main/java/org/apache/qpid/security/UsernamePasswordCallbackHandler.java new file mode 100644 index 0000000000..89a63abeab --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/security/UsernamePasswordCallbackHandler.java @@ -0,0 +1,60 @@ +/* + * + * 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.security; + +import java.io.IOException; + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; + +public class UsernamePasswordCallbackHandler implements AMQPCallbackHandler +{ + private String _username; + private String _password; + + public void initialise(String username,String password) + { + _username = username; + _password = password; + } + + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException + { + for (int i = 0; i < callbacks.length; i++) + { + Callback cb = callbacks[i]; + if (cb instanceof NameCallback) + { + ((NameCallback)cb).setName(_username); + } + else if (cb instanceof PasswordCallback) + { + ((PasswordCallback)cb).setPassword((_password).toCharArray()); + } + else + { + throw new UnsupportedCallbackException(cb); + } + } + } +} diff --git a/java/common/src/main/java/org/apache/qpid/security/amqplain/AmqPlainSaslClient.java b/java/common/src/main/java/org/apache/qpid/security/amqplain/AmqPlainSaslClient.java new file mode 100644 index 0000000000..81acc66de4 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/security/amqplain/AmqPlainSaslClient.java @@ -0,0 +1,105 @@ +/* + * + * 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.security.amqplain; + +import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.framing.FieldTableFactory; + +import javax.security.sasl.SaslClient; +import javax.security.sasl.SaslException; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.Callback; + +/** + * Implements the "AMQPlain" authentication protocol that uses FieldTables to send username and pwd. + * + */ +public class AmqPlainSaslClient implements SaslClient +{ + /** + * The name of this mechanism + */ + public static final String MECHANISM = "AMQPLAIN"; + + private CallbackHandler _cbh; + + public AmqPlainSaslClient(CallbackHandler cbh) + { + _cbh = cbh; + } + + public String getMechanismName() + { + return "AMQPLAIN"; + } + + public boolean hasInitialResponse() + { + return true; + } + + public byte[] evaluateChallenge(byte[] challenge) throws SaslException + { + // we do not care about the prompt or the default name + NameCallback nameCallback = new NameCallback("prompt", "defaultName"); + PasswordCallback pwdCallback = new PasswordCallback("prompt", false); + Callback[] callbacks = new Callback[]{nameCallback, pwdCallback}; + try + { + _cbh.handle(callbacks); + } + catch (Exception e) + { + throw new SaslException("Error handling SASL callbacks: " + e, e); + } + FieldTable table = FieldTableFactory.newFieldTable(); + table.setString("LOGIN", nameCallback.getName()); + table.setString("PASSWORD", new String(pwdCallback.getPassword())); + return table.getDataAsBytes(); + } + + public boolean isComplete() + { + return true; + } + + public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException + { + throw new SaslException("Not supported"); + } + + public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException + { + throw new SaslException("Not supported"); + } + + public Object getNegotiatedProperty(String propName) + { + return null; + } + + public void dispose() throws SaslException + { + _cbh = null; + } +} diff --git a/java/common/src/main/java/org/apache/qpid/security/amqplain/AmqPlainSaslClientFactory.java b/java/common/src/main/java/org/apache/qpid/security/amqplain/AmqPlainSaslClientFactory.java new file mode 100644 index 0000000000..6c66c87f4c --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/security/amqplain/AmqPlainSaslClientFactory.java @@ -0,0 +1,62 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.security.amqplain; + +import javax.security.sasl.SaslClientFactory; +import javax.security.sasl.SaslClient; +import javax.security.sasl.SaslException; +import javax.security.sasl.Sasl; +import javax.security.auth.callback.CallbackHandler; +import java.util.Map; + +public class AmqPlainSaslClientFactory implements SaslClientFactory +{ + public SaslClient createSaslClient(String[] mechanisms, String authorizationId, String protocol, String serverName, Map props, CallbackHandler cbh) throws SaslException + { + for (int i = 0; i < mechanisms.length; i++) + { + if (mechanisms[i].equals(AmqPlainSaslClient.MECHANISM)) + { + if (cbh == null) + { + throw new SaslException("CallbackHandler must not be null"); + } + return new AmqPlainSaslClient(cbh); + } + } + return null; + } + + public String[] getMechanismNames(Map props) + { + if (props.containsKey(Sasl.POLICY_NOPLAINTEXT) || + props.containsKey(Sasl.POLICY_NODICTIONARY) || + props.containsKey(Sasl.POLICY_NOACTIVE)) + { + // returned array must be non null according to interface documentation + return new String[0]; + } + else + { + return new String[]{AmqPlainSaslClient.MECHANISM}; + } + } +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/Binary.java b/java/common/src/main/java/org/apache/qpid/transport/Binary.java new file mode 100644 index 0000000000..e6dedc536f --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/Binary.java @@ -0,0 +1,129 @@ +/* + * + * 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.transport; + + +/** + * Binary + * + */ + +public final class Binary +{ + + private byte[] bytes; + private int offset; + private int size; + private int hash = 0; + + public Binary(byte[] bytes, int offset, int size) + { + if (offset + size > bytes.length) + { + throw new ArrayIndexOutOfBoundsException(); + } + + this.bytes = bytes; + this.offset = offset; + this.size = size; + } + + public Binary(byte[] bytes) + { + this(bytes, 0, bytes.length); + } + + public final byte[] array() + { + return bytes; + } + + public final int offset() + { + return offset; + } + + public final int size() + { + return size; + } + + public final Binary slice(int low, int high) + { + int sz; + + if (high < 0) + { + sz = size + high; + } + else + { + sz = high - low; + } + + if (sz < 0) + { + sz = 0; + } + + return new Binary(bytes, offset + low, sz); + } + + public final int hashCode() + { + if (hash == 0) + { + int hc = 0; + for (int i = 0; i < size; i++) + { + hc = 31*hc + (0xFF & bytes[offset + i]); + } + hash = hc; + } + + return hash; + } + + public final boolean equals(Object o) + { + if (!(o instanceof Binary)) + { + return false; + } + + Binary buf = (Binary) o; + if (this.size != buf.size) + { + return false; + } + + for (int i = 0; i < size; i++) + { + if (bytes[offset + i] != buf.bytes[buf.offset + i]) + { + return false; + } + } + + return true; + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/Binding.java b/java/common/src/main/java/org/apache/qpid/transport/Binding.java new file mode 100644 index 0000000000..8418c42189 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/Binding.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.transport; + + +/** + * Binding + * + */ + +public interface Binding +{ + + E endpoint(Sender sender); + + Receiver receiver(E endpoint); + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/Channel.java b/java/common/src/main/java/org/apache/qpid/transport/Channel.java new file mode 100644 index 0000000000..7a967adbba --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/Channel.java @@ -0,0 +1,233 @@ +/* + * + * 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.transport; + +import org.apache.qpid.transport.network.Frame; +import org.apache.qpid.transport.util.Logger; + +import java.nio.ByteBuffer; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import static org.apache.qpid.transport.network.Frame.*; +import static org.apache.qpid.transport.util.Functions.*; + + +/** + * Channel + * + * @author Rafael H. Schloming + */ + +public class Channel extends Invoker + implements Receiver, ProtocolDelegate +{ + + private static final Logger log = Logger.get(Channel.class); + + final private Connection connection; + final private int channel; + final private MethodDelegate delegate; + final private SessionDelegate sessionDelegate; + // session may be null + private Session session; + + private Lock commandLock = new ReentrantLock(); + private boolean first = true; + private ByteBuffer data = null; + private boolean batch = false; + + public Channel(Connection connection, int channel, SessionDelegate delegate) + { + this.connection = connection; + this.channel = channel; + this.delegate = new ChannelDelegate(); + this.sessionDelegate = delegate; + } + + public Connection getConnection() + { + return connection; + } + + public void received(ProtocolEvent event) + { + event.delegate(null, this); + } + + public void init(Void v, ProtocolHeader hdr) + { + connection.getConnectionDelegate().init(this, hdr); + } + + public void control(Void v, Method method) + { + switch (method.getEncodedTrack()) + { + case L1: + method.dispatch(this, connection.getConnectionDelegate()); + break; + case L2: + method.dispatch(this, delegate); + break; + case L3: + method.delegate(session, sessionDelegate); + break; + default: + throw new IllegalStateException + ("unknown track: " + method.getEncodedTrack()); + } + } + + public void command(Void v, Method method) + { + method.delegate(session, sessionDelegate); + } + + public void header(Void v, Header header) + { + header.delegate(session, sessionDelegate); + } + + public void data(Void v, Data data) + { + data.delegate(session, sessionDelegate); + } + + public void error(Void v, ProtocolError error) + { + throw new RuntimeException(error.getMessage()); + } + + public void exception(Throwable t) + { + session.exception(t); + } + + public void closed() + { + log.debug("channel closed: ", this); + if (session != null) + { + session.closed(); + } + connection.removeChannel(channel); + } + + public int getEncodedChannel() { + return channel; + } + + public Session getSession() + { + return session; + } + + void setSession(Session session) + { + this.session = session; + } + + private void emit(ProtocolEvent event) + { + event.setChannel(channel); + connection.send(event); + } + + public void method(Method m) + { + if (m.getEncodedTrack() == Frame.L4) + { + commandLock.lock(); + } + + emit(m); + + if (!m.isBatch() && !m.hasPayload()) + { + connection.flush(); + } + + batch = m.isBatch(); + + if (m.getEncodedTrack() == Frame.L4 && !m.hasPayload()) + { + commandLock.unlock(); + } + } + + public void header(Header header) + { + emit(header); + } + + public void data(ByteBuffer buf) + { + if (data != null) + { + emit(new Data(data, first, false)); + first = false; + } + + data = buf; + } + + public void data(String str) + { + data(str.getBytes()); + } + + public void data(byte[] bytes) + { + data(ByteBuffer.wrap(bytes)); + } + + public void end() + { + emit(new Data(data, first, true)); + first = true; + data = null; + if (!batch) + { + connection.flush(); + } + commandLock.unlock(); + } + + protected void invoke(Method m) + { + method(m); + } + + protected Future invoke(Method m, Class cls) + { + throw new UnsupportedOperationException(); + } + + public String toString() + { + return String.format("%s:%s", connection, channel); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/ChannelDelegate.java b/java/common/src/main/java/org/apache/qpid/transport/ChannelDelegate.java new file mode 100644 index 0000000000..8475fbf174 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/ChannelDelegate.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.transport; + +import java.util.UUID; + + +/** + * ChannelDelegate + * + * @author Rafael H. Schloming + */ + +class ChannelDelegate extends MethodDelegate +{ + + public @Override void sessionAttach(Channel channel, SessionAttach atch) + { + Session ssn = new Session(atch.getName()); + ssn.attach(channel); + ssn.sessionAttached(ssn.getName()); + } + + public @Override void sessionDetached(Channel channel, SessionDetached closed) + { + channel.closed(); + } + + public @Override void sessionDetach(Channel channel, SessionDetach dtc) + { + channel.getSession().closed(); + channel.sessionDetached(dtc.getName(), SessionDetachCode.NORMAL); + channel.closed(); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/ClientDelegate.java b/java/common/src/main/java/org/apache/qpid/transport/ClientDelegate.java new file mode 100644 index 0000000000..bbdadfadb9 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/ClientDelegate.java @@ -0,0 +1,40 @@ +/* + * + * 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.transport; + + +/** + * ClientDelegate + * + */ + +public abstract class ClientDelegate extends ConnectionDelegate +{ + + public void init(Channel ch, ProtocolHeader hdr) + { + if (hdr.getMajor() != 0 && hdr.getMinor() != 10) + { + throw new ProtocolVersionException(hdr.getMajor(), hdr.getMinor()); + } + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/Connection.java b/java/common/src/main/java/org/apache/qpid/transport/Connection.java new file mode 100644 index 0000000000..f1db5a6866 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/Connection.java @@ -0,0 +1,175 @@ +/* + * + * 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.transport; + +import org.apache.qpid.transport.util.Logger; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import java.nio.ByteBuffer; + + +/** + * Connection + * + * @author Rafael H. Schloming + * + * @todo the channels map should probably be replaced with something + * more efficient, e.g. an array or a map implementation that can use + * short instead of Short + */ + +public class Connection + implements Receiver, Sender +{ + + private static final Logger log = Logger.get(Connection.class); + + final private Sender sender; + final private ConnectionDelegate delegate; + private int channelMax = 1; + // want to make this final + private int _connectionId; + + final private Map channels = new HashMap(); + + public Connection(Sender sender, + ConnectionDelegate delegate) + { + this.sender = sender; + this.delegate = delegate; + } + + public void setConnectionId(int id) + { + _connectionId = id; + } + + public int getConnectionId() + { + return _connectionId; + } + + public ConnectionDelegate getConnectionDelegate() + { + return delegate; + } + + public void received(ProtocolEvent event) + { + log.debug("RECV: [%s] %s", this, event); + Channel channel = getChannel(event.getChannel()); + channel.received(event); + } + + public void send(ProtocolEvent event) + { + log.debug("SEND: [%s] %s", this, event); + sender.send(event); + } + + public void flush() + { + log.debug("FLUSH: [%s]", this); + sender.flush(); + } + + public int getChannelMax() + { + return channelMax; + } + + void setChannelMax(int max) + { + channelMax = max; + } + + public Channel getChannel() + { + synchronized (channels) + { + for (int i = 0; i < getChannelMax(); i++) + { + if (!channels.containsKey(i)) + { + return getChannel(i); + } + } + + throw new RuntimeException("no more channels available"); + } + } + + public Channel getChannel(int number) + { + synchronized (channels) + { + Channel channel = channels.get(number); + if (channel == null) + { + channel = new Channel(this, number, delegate.getSessionDelegate()); + channels.put(number, channel); + } + return channel; + } + } + + void removeChannel(int number) + { + synchronized (channels) + { + channels.remove(number); + } + } + + public void exception(Throwable t) + { + delegate.exception(t); + } + + public void closed() + { + log.debug("connection closed: %s", this); + synchronized (channels) + { + List values = new ArrayList(channels.values()); + for (Channel ch : values) + { + ch.closed(); + } + } + delegate.closed(); + } + + public void close() + { + sender.close(); + } + + public String toString() + { + return String.format("conn:%x", System.identityHashCode(this)); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/ConnectionDelegate.java b/java/common/src/main/java/org/apache/qpid/transport/ConnectionDelegate.java new file mode 100644 index 0000000000..90b22983d9 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/ConnectionDelegate.java @@ -0,0 +1,281 @@ +/* + * + * 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.transport; + +import org.apache.qpid.transport.util.Logger; + +import org.apache.qpid.SecurityHelper; +import org.apache.qpid.QpidException; + +import java.io.UnsupportedEncodingException; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; + +import javax.security.sasl.Sasl; +import javax.security.sasl.SaslClient; +import javax.security.sasl.SaslException; +import javax.security.sasl.SaslServer; + + +/** + * ConnectionDelegate + * + * @author Rafael H. Schloming + */ + +/** + * Currently only implemented client specific methods + * the server specific methods are dummy impls for testing + * + * the connectionClose is kind of different for both sides + */ +public abstract class ConnectionDelegate extends MethodDelegate +{ + + private static final Logger log = Logger.get(ConnectionDelegate.class); + + private String _username = "guest"; + private String _password = "guest";; + private String _mechanism; + private String _virtualHost; + private SaslClient saslClient; + private SaslServer saslServer; + private String _locale = "utf8"; + private int maxFrame = 64*1024; + private Condition _negotiationComplete; + private Lock _negotiationCompleteLock; + + public abstract SessionDelegate getSessionDelegate(); + + public abstract void exception(Throwable t); + + public abstract void closed(); + + public void setCondition(Lock negotiationCompleteLock,Condition negotiationComplete) + { + _negotiationComplete = negotiationComplete; + _negotiationCompleteLock = negotiationCompleteLock; + } + + public void init(Channel ch, ProtocolHeader hdr) + { + ch.getConnection().send(new ProtocolHeader (1, hdr.getMajor(), hdr.getMinor())); + List plain = new ArrayList(); + plain.add("PLAIN"); + List utf8 = new ArrayList(); + utf8.add("utf8"); + ch.connectionStart(null, plain, utf8); + } + + // ---------------------------------------------- + // Client side + //----------------------------------------------- + @Override public void connectionStart(Channel context, ConnectionStart struct) + { + String mechanism = null; + byte[] response = null; + try + { + mechanism = SecurityHelper.chooseMechanism(struct.getMechanisms()); + saslClient = Sasl.createSaslClient(new String[]{ mechanism },null, "AMQP", "localhost", null, + SecurityHelper.createCallbackHandler(mechanism,_username,_password )); + response = saslClient.evaluateChallenge(new byte[0]); + } + catch (UnsupportedEncodingException e) + { + // need error handling + } + catch (SaslException e) + { + // need error handling + } + catch (QpidException e) + { + // need error handling + } + + Map props = new HashMap(); + context.connectionStartOk(props, mechanism, response, _locale); + } + + @Override public void connectionSecure(Channel context, ConnectionSecure struct) + { + try + { + byte[] response = saslClient.evaluateChallenge(struct.getChallenge()); + context.connectionSecureOk(response); + } + catch (SaslException e) + { + // need error handling + } + } + + @Override public void connectionTune(Channel context, ConnectionTune struct) + { + context.getConnection().setChannelMax(struct.getChannelMax()); + context.connectionTuneOk(struct.getChannelMax(), struct.getMaxFrameSize(), struct.getHeartbeatMax()); + context.connectionOpen(_virtualHost, null, Option.INSIST); + } + + + @Override public void connectionOpenOk(Channel context, ConnectionOpenOk struct) + { + List knownHosts = struct.getKnownHosts(); + if(_negotiationCompleteLock != null) + { + _negotiationCompleteLock.lock(); + try + { + _negotiationComplete.signalAll(); + } + finally + { + _negotiationCompleteLock.unlock(); + } + } + } + + public void connectionRedirect(Channel context, ConnectionRedirect struct) + { + // not going to bother at the moment + } + + // ---------------------------------------------- + // Server side + //----------------------------------------------- + @Override public void connectionStartOk(Channel context, ConnectionStartOk struct) + { + //set the client side locale on the server side + _locale = struct.getLocale(); + _mechanism = struct.getMechanism(); + + //try + //{ + //saslServer = Sasl.createSaslServer(_mechanism, "AMQP", "ABC",null,SecurityHelper.createCallbackHandler(_mechanism,_username,_password)); + //byte[] challenge = saslServer.evaluateResponse(struct.getResponse().getBytes()); + byte[] challenge = null; + if ( challenge == null) + { + context.connectionTune(Integer.MAX_VALUE, maxFrame, 0, Integer.MAX_VALUE); + } + else + { + try + { + context.connectionSecure(challenge); + } + catch(Exception e) + { + + } + } + + + /*} + catch (SaslException e) + { + // need error handling + } + catch (QpidException e) + { + // need error handling + }*/ + } + + @Override public void connectionSecureOk(Channel context, ConnectionSecureOk struct) + { + try + { + saslServer = Sasl.createSaslServer(_mechanism, "AMQP", "ABC",new HashMap(),SecurityHelper.createCallbackHandler(_mechanism,_username,_password)); + byte[] challenge = saslServer.evaluateResponse(struct.getResponse()); + if ( challenge == null) + { + context.connectionTune(Integer.MAX_VALUE, maxFrame, 0, Integer.MAX_VALUE); + } + else + { + try + { + context.connectionSecure(challenge); + } + catch(Exception e) + { + + } + } + + + } + catch (SaslException e) + { + // need error handling + } + catch (QpidException e) + { + // need error handling + } + } + + + @Override public void connectionOpen(Channel context, ConnectionOpen struct) + { + List hosts = new ArrayList(); + hosts.add("amqp:1223243232325"); + context.connectionOpenOk(hosts); + } + + public String getPassword() + { + return _password; + } + + public void setPassword(String password) + { + _password = password; + } + + public String getUsername() + { + return _username; + } + + public void setUsername(String username) + { + _username = username; + } + + public String getVirtualHost() + { + return _virtualHost; + } + + public void setVirtualHost(String host) + { + _virtualHost = host; + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/Data.java b/java/common/src/main/java/org/apache/qpid/transport/Data.java new file mode 100644 index 0000000000..fbf7428864 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/Data.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.transport; + +import org.apache.qpid.transport.network.Frame; + +import java.nio.ByteBuffer; + +import java.util.Collections; + +import static org.apache.qpid.transport.util.Functions.*; + + +/** + * Data + * + */ + +public class Data implements ProtocolEvent +{ + + private final ByteBuffer data; + private final boolean first; + private final boolean last; + private int channel; + + public Data(ByteBuffer data, boolean first, boolean last) + { + this.data = data; + this.first = first; + this.last = last; + } + + public ByteBuffer getData() + { + return data.slice(); + } + + public boolean isFirst() + { + return first; + } + + public boolean isLast() + { + return last; + } + + public final int getChannel() + { + return channel; + } + + public final void setChannel(int channel) + { + this.channel = channel; + } + + public byte getEncodedTrack() + { + return Frame.L4; + } + + public void delegate(C context, ProtocolDelegate delegate) + { + delegate.data(context, this); + } + + public String toString() + { + StringBuffer str = new StringBuffer(); + str.append("ch="); + str.append(" "); + str.append("Data("); + str.append(str(data, 64)); + str.append(")"); + return str.toString(); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/Echo.java b/java/common/src/main/java/org/apache/qpid/transport/Echo.java new file mode 100644 index 0000000000..f8debcf923 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/Echo.java @@ -0,0 +1,84 @@ +/* + * + * 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.transport; + +import java.io.IOException; +import java.nio.ByteBuffer; + +import org.apache.qpid.transport.network.mina.MinaHandler; + + +/** + * Echo + * + */ + +public class Echo extends SessionDelegate +{ + + private MessageTransfer xfr = null; + + public void messageTransfer(Session ssn, MessageTransfer xfr) + { + this.xfr = xfr; + ssn.invoke(xfr); + } + + public void header(Session ssn, Header hdr) + { + ssn.header(hdr); + } + + public void data(Session ssn, Data data) + { + ssn.data(data.getData()); + if (data.isLast()) + { + ssn.endData(); + } + + // XXX: should be able to get command-id from any segment + ssn.processed(xfr); + } + + public static final void main(String[] args) throws IOException + { + ConnectionDelegate delegate = new ConnectionDelegate() + { + public SessionDelegate getSessionDelegate() + { + return new Echo(); + } + public void exception(Throwable t) + { + t.printStackTrace(); + } + public void closed() {} + }; + + //hack + delegate.setUsername("guest"); + delegate.setPassword("guest"); + + MinaHandler.accept("0.0.0.0", 5672, delegate); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/Field.java b/java/common/src/main/java/org/apache/qpid/transport/Field.java new file mode 100644 index 0000000000..bc6bf10041 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/Field.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.transport; + +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encoder; + + +/** + * Field + * + */ + +public abstract class Field +{ + + private final Class container; + private final Class type; + private final String name; + private final int index; + + Field(Class container, Class type, String name, int index) + { + this.container = container; + this.type = type; + this.name = name; + this.index = index; + } + + public final Class getContainer() + { + return container; + } + + public final Class getType() + { + return type; + } + + public final String getName() + { + return name; + } + + public final int getIndex() + { + return index; + } + + protected final C check(Object struct) + { + return container.cast(struct); + } + + public abstract boolean has(Object struct); + + public abstract void has(Object struct, boolean value); + + public abstract T get(Object struct); + + public abstract void read(Decoder dec, Object struct); + + public abstract void write(Encoder enc, Object struct); + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/Future.java b/java/common/src/main/java/org/apache/qpid/transport/Future.java new file mode 100644 index 0000000000..d8cde61af5 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/Future.java @@ -0,0 +1,37 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.transport; + + +/** + * Future + * + * @author Rafael H. Schloming + */ + +public interface Future +{ + + T get(); + + boolean isDone(); + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/Header.java b/java/common/src/main/java/org/apache/qpid/transport/Header.java new file mode 100644 index 0000000000..3b351ee828 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/Header.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.transport; + +import org.apache.qpid.transport.network.Frame; + +import java.util.List; +import java.nio.ByteBuffer; + + +/** + * Header + * + * @author Rafael H. Schloming + */ + +public class Header implements ProtocolEvent { + + private final List structs; + private ByteBuffer _buf; + private boolean _noPayload; + private int channel; + + public Header(List structs, boolean lastframe) + { + this.structs = structs; + _noPayload= lastframe; + } + + public List getStructs() + { + return structs; + } + + public void setBuf(ByteBuffer buf) + { + _buf = buf; + } + + public ByteBuffer getBuf() + { + return _buf; + } + public T get(Class klass) + { + for (Struct st : structs) + { + if (klass.isInstance(st)) + { + return klass.cast(st); + } + } + + return null; + } + + public final int getChannel() + { + return channel; + } + + public final void setChannel(int channel) + { + this.channel = channel; + } + + public byte getEncodedTrack() + { + return Frame.L4; + } + + public void delegate(C context, ProtocolDelegate delegate) + { + delegate.header(context, this); + } + + public boolean hasNoPayload() + { + return _noPayload; + } + + public String toString() + { + StringBuffer str = new StringBuffer(); + str.append("ch="); + str.append(channel); + str.append(" Header("); + boolean first = true; + for (Struct s : structs) + { + if (first) + { + first = false; + } + else + { + str.append(", "); + } + str.append(s); + } + str.append(")"); + return str.toString(); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/Method.java b/java/common/src/main/java/org/apache/qpid/transport/Method.java new file mode 100644 index 0000000000..1c80d8c00c --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/Method.java @@ -0,0 +1,141 @@ +/* + * + * 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.transport; + +import org.apache.qpid.transport.network.Frame; + +/** + * Method + * + * @author Rafael H. Schloming + */ + +public abstract class Method extends Struct implements ProtocolEvent +{ + + public static final Method create(int type) + { + // XXX: should generate separate factories for separate + // namespaces + return (Method) StructFactory.createInstruction(type); + } + + // XXX: command subclass? + private int id; + private int channel; + private boolean idSet = false; + private boolean sync = false; + private boolean batch = false; + + public final int getId() + { + return id; + } + + void setId(int id) + { + this.id = id; + this.idSet = true; + } + + public final int getChannel() + { + return channel; + } + + public final void setChannel(int channel) + { + this.channel = channel; + } + + public final boolean isSync() + { + return sync; + } + + final void setSync(boolean value) + { + this.sync = value; + } + + public final boolean isBatch() + { + return batch; + } + + final void setBatch(boolean value) + { + this.batch = value; + } + + public abstract boolean hasPayload(); + + public abstract byte getEncodedTrack(); + + public abstract void dispatch(C context, MethodDelegate delegate); + + public void delegate(C context, ProtocolDelegate delegate) + { + if (getEncodedTrack() == Frame.L4) + { + delegate.command(context, this); + } + else + { + delegate.control(context, this); + } + } + + public String toString() + { + StringBuilder str = new StringBuilder(); + + str.append("ch="); + str.append(channel); + + if (getEncodedTrack() == Frame.L4 && idSet) + { + str.append(" id="); + str.append(id); + } + + if (sync || batch) + { + str.append(" "); + str.append("["); + if (sync) + { + str.append("S"); + } + if (batch) + { + str.append("B"); + } + str.append("]"); + } + + str.append(" "); + str.append(super.toString()); + + return str.toString(); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/ProtocolDelegate.java b/java/common/src/main/java/org/apache/qpid/transport/ProtocolDelegate.java new file mode 100644 index 0000000000..9fa28fbe23 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/ProtocolDelegate.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.transport; + + +/** + * ProtocolDelegate + * + */ + +public interface ProtocolDelegate +{ + + void init(C context, ProtocolHeader header); + + void control(C context, Method control); + + void command(C context, Method command); + + void header(C context, Header header); + + void data(C context, Data data); + + void error(C context, ProtocolError error); + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/ProtocolError.java b/java/common/src/main/java/org/apache/qpid/transport/ProtocolError.java new file mode 100644 index 0000000000..bd6ab81997 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/ProtocolError.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.transport; + +import org.apache.qpid.transport.network.NetworkDelegate; +import org.apache.qpid.transport.network.NetworkEvent; + + +/** + * ProtocolError + * + * @author Rafael H. Schloming + */ + +public final class ProtocolError implements NetworkEvent, ProtocolEvent +{ + + private int channel; + private final byte track; + private final String format; + private final Object[] args; + + public ProtocolError(byte track, String format, Object ... args) + { + this.track = track; + this.format = format; + this.args = args; + } + + public int getChannel() + { + return channel; + } + + public void setChannel(int channel) + { + this.channel = channel; + } + + public byte getEncodedTrack() + { + return track; + } + + public String getMessage() + { + return String.format(format, args); + } + + public void delegate(C context, ProtocolDelegate delegate) + { + delegate.error(context, this); + } + + public void delegate(NetworkDelegate delegate) + { + delegate.error(this); + } + + public String toString() + { + return String.format("protocol error: %s", getMessage()); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/ProtocolEvent.java b/java/common/src/main/java/org/apache/qpid/transport/ProtocolEvent.java new file mode 100644 index 0000000000..60234c1537 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/ProtocolEvent.java @@ -0,0 +1,40 @@ +/* + * + * 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.transport; + + +/** + * ProtocolEvent + * + */ + +public interface ProtocolEvent +{ + + int getChannel(); + + void setChannel(int channel); + + byte getEncodedTrack(); + + void delegate(C context, ProtocolDelegate delegate); + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/ProtocolHeader.java b/java/common/src/main/java/org/apache/qpid/transport/ProtocolHeader.java new file mode 100644 index 0000000000..fa0c1e9c63 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/ProtocolHeader.java @@ -0,0 +1,116 @@ +/* + * + * 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.transport; + +import java.nio.ByteBuffer; + +import org.apache.qpid.transport.network.NetworkDelegate; +import org.apache.qpid.transport.network.NetworkEvent; +import org.apache.qpid.transport.network.Frame; + + +/** + * ProtocolHeader + * + * @author Rafael H. Schloming + */ + +public final class ProtocolHeader implements NetworkEvent, ProtocolEvent +{ + + private static final byte[] AMQP = {'A', 'M', 'Q', 'P' }; + private static final byte CLASS = 1; + + final private byte instance; + final private byte major; + final private byte minor; + private int channel; + + public ProtocolHeader(byte instance, byte major, byte minor) + { + this.instance = instance; + this.major = major; + this.minor = minor; + } + + public ProtocolHeader(int instance, int major, int minor) + { + this((byte) instance, (byte) major, (byte) minor); + } + + public byte getInstance() + { + return instance; + } + + public byte getMajor() + { + return major; + } + + public byte getMinor() + { + return minor; + } + + public int getChannel() + { + return channel; + } + + public void setChannel(int channel) + { + this.channel = channel; + } + + public byte getEncodedTrack() + { + return Frame.L1; + } + + public ByteBuffer toByteBuffer() + { + ByteBuffer buf = ByteBuffer.allocate(8); + buf.put(AMQP); + buf.put(CLASS); + buf.put(instance); + buf.put(major); + buf.put(minor); + buf.flip(); + return buf; + } + + public void delegate(C context, ProtocolDelegate delegate) + { + delegate.init(context, this); + } + + public void delegate(NetworkDelegate delegate) + { + delegate.init(this); + } + + public String toString() + { + return String.format("AMQP.%d %d-%d", instance, major, minor); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/ProtocolVersionException.java b/java/common/src/main/java/org/apache/qpid/transport/ProtocolVersionException.java new file mode 100644 index 0000000000..2de0c169a5 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/ProtocolVersionException.java @@ -0,0 +1,52 @@ +/* + * + * 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.transport; + + +/** + * ProtocolVersionException + * + */ + +public final class ProtocolVersionException extends TransportException +{ + + private final byte major; + private final byte minor; + + public ProtocolVersionException(byte major, byte minor) + { + super(String.format("version missmatch: %s-%s", major, minor)); + this.major = major; + this.minor = minor; + } + + public byte getMajor() + { + return this.major; + } + + public byte getMinor() + { + return this.minor; + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/Range.java b/java/common/src/main/java/org/apache/qpid/transport/Range.java new file mode 100644 index 0000000000..f4335dc8a6 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/Range.java @@ -0,0 +1,125 @@ +/* + * + * 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.transport; + +import java.util.ArrayList; +import java.util.List; + +import static org.apache.qpid.util.Serial.*; + + +/** + * Range + * + * @author Rafael H. Schloming + */ + +public final class Range +{ + private final int lower; + private final int upper; + + public Range(int lower, int upper) + { + this.lower = lower; + this.upper = upper; + } + + public int getLower() + { + return lower; + } + + public int getUpper() + { + return upper; + } + + public boolean includes(int value) + { + return le(lower, value) && le(value, upper); + } + + public boolean includes(Range range) + { + return includes(range.lower) && includes(range.upper); + } + + public boolean intersects(Range range) + { + return (includes(range.lower) || includes(range.upper) || + range.includes(lower) || range.includes(upper)); + } + + public boolean touches(Range range) + { + return (intersects(range) || + includes(range.upper + 1) || includes(range.lower - 1) || + range.includes(upper + 1) || range.includes(lower - 1)); + } + + public Range span(Range range) + { + return new Range(min(lower, range.lower), max(upper, range.upper)); + } + + public List subtract(Range range) + { + List result = new ArrayList(); + + if (includes(range.lower) && le(lower, range.lower - 1)) + { + result.add(new Range(lower, range.lower - 1)); + } + + if (includes(range.upper) && le(range.upper + 1, upper)) + { + result.add(new Range(range.upper + 1, upper)); + } + + if (result.isEmpty() && !range.includes(this)) + { + result.add(this); + } + + return result; + } + + public Range intersect(Range range) + { + int l = max(lower, range.lower); + int r = min(upper, range.upper); + if (gt(l, r)) + { + return null; + } + else + { + return new Range(l, r); + } + } + + public String toString() + { + return "[" + lower + ", " + upper + "]"; + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/RangeSet.java b/java/common/src/main/java/org/apache/qpid/transport/RangeSet.java new file mode 100644 index 0000000000..217b81f43f --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/RangeSet.java @@ -0,0 +1,142 @@ +/* + * + * 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.transport; + +import java.util.Iterator; +import java.util.ListIterator; +import java.util.LinkedList; + +import static org.apache.qpid.util.Serial.*; + +/** + * RangeSet + * + * @author Rafael H. Schloming + */ + +public final class RangeSet implements Iterable +{ + + private LinkedList ranges = new LinkedList(); + + public int size() + { + return ranges.size(); + } + + public Iterator iterator() + { + return ranges.iterator(); + } + + public boolean includes(Range range) + { + for (Range r : this) + { + if (r.includes(range)) + { + return true; + } + } + + return false; + } + + public boolean includes(int n) + { + for (Range r : this) + { + if (r.includes(n)) + { + return true; + } + } + + return false; + } + + public void add(Range range) + { + ListIterator it = ranges.listIterator(); + + while (it.hasNext()) + { + Range next = it.next(); + if (range.touches(next)) + { + it.remove(); + range = range.span(next); + } + else if (lt(range.getUpper(), next.getLower())) + { + it.previous(); + it.add(range); + return; + } + } + + it.add(range); + } + + public void add(int lower, int upper) + { + add(new Range(lower, upper)); + } + + public void add(int value) + { + add(value, value); + } + + public void clear() + { + ranges.clear(); + } + + public RangeSet copy() + { + RangeSet copy = new RangeSet(); + copy.ranges.addAll(ranges); + return copy; + } + + public String toString() + { + StringBuffer str = new StringBuffer(); + str.append("{"); + boolean first = true; + for (Range range : ranges) + { + if (first) + { + first = false; + } + else + { + str.append(", "); + } + str.append(range); + } + str.append("}"); + return str.toString(); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/Receiver.java b/java/common/src/main/java/org/apache/qpid/transport/Receiver.java new file mode 100644 index 0000000000..2a994580dc --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/Receiver.java @@ -0,0 +1,38 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.transport; + + +/** + * Receiver + * + */ + +public interface Receiver +{ + + void received(T msg); + + void exception(Throwable t); + + void closed(); + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/Result.java b/java/common/src/main/java/org/apache/qpid/transport/Result.java new file mode 100644 index 0000000000..1116492a8d --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/Result.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.transport; + + +/** + * Result + * + * @author Rafael H. Schloming + */ + +public abstract class Result extends Struct {} diff --git a/java/common/src/main/java/org/apache/qpid/transport/Sender.java b/java/common/src/main/java/org/apache/qpid/transport/Sender.java new file mode 100644 index 0000000000..9a6f675d7f --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/Sender.java @@ -0,0 +1,38 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.transport; + + +/** + * Sender + * + */ + +public interface Sender +{ + + void send(T msg); + + void flush(); + + void close(); + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/Session.java b/java/common/src/main/java/org/apache/qpid/transport/Session.java new file mode 100644 index 0000000000..8ec13c0ee7 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/Session.java @@ -0,0 +1,558 @@ +/* + * + * 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.transport; + + +import org.apache.qpid.transport.network.Frame; + +import org.apache.qpid.transport.util.Logger; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; + +import static org.apache.qpid.transport.Option.*; +import static org.apache.qpid.transport.util.Functions.*; +import static org.apache.qpid.util.Serial.*; + +/** + * Session + * + * @author Rafael H. Schloming + */ + +public class Session extends Invoker +{ + + private static final Logger log = Logger.get(Session.class); + + private static boolean ENABLE_REPLAY = false; + + static + { + String enableReplay = "enable_command_replay"; + try + { + ENABLE_REPLAY = new Boolean(System.getProperties().getProperty(enableReplay, "false")); + } + catch (Exception e) + { + ENABLE_REPLAY = false; + } + } + + private byte[] name; + private long timeout = 60000; + private boolean autoSync = false; + + // channel may be null + Channel channel; + + // incoming command count + int commandsIn = 0; + // completed incoming commands + private final Object processedLock = new Object(); + private RangeSet processed = new RangeSet(); + private Range syncPoint = null; + + // outgoing command count + private int commandsOut = 0; + private Map commands = new HashMap(); + private int maxComplete = commandsOut - 1; + private boolean needSync = false; + + private AtomicBoolean closed = new AtomicBoolean(false); + + public Session(byte[] name) + { + this.name = name; + } + + public byte[] getName() + { + return name; + } + + public void setAutoSync(boolean value) + { + synchronized (commands) + { + this.autoSync = value; + } + } + + public Map getOutstandingCommands() + { + return commands; + } + + public int getCommandsOut() + { + return commandsOut; + } + + public int getCommandsIn() + { + return commandsIn; + } + + public int nextCommandId() + { + return commandsIn++; + } + + final void identify(Method cmd) + { + int id = nextCommandId(); + cmd.setId(id); + log.debug("ID: [%s] %s", this.channel, id); + if ((id % 65536) == 0) + { + flushProcessed(TIMELY_REPLY); + } + } + + public void processed(Method command) + { + processed(command.getId()); + } + + public void processed(int command) + { + processed(new Range(command, command)); + } + + public void processed(int lower, int upper) + { + + processed(new Range(lower, upper)); + } + + public void processed(Range range) + { + log.debug("%s processed(%s)", this, range); + + boolean flush; + synchronized (processedLock) + { + processed.add(range); + flush = syncPoint != null && processed.includes(syncPoint); + } + if (flush) + { + flushProcessed(); + } + } + + public void flushProcessed(Option ... options) + { + RangeSet copy; + synchronized (processedLock) + { + copy = processed.copy(); + } + sessionCompleted(copy, options); + } + + void knownComplete(RangeSet kc) + { + synchronized (processedLock) + { + RangeSet newProcessed = new RangeSet(); + for (Range pr : processed) + { + for (Range kr : kc) + { + for (Range r : pr.subtract(kr)) + { + newProcessed.add(r); + } + } + } + this.processed = newProcessed; + } + } + + void syncPoint() + { + int id = getCommandsIn() - 1; + log.debug("%s synced to %d", this, id); + Range range = new Range(0, id - 1); + boolean flush; + synchronized (processedLock) + { + flush = processed.includes(range); + if (!flush) + { + syncPoint = range; + } + } + if (flush) + { + flushProcessed(); + } + } + + public void attach(Channel channel) + { + this.channel = channel; + channel.setSession(this); + } + + public Method getCommand(int id) + { + synchronized (commands) + { + return commands.get(id); + } + } + + boolean complete(int lower, int upper) + { + log.debug("%s complete(%d, %d)", this, lower, upper); + synchronized (commands) + { + int old = maxComplete; + for (int id = max(maxComplete, lower); le(id, upper); id++) + { + commands.remove(id); + } + if (le(lower, maxComplete + 1)) + { + maxComplete = max(maxComplete, upper); + } + log.debug("%s commands remaining: %s", this, commands); + commands.notifyAll(); + return gt(maxComplete, old); + } + } + + public void invoke(Method m) + { + if (m.getEncodedTrack() == Frame.L4) + { + synchronized (commands) + { + int next = commandsOut++; + m.setId(next); + if (next == 0) + { + sessionCommandPoint(0, 0); + } + if (ENABLE_REPLAY) + { + commands.put(next, m); + } + if (autoSync) + { + m.setSync(true); + } + needSync = !m.isSync(); + channel.method(m); + if (autoSync && !m.hasPayload()) + { + sync(); + } + + // flush every 64K commands to avoid ambiguity on + // wraparound + if ((next % 65536) == 0) + { + sessionFlush(COMPLETED); + } + } + } + else + { + channel.method(m); + } + } + + public void header(Header header) + { + channel.header(header); + } + + public Header header(List structs) + { + Header res = new Header(structs, false); + header(res); + return res; + } + + public Header header(Struct ... structs) + { + return header(Arrays.asList(structs)); + } + + public void data(ByteBuffer buf) + { + channel.data(buf); + } + + public void data(String str) + { + channel.data(str); + } + + public void data(byte[] bytes) + { + channel.data(bytes); + } + + public void endData() + { + channel.end(); + synchronized (commands) + { + if (autoSync) + { + sync(); + } + } + } + + public void sync() + { + sync(timeout); + } + + public void sync(long timeout) + { + log.debug("%s sync()", this); + synchronized (commands) + { + int point = commandsOut - 1; + + if (needSync && lt(maxComplete, point)) + { + executionSync(SYNC); + } + + long start = System.currentTimeMillis(); + long elapsed = 0; + while (!closed.get() && elapsed < timeout && lt(maxComplete, point)) + { + try { + log.debug("%s waiting for[%d]: %d, %s", this, point, + maxComplete, commands); + commands.wait(timeout - elapsed); + elapsed = System.currentTimeMillis() - start; + } + catch (InterruptedException e) + { + throw new RuntimeException(e); + } + } + + if (lt(maxComplete, point)) + { + if (closed.get()) + { + throw new SessionException(getExceptions()); + } + else + { + throw new RuntimeException + (String.format + ("timed out waiting for sync: complete = %s, point = %s", maxComplete, point)); + } + } + } + } + + private Map> results = + new HashMap>(); + private List exceptions = + new ArrayList(); + + void result(int command, Struct result) + { + ResultFuture future; + synchronized (results) + { + future = results.remove(command); + } + future.set(result); + } + + void addException(ExecutionException exc) + { + synchronized (exceptions) + { + exceptions.add(exc); + } + } + + List getExceptions() + { + synchronized (exceptions) + { + return new ArrayList(exceptions); + } + } + + protected Future invoke(Method m, Class klass) + { + synchronized (commands) + { + int command = commandsOut; + ResultFuture future = new ResultFuture(klass); + synchronized (results) + { + results.put(command, future); + } + invoke(m); + return future; + } + } + + private class ResultFuture implements Future + { + + private final Class klass; + private T result; + + private ResultFuture(Class klass) + { + this.klass = klass; + } + + private void set(Struct result) + { + synchronized (this) + { + this.result = klass.cast(result); + notifyAll(); + } + } + + public T get(long timeout) + { + synchronized (this) + { + long start = System.currentTimeMillis(); + long elapsed = 0; + while (!closed.get() && timeout - elapsed > 0 && !isDone()) + { + try + { + log.debug("%s waiting for result: %s", Session.this, this); + wait(timeout - elapsed); + elapsed = System.currentTimeMillis() - start; + } + catch (InterruptedException e) + { + throw new RuntimeException(e); + } + } + } + + if (isDone()) + { + return result; + } + else if (closed.get()) + { + throw new SessionException(getExceptions()); + } + else + { + return null; + } + } + + public T get() + { + return get(timeout); + } + + public boolean isDone() + { + return result != null; + } + + public String toString() + { + return String.format("Future(%s)", isDone() ? result : klass); + } + + } + + public void close() + { + sessionRequestTimeout(0); + sessionDetach(name); + synchronized (commands) + { + long start = System.currentTimeMillis(); + long elapsed = 0; + try + { + while (!closed.get() && elapsed < timeout) + { + commands.wait(timeout - elapsed); + elapsed = System.currentTimeMillis() - start; + } + } + catch (InterruptedException e) + { + throw new RuntimeException(e); + } + } + } + + public void exception(Throwable t) + { + log.error(t, "caught exception"); + } + + public void closed() + { + closed.set(true); + synchronized (commands) + { + commands.notifyAll(); + } + synchronized (results) + { + for (ResultFuture result : results.values()) + { + synchronized(result) + { + result.notifyAll(); + } + } + } + channel.setSession(null); + channel = null; + } + + public String toString() + { + return String.format("ssn:%s", str(name)); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/SessionDelegate.java b/java/common/src/main/java/org/apache/qpid/transport/SessionDelegate.java new file mode 100644 index 0000000000..dc400d3098 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/SessionDelegate.java @@ -0,0 +1,129 @@ +/* + * + * 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.transport; + +import org.apache.qpid.transport.network.Frame; + + +/** + * SessionDelegate + * + * @author Rafael H. Schloming + */ + +public abstract class SessionDelegate + extends MethodDelegate + implements ProtocolDelegate +{ + public void init(Session ssn, ProtocolHeader hdr) { } + + public void control(Session ssn, Method method) { + method.dispatch(ssn, this); + } + + public void command(Session ssn, Method method) { + ssn.identify(method); + method.dispatch(ssn, this); + if (!method.hasPayload()) + { + ssn.processed(method); + } + } + + public void header(Session ssn, Header header) { } + + public void data(Session ssn, Data data) { } + + public void error(Session ssn, ProtocolError error) { } + + @Override public void executionResult(Session ssn, ExecutionResult result) + { + ssn.result(result.getCommandId(), result.getValue()); + } + + @Override public void executionException(Session ssn, ExecutionException exc) + { + ssn.addException(exc); + } + + @Override public void sessionCompleted(Session ssn, SessionCompleted cmp) + { + RangeSet ranges = cmp.getCommands(); + RangeSet known = null; + if (cmp.getTimelyReply()) + { + known = new RangeSet(); + } + + if (ranges != null) + { + for (Range range : ranges) + { + boolean advanced = ssn.complete(range.getLower(), range.getUpper()); + if (advanced && known != null) + { + known.add(range); + } + } + } + + if (known != null) + { + ssn.sessionKnownCompleted(known); + } + } + + @Override public void sessionKnownCompleted(Session ssn, SessionKnownCompleted kcmp) + { + RangeSet kc = kcmp.getCommands(); + if (kc != null) + { + ssn.knownComplete(kc); + } + } + + @Override public void sessionFlush(Session ssn, SessionFlush flush) + { + if (flush.getCompleted()) + { + ssn.flushProcessed(); + } + if (flush.getConfirmed()) + { + ssn.flushProcessed(); + } + if (flush.getExpected()) + { + throw new Error("not implemented"); + } + } + + @Override public void sessionCommandPoint(Session ssn, SessionCommandPoint scp) + { + ssn.commandsIn = scp.getCommandId(); + } + + @Override public void executionSync(Session ssn, ExecutionSync sync) + { + ssn.syncPoint(); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/SessionException.java b/java/common/src/main/java/org/apache/qpid/transport/SessionException.java new file mode 100644 index 0000000000..dc294b2206 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/SessionException.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.transport; + +import java.util.List; + +/** + * SessionException + * + */ + +public class SessionException extends RuntimeException +{ + + private List exceptions; + + public SessionException(List exceptions) + { + super(exceptions.isEmpty() ? "" : exceptions.toString()); + this.exceptions = exceptions; + } + + public List getExceptions() + { + return exceptions; + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/Struct.java b/java/common/src/main/java/org/apache/qpid/transport/Struct.java new file mode 100644 index 0000000000..22bd9f34ad --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/Struct.java @@ -0,0 +1,142 @@ +/* + * + * 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.transport; + +import java.util.List; +import java.util.Map; + +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encodable; +import org.apache.qpid.transport.codec.Encoder; + + +/** + * Struct + * + * @author Rafael H. Schloming + */ + +public abstract class Struct implements Encodable +{ + + public static Struct create(int type) + { + return StructFactory.create(type); + } + + boolean dirty = true; + + public boolean isDirty() + { + return dirty; + } + + public void setDirty(boolean dirty) + { + this.dirty = dirty; + } + + public abstract int getStructType(); + + public abstract int getSizeWidth(); + + public abstract int getPackWidth(); + + public final int getEncodedType() + { + int type = getStructType(); + if (type < 0) + { + throw new UnsupportedOperationException(); + } + return type; + } + + private final boolean isBit(Field f) + { + return f.getType().equals(Boolean.class); + } + + private final boolean packed() + { + return getPackWidth() > 0; + } + + private final boolean encoded(Field f) + { + return !packed() || !isBit(f) && f.has(this); + } + + private final int getFlagWidth() + { + return (getFields().size() + 7)/8; + } + + private final int getPaddWidth() + { + int pw = getPackWidth() - getFlagWidth(); + assert pw > 0; + return pw; + } + + private final int getFlagCount() + { + return 8*getPackWidth(); + } + + private final int getReservedFlagCount() + { + return getFlagCount() - getFields().size(); + } + + public abstract void read(Decoder dec); + + public abstract void write(Encoder enc); + + public abstract Map getFields(); + + public String toString() + { + StringBuilder str = new StringBuilder(); + str.append(getClass().getSimpleName()); + + str.append("("); + boolean first = true; + for (Map.Entry me : getFields().entrySet()) + { + if (first) + { + first = false; + } + else + { + str.append(", "); + } + str.append(me.getKey()); + str.append("="); + str.append(me.getValue()); + } + str.append(")"); + + return str.toString(); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/TransportException.java b/java/common/src/main/java/org/apache/qpid/transport/TransportException.java new file mode 100644 index 0000000000..5ef15154fc --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/TransportException.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.transport; + + +/** + * TransportException + */ + +public class TransportException extends RuntimeException +{ + + public TransportException(String msg) + { + super(msg); + } + + public TransportException(String msg, Throwable cause) + { + super(msg, cause); + } + + public TransportException(Throwable cause) + { + super(cause); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/codec/AbstractDecoder.java b/java/common/src/main/java/org/apache/qpid/transport/codec/AbstractDecoder.java new file mode 100644 index 0000000000..a8a4997ae7 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/codec/AbstractDecoder.java @@ -0,0 +1,470 @@ +/* + * + * 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.transport.codec; + +import java.io.UnsupportedEncodingException; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.transport.Binary; +import org.apache.qpid.transport.RangeSet; +import org.apache.qpid.transport.Struct; +import org.apache.qpid.transport.Type; + +import static org.apache.qpid.transport.util.Functions.*; + + +/** + * AbstractDecoder + * + * @author Rafael H. Schloming + */ + +abstract class AbstractDecoder implements Decoder +{ + + private final Map str8cache = new LinkedHashMap() + { + @Override protected boolean removeEldestEntry(Map.Entry me) + { + return size() > 4*1024; + } + }; + + protected abstract byte doGet(); + + protected abstract void doGet(byte[] bytes); + + protected byte get() + { + return doGet(); + } + + protected void get(byte[] bytes) + { + doGet(bytes); + } + + protected Binary get(int size) + { + byte[] bytes = new byte[size]; + get(bytes); + return new Binary(bytes); + } + + protected short uget() + { + return (short) (0xFF & get()); + } + + public short readUint8() + { + return uget(); + } + + public int readUint16() + { + int i = uget() << 8; + i |= uget(); + return i; + } + + public long readUint32() + { + long l = uget() << 24; + l |= uget() << 16; + l |= uget() << 8; + l |= uget(); + return l; + } + + public int readSequenceNo() + { + return (int) readUint32(); + } + + public long readUint64() + { + long l = 0; + for (int i = 0; i < 8; i++) + { + l |= ((long) (0xFF & get())) << (56 - i*8); + } + return l; + } + + public long readDatetime() + { + return readUint64(); + } + + private static final String decode(byte[] bytes, int offset, int length, String charset) + { + try + { + return new String(bytes, offset, length, charset); + } + catch (UnsupportedEncodingException e) + { + throw new RuntimeException(e); + } + } + + private static final String decode(byte[] bytes, String charset) + { + return decode(bytes, 0, bytes.length, charset); + } + + public String readStr8() + { + short size = readUint8(); + Binary bin = get(size); + String str = str8cache.get(bin); + if (str == null) + { + str = decode(bin.array(), bin.offset(), bin.size(), "UTF-8"); + str8cache.put(bin, str); + } + return str; + } + + public String readStr16() + { + int size = readUint16(); + byte[] bytes = new byte[size]; + get(bytes); + return decode(bytes, "UTF-8"); + } + + public byte[] readVbin8() + { + int size = readUint8(); + byte[] bytes = new byte[size]; + get(bytes); + return bytes; + } + + public byte[] readVbin16() + { + int size = readUint16(); + byte[] bytes = new byte[size]; + get(bytes); + return bytes; + } + + public byte[] readVbin32() + { + int size = (int) readUint32(); + byte[] bytes = new byte[size]; + get(bytes); + return bytes; + } + + public RangeSet readSequenceSet() + { + int count = readUint16()/8; + if (count == 0) + { + return null; + } + else + { + RangeSet ranges = new RangeSet(); + for (int i = 0; i < count; i++) + { + ranges.add(readSequenceNo(), readSequenceNo()); + } + return ranges; + } + } + + public RangeSet readByteRanges() + { + throw new Error("not implemented"); + } + + public UUID readUuid() + { + long msb = readUint64(); + long lsb = readUint64(); + return new UUID(msb, lsb); + } + + public String readContent() + { + throw new Error("Deprecated"); + } + + public Struct readStruct(int type) + { + Struct st = Struct.create(type); + int width = st.getSizeWidth(); + if (width > 0) + { + long size = readSize(width); + if (size == 0) + { + return null; + } + } + if (type > 0) + { + int code = readUint16(); + assert code == type; + } + st.read(this); + return st; + } + + public Struct readStruct32() + { + long size = readUint32(); + if (size == 0) + { + return null; + } + else + { + int type = readUint16(); + Struct result = Struct.create(type); + result.read(this); + return result; + } + } + + public Map readMap() + { + long size = readUint32(); + + if (size == 0) + { + return null; + } + + long count = readUint32(); + + if (count == 0) + { + return Collections.EMPTY_MAP; + } + + Map result = new LinkedHashMap(); + for (int i = 0; i < count; i++) + { + String key = readStr8(); + byte code = get(); + Type t = getType(code); + Object value = read(t); + result.put(key, value); + } + + return result; + } + + public List readList() + { + long size = readUint32(); + + if (size == 0) + { + return null; + } + + long count = readUint32(); + + if (count == 0) + { + return Collections.EMPTY_LIST; + } + + List result = new ArrayList(); + for (int i = 0; i < count; i++) + { + byte code = get(); + Type t = getType(code); + Object value = read(t); + result.add(value); + } + return result; + } + + public List readArray() + { + long size = readUint32(); + + if (size == 0) + { + return null; + } + + byte code = get(); + Type t = getType(code); + long count = readUint32(); + + if (count == 0) + { + return Collections.EMPTY_LIST; + } + + List result = new ArrayList(); + for (int i = 0; i < count; i++) + { + Object value = read(t); + result.add(value); + } + return result; + } + + private Type getType(byte code) + { + Type type = Type.get(code); + if (type == null) + { + throw new IllegalArgumentException("unknown code: " + code); + } + else + { + return type; + } + } + + private long readSize(Type t) + { + if (t.fixed) + { + return t.width; + } + else + { + return readSize(t.width); + } + } + + private long readSize(int width) + { + switch (width) + { + case 1: + return readUint8(); + case 2: + return readUint16(); + case 4: + return readUint32(); + default: + throw new IllegalStateException("illegal width: " + width); + } + } + + private byte[] readBytes(Type t) + { + long size = readSize(t); + byte[] result = new byte[(int) size]; + get(result); + return result; + } + + private Object read(Type t) + { + switch (t) + { + case BIN8: + case UINT8: + return readUint8(); + case INT8: + return get(); + case CHAR: + return (char) get(); + case BOOLEAN: + return get() > 0; + + case BIN16: + case UINT16: + return readUint16(); + + case INT16: + return (short) readUint16(); + + case BIN32: + case UINT32: + return readUint32(); + + case CHAR_UTF32: + case INT32: + return (int) readUint32(); + + case FLOAT: + return Float.intBitsToFloat((int) readUint32()); + + case BIN64: + case UINT64: + case INT64: + case DATETIME: + return readUint64(); + + case DOUBLE: + return Double.longBitsToDouble(readUint64()); + + case UUID: + return readUuid(); + + case STR8: + return readStr8(); + + case STR16: + return readStr16(); + + case STR8_LATIN: + case STR8_UTF16: + case STR16_LATIN: + case STR16_UTF16: + // XXX: need to do character conversion + return new String(readBytes(t)); + + case MAP: + return readMap(); + case LIST: + return readList(); + case ARRAY: + return readArray(); + case STRUCT32: + return readStruct32(); + + case BIN40: + case DEC32: + case BIN72: + case DEC64: + // XXX: what types are we supposed to use here? + return readBytes(t); + + case VOID: + return null; + + default: + return readBytes(t); + } + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/codec/AbstractEncoder.java b/java/common/src/main/java/org/apache/qpid/transport/codec/AbstractEncoder.java new file mode 100644 index 0000000000..908d14a307 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/codec/AbstractEncoder.java @@ -0,0 +1,620 @@ +/* + * + * 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.transport.codec; + +import java.io.UnsupportedEncodingException; + +import java.nio.ByteBuffer; + +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.transport.Range; +import org.apache.qpid.transport.RangeSet; +import org.apache.qpid.transport.Struct; +import org.apache.qpid.transport.Type; + +import static org.apache.qpid.transport.util.Functions.*; + + +/** + * AbstractEncoder + * + * @author Rafael H. Schloming + */ + +abstract class AbstractEncoder implements Encoder +{ + + private static Map,Type> ENCODINGS = new HashMap,Type>(); + static + { + ENCODINGS.put(Boolean.class, Type.BOOLEAN); + ENCODINGS.put(String.class, Type.STR16); + ENCODINGS.put(Long.class, Type.INT64); + ENCODINGS.put(Integer.class, Type.INT32); + ENCODINGS.put(Short.class, Type.INT16); + ENCODINGS.put(Byte.class, Type.INT8); + ENCODINGS.put(Map.class, Type.MAP); + ENCODINGS.put(List.class, Type.LIST); + ENCODINGS.put(Float.class, Type.FLOAT); + ENCODINGS.put(Double.class, Type.DOUBLE); + ENCODINGS.put(Character.class, Type.CHAR); + ENCODINGS.put(byte[].class, Type.VBIN32); + } + + private final Map str8cache = new LinkedHashMap() + { + @Override protected boolean removeEldestEntry(Map.Entry me) + { + return size() > 4*1024; + } + }; + + protected abstract void doPut(byte b); + + protected abstract void doPut(ByteBuffer src); + + protected void put(byte b) + { + doPut(b); + } + + protected void put(ByteBuffer src) + { + doPut(src); + } + + protected void put(byte[] bytes) + { + put(ByteBuffer.wrap(bytes)); + } + + protected abstract int beginSize8(); + protected abstract void endSize8(int pos); + + protected abstract int beginSize16(); + protected abstract void endSize16(int pos); + + protected abstract int beginSize32(); + protected abstract void endSize32(int pos); + + public void writeUint8(short b) + { + assert b < 0x100; + + put((byte) b); + } + + public void writeUint16(int s) + { + assert s < 0x10000; + + put(lsb(s >>> 8)); + put(lsb(s)); + } + + public void writeUint32(long i) + { + assert i < 0x100000000L; + + put(lsb(i >>> 24)); + put(lsb(i >>> 16)); + put(lsb(i >>> 8)); + put(lsb(i)); + } + + public void writeSequenceNo(int i) + { + writeUint32(i); + } + + public void writeUint64(long l) + { + for (int i = 0; i < 8; i++) + { + put(lsb(l >> (56 - i*8))); + } + } + + + public void writeDatetime(long l) + { + writeUint64(l); + } + + private static final byte[] encode(String s, String charset) + { + try + { + return s.getBytes(charset); + } + catch (UnsupportedEncodingException e) + { + throw new RuntimeException(e); + } + } + + public void writeStr8(String s) + { + if (s == null) + { + s = ""; + } + + byte[] bytes = str8cache.get(s); + if (bytes == null) + { + bytes = encode(s, "UTF-8"); + str8cache.put(s, bytes); + } + writeUint8((short) bytes.length); + put(bytes); + } + + public void writeStr16(String s) + { + if (s == null) + { + s = ""; + } + + byte[] bytes = encode(s, "UTF-8"); + writeUint16(bytes.length); + put(bytes); + } + + public void writeVbin8(byte[] bytes) + { + if (bytes == null) { bytes = new byte[0]; } + if (bytes.length > 255) + { + throw new IllegalArgumentException("array too long: " + bytes.length); + } + writeUint8((short) bytes.length); + put(ByteBuffer.wrap(bytes)); + } + + public void writeVbin16(byte[] bytes) + { + if (bytes == null) { bytes = new byte[0]; } + writeUint16(bytes.length); + put(ByteBuffer.wrap(bytes)); + } + + public void writeVbin32(byte[] bytes) + { + if (bytes == null) { bytes = new byte[0]; } + writeUint32(bytes.length); + put(ByteBuffer.wrap(bytes)); + } + + public void writeSequenceSet(RangeSet ranges) + { + if (ranges == null) + { + writeUint16((short) 0); + } + else + { + writeUint16(ranges.size() * 8); + for (Range range : ranges) + { + writeSequenceNo(range.getLower()); + writeSequenceNo(range.getUpper()); + } + } + } + + public void writeByteRanges(RangeSet ranges) + { + throw new Error("not implemented"); + } + + public void writeUuid(UUID uuid) + { + long msb = 0; + long lsb = 0; + if (uuid != null) + { + msb = uuid.getMostSignificantBits(); + lsb = uuid.getLeastSignificantBits(); + } + writeUint64(msb); + writeUint64(lsb); + } + + public void writeStruct(int type, Struct s) + { + boolean empty = false; + if (s == null) + { + s = Struct.create(type); + empty = true; + } + + int width = s.getSizeWidth(); + int pos = -1; + if (width > 0) + { + pos = beginSize(width); + } + + if (type > 0) + { + writeUint16(type); + } + + s.write(this); + + if (width > 0) + { + endSize(width, pos); + } + } + + public void writeStruct32(Struct s) + { + if (s == null) + { + writeUint32(0); + } + else + { + int pos = beginSize32(); + writeUint16(s.getEncodedType()); + s.write(this); + endSize32(pos); + } + } + + private Type encoding(Object value) + { + if (value == null) + { + return Type.VOID; + } + + Class klass = value.getClass(); + Type type = resolve(klass); + + if (type == null) + { + throw new IllegalArgumentException + ("unable to resolve type: " + klass + ", " + value); + } + else + { + return type; + } + } + + static final Type resolve(Class klass) + { + Type type = ENCODINGS.get(klass); + if (type != null) + { + return type; + } + + Class sup = klass.getSuperclass(); + if (sup != null) + { + type = resolve(klass.getSuperclass()); + + if (type != null) + { + return type; + } + } + + for (Class iface : klass.getInterfaces()) + { + type = resolve(iface); + if (type != null) + { + return type; + } + } + + return null; + } + + public void writeMap(Map map) + { + int pos = beginSize32(); + if (map != null) + { + writeUint32(map.size()); + writeMapEntries(map); + } + endSize32(pos); + } + + protected void writeMapEntries(Map map) + { + for (Map.Entry entry : map.entrySet()) + { + String key = entry.getKey(); + Object value = entry.getValue(); + Type type = encoding(value); + writeStr8(key); + put(type.code); + write(type, value); + } + } + + public void writeList(List list) + { + int pos = beginSize32(); + if (list != null) + { + writeUint32(list.size()); + writeListEntries(list); + } + endSize32(pos); + } + + protected void writeListEntries(List list) + { + for (Object value : list) + { + Type type = encoding(value); + put(type.code); + write(type, value); + } + } + + public void writeArray(List array) + { + int pos = beginSize32(); + if (array != null) + { + writeArrayEntries(array); + } + endSize32(pos); + } + + protected void writeArrayEntries(List array) + { + Type type; + + if (array.isEmpty()) + { + return; + } + else + { + type = encoding(array.get(0)); + } + + put(type.code); + + writeUint32(array.size()); + + for (Object value : array) + { + write(type, value); + } + } + + private void writeSize(Type t, int size) + { + if (t.fixed) + { + if (size != t.width) + { + throw new IllegalArgumentException + ("size does not match fixed width " + t.width + ": " + + size); + } + } + else + { + writeSize(t.width, size); + } + } + + private void writeSize(int width, int size) + { + // XXX: should check lengths + switch (width) + { + case 1: + writeUint8((short) size); + break; + case 2: + writeUint16(size); + break; + case 4: + writeUint32(size); + break; + default: + throw new IllegalStateException("illegal width: " + width); + } + } + + private int beginSize(int width) + { + switch (width) + { + case 1: + return beginSize8(); + case 2: + return beginSize16(); + case 4: + return beginSize32(); + default: + throw new IllegalStateException("illegal width: " + width); + } + } + + private void endSize(int width, int pos) + { + switch (width) + { + case 1: + endSize8(pos); + break; + case 2: + endSize16(pos); + break; + case 4: + endSize32(pos); + break; + default: + throw new IllegalStateException("illegal width: " + width); + } + } + + private void writeBytes(Type t, byte[] bytes) + { + writeSize(t, bytes.length); + put(bytes); + } + + private T coerce(Class klass, Object value) + { + if (klass.isInstance(value)) + { + return klass.cast(value); + } + else + { + throw new IllegalArgumentException("" + value); + } + } + + private void write(Type t, Object value) + { + switch (t) + { + case BIN8: + case UINT8: + writeUint8(coerce(Short.class, value)); + break; + case INT8: + put(coerce(Byte.class, value)); + break; + case CHAR: + put((byte) ((char)coerce(Character.class, value))); + break; + case BOOLEAN: + if (coerce(Boolean.class, value)) + { + put((byte) 1); + } + else + { + put((byte) 0); + } + break; + + case BIN16: + case UINT16: + writeUint16(coerce(Integer.class, value)); + break; + + case INT16: + writeUint16(coerce(Short.class, value)); + break; + + case BIN32: + case UINT32: + writeUint32(coerce(Long.class, value)); + break; + + case CHAR_UTF32: + case INT32: + writeUint32(coerce(Integer.class, value)); + break; + + case FLOAT: + writeUint32(Float.floatToIntBits(coerce(Float.class, value))); + break; + + case BIN64: + case UINT64: + case INT64: + case DATETIME: + writeUint64(coerce(Long.class, value)); + break; + + case DOUBLE: + long bits = Double.doubleToLongBits(coerce(Double.class, value)); + writeUint64(bits); + break; + + case UUID: + writeUuid(coerce(UUID.class, value)); + break; + + case STR8: + writeStr8(coerce(String.class, value)); + break; + + case STR16: + writeStr16(coerce(String.class, value)); + break; + + case STR8_LATIN: + case STR8_UTF16: + case STR16_LATIN: + case STR16_UTF16: + // XXX: need to do character conversion + writeBytes(t, coerce(String.class, value).getBytes()); + break; + + case MAP: + writeMap((Map) coerce(Map.class, value)); + break; + case LIST: + writeList(coerce(List.class, value)); + break; + case ARRAY: + writeArray(coerce(List.class, value)); + break; + case STRUCT32: + writeStruct32(coerce(Struct.class, value)); + break; + + case BIN40: + case DEC32: + case BIN72: + case DEC64: + // XXX: what types are we supposed to use here? + writeBytes(t, coerce(byte[].class, value)); + break; + + case VOID: + break; + + default: + writeBytes(t, coerce(byte[].class, value)); + break; + } + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/codec/BBDecoder.java b/java/common/src/main/java/org/apache/qpid/transport/codec/BBDecoder.java new file mode 100644 index 0000000000..dd634eb94a --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/codec/BBDecoder.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.transport.codec; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import org.apache.qpid.transport.Binary; + + +/** + * BBDecoder + * + * @author Rafael H. Schloming + */ + +public final class BBDecoder extends AbstractDecoder +{ + + private ByteBuffer in; + + public void init(ByteBuffer in) + { + this.in = in; + this.in.order(ByteOrder.BIG_ENDIAN); + } + + protected byte doGet() + { + return in.get(); + } + + protected void doGet(byte[] bytes) + { + in.get(bytes); + } + + protected Binary get(int size) + { + if (in.hasArray()) + { + byte[] bytes = in.array(); + Binary bin = new Binary(bytes, in.arrayOffset() + in.position(), size); + in.position(in.position() + size); + return bin; + } + else + { + return super.get(size); + } + } + + public boolean hasRemaining() + { + return in.hasRemaining(); + } + + public short readUint8() + { + return (short) (0xFF & in.get()); + } + + public int readUint16() + { + return 0xFFFF & in.getShort(); + } + + public long readUint32() + { + return 0xFFFFFFFFL & in.getInt(); + } + + public long readUint64() + { + return in.getLong(); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/codec/BBEncoder.java b/java/common/src/main/java/org/apache/qpid/transport/codec/BBEncoder.java new file mode 100644 index 0000000000..788b6a55e3 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/codec/BBEncoder.java @@ -0,0 +1,227 @@ +/* + * + * 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.transport.codec; + +import java.nio.BufferOverflowException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + + +/** + * BBEncoder + * + * @author Rafael H. Schloming + */ + +public final class BBEncoder extends AbstractEncoder +{ + + private ByteBuffer out; + + public BBEncoder(int capacity) { + out = ByteBuffer.allocate(capacity); + out.order(ByteOrder.BIG_ENDIAN); + } + + public void init() + { + out.clear(); + } + + public ByteBuffer done() + { + out.flip(); + ByteBuffer encoded = ByteBuffer.allocate(out.remaining()); + encoded.put(out); + encoded.flip(); + return encoded; + } + + private void grow(int size) + { + ByteBuffer old = out; + int capacity = old.capacity(); + out = ByteBuffer.allocate(Math.max(capacity + size, 2*capacity)); + out.order(ByteOrder.BIG_ENDIAN); + out.put(old); + } + + protected void doPut(byte b) + { + try + { + out.put(b); + } + catch (BufferOverflowException e) + { + grow(1); + out.put(b); + } + } + + protected void doPut(ByteBuffer src) + { + try + { + out.put(src); + } + catch (BufferOverflowException e) + { + grow(src.remaining()); + out.put(src); + } + } + + protected void put(byte[] bytes) + { + try + { + out.put(bytes); + } + catch (BufferOverflowException e) + { + grow(bytes.length); + out.put(bytes); + } + } + + public void writeUint8(short b) + { + assert b < 0x100; + + try + { + out.put((byte) b); + } + catch (BufferOverflowException e) + { + grow(1); + out.put((byte) b); + } + } + + public void writeUint16(int s) + { + assert s < 0x10000; + + try + { + out.putShort((short) s); + } + catch (BufferOverflowException e) + { + grow(2); + out.putShort((short) s); + } + } + + public void writeUint32(long i) + { + assert i < 0x100000000L; + + try + { + out.putInt((int) i); + } + catch (BufferOverflowException e) + { + grow(4); + out.putInt((int) i); + } + } + + public void writeUint64(long l) + { + try + { + out.putLong(l); + } + catch (BufferOverflowException e) + { + grow(8); + out.putLong(l); + } + } + + public int beginSize8() + { + int pos = out.position(); + try + { + out.put((byte) 0); + } + catch (BufferOverflowException e) + { + grow(1); + out.put((byte) 0); + } + return pos; + } + + public void endSize8(int pos) + { + int cur = out.position(); + out.put(pos, (byte) (cur - pos - 1)); + } + + public int beginSize16() + { + int pos = out.position(); + try + { + out.putShort((short) 0); + } + catch (BufferOverflowException e) + { + grow(2); + out.putShort((short) 0); + } + return pos; + } + + public void endSize16(int pos) + { + int cur = out.position(); + out.putShort(pos, (short) (cur - pos - 2)); + } + + public int beginSize32() + { + int pos = out.position(); + try + { + out.putInt(0); + } + catch (BufferOverflowException e) + { + grow(4); + out.putInt(0); + } + return pos; + } + + public void endSize32(int pos) + { + int cur = out.position(); + out.putInt(pos, (cur - pos - 4)); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/codec/Decoder.java b/java/common/src/main/java/org/apache/qpid/transport/codec/Decoder.java new file mode 100644 index 0000000000..50e787ccb2 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/codec/Decoder.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.transport.codec; + +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.transport.RangeSet; +import org.apache.qpid.transport.Struct; + + +/** + * Decoder + * + * @author Rafael H. Schloming + */ + +public interface Decoder +{ + + boolean hasRemaining(); + + short readUint8(); + int readUint16(); + long readUint32(); + long readUint64(); + + long readDatetime(); + UUID readUuid(); + + int readSequenceNo(); + RangeSet readSequenceSet(); // XXX + RangeSet readByteRanges(); // XXX + + String readStr8(); + String readStr16(); + + byte[] readVbin8(); + byte[] readVbin16(); + byte[] readVbin32(); + + Struct readStruct32(); + Map readMap(); + List readList(); + List readArray(); + + Struct readStruct(int type); + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/codec/Encodable.java b/java/common/src/main/java/org/apache/qpid/transport/codec/Encodable.java new file mode 100644 index 0000000000..2aefafd19c --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/codec/Encodable.java @@ -0,0 +1,37 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.transport.codec; + + +/** + * Encodable + * + * @author Rafael H. Schloming + */ + +public interface Encodable +{ + + void write(Encoder enc); + + void read(Decoder dec); + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/codec/Encoder.java b/java/common/src/main/java/org/apache/qpid/transport/codec/Encoder.java new file mode 100644 index 0000000000..2d8d13e80a --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/codec/Encoder.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.transport.codec; + +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.transport.RangeSet; +import org.apache.qpid.transport.Struct; + + +/** + * Encoder + * + * @author Rafael H. Schloming + */ + +public interface Encoder +{ + + void writeUint8(short b); + void writeUint16(int s); + void writeUint32(long i); + void writeUint64(long l); + + void writeDatetime(long l); + void writeUuid(UUID uuid); + + void writeSequenceNo(int s); + void writeSequenceSet(RangeSet ranges); // XXX + void writeByteRanges(RangeSet ranges); // XXX + + void writeStr8(String s); + void writeStr16(String s); + + void writeVbin8(byte[] bytes); + void writeVbin16(byte[] bytes); + void writeVbin32(byte[] bytes); + + void writeStruct32(Struct s); + void writeMap(Map map); + void writeList(List list); + void writeArray(List array); + + void writeStruct(int type, Struct s); + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/codec/Validator.java b/java/common/src/main/java/org/apache/qpid/transport/codec/Validator.java new file mode 100644 index 0000000000..ae12d35209 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/codec/Validator.java @@ -0,0 +1,177 @@ +/* + * + * 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.transport.codec; + +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.transport.RangeSet; +import org.apache.qpid.transport.Struct; + + +/** + * Validator + * + */ + +public class Validator +{ + + public static final void checkBit(boolean b) + { + // no illegal values + } + + public static final void checkUint8(short s) + { + if (s > 0xFF || s < 0) + { + throw new IllegalArgumentException("" + s); + } + } + + public static final void checkUint16(int i) + { + if (i > 0xFFFF || i < 0) + { + throw new IllegalArgumentException("" + i); + } + } + + public static final void checkUint32(long l) + { + // XXX: we can't currently validate this because we do thinks + // like pass in -1 for 0xFFFFFFFF + // if (l > 0xFFFFFFFFL || l < 0) + // { + // throw new IllegalArgumentException("" + l); + // } + } + + public static final void checkSequenceNo(int s) + { + // no illegal values + } + + public static final void checkUint64(long l) + { + // no illegal values + } + + public static final void checkDatetime(long l) + { + // no illegal values + } + + public static final void checkUuid(UUID u) + { + // no illegal values + } + + public static final void checkStr8(String value) + { + if (value != null && value.length() > 255) + { + throw new IllegalArgumentException("" + value); + } + } + + public static final void checkStr16(String value) + { + if (value != null && value.length() > 0xFFFF) + { + throw new IllegalArgumentException("" + value); + } + } + + public static final void checkVbin8(byte[] value) + { + if (value != null && value.length > 255) + { + throw new IllegalArgumentException("" + value); + } + } + + public static final void checkVbin16(byte[] value) + { + if (value != null && value.length > 0xFFFF) + { + throw new IllegalArgumentException("" + value); + } + } + + public static final void checkByteRanges(RangeSet r) + { + // no illegal values + } + + public static final void checkSequenceSet(RangeSet r) + { + // no illegal values + } + + public static final void checkVbin32(byte[] value) + { + // no illegal values + } + + public static final void checkStruct32(Struct s) + { + // no illegal values + } + + public static final void checkArray(List array) + { + if (array == null) + { + return; + } + + for (Object o : array) + { + checkObject(o); + } + } + + public static final void checkMap(Map map) + { + if (map == null) + { + return; + } + + for (Map.Entry entry : map.entrySet()) + { + checkStr8(entry.getKey()); + checkObject(entry.getValue()); + } + } + + public static final void checkObject(Object o) + { + if (o != null && AbstractEncoder.resolve(o.getClass()) == null) + { + throw new IllegalArgumentException("cannot encode " + o.getClass()); + } + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/Assembler.java b/java/common/src/main/java/org/apache/qpid/transport/network/Assembler.java new file mode 100644 index 0000000000..2c09776c3d --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/network/Assembler.java @@ -0,0 +1,219 @@ +/* + * + * 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.transport.network; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import java.nio.ByteBuffer; + +import org.apache.qpid.transport.codec.BBDecoder; +import org.apache.qpid.transport.codec.Decoder; + +import org.apache.qpid.transport.Data; +import org.apache.qpid.transport.Header; +import org.apache.qpid.transport.Method; +import org.apache.qpid.transport.ProtocolError; +import org.apache.qpid.transport.ProtocolEvent; +import org.apache.qpid.transport.ProtocolHeader; +import org.apache.qpid.transport.Receiver; +import org.apache.qpid.transport.SegmentType; +import org.apache.qpid.transport.Struct; + + +/** + * Assembler + * + */ + +public class Assembler implements Receiver, NetworkDelegate +{ + + private final Receiver receiver; + private final Map> segments; + private final ThreadLocal decoder = new ThreadLocal() + { + public BBDecoder initialValue() + { + return new BBDecoder(); + } + }; + + public Assembler(Receiver receiver) + { + this.receiver = receiver; + segments = new HashMap>(); + } + + private int segmentKey(Frame frame) + { + return (frame.getTrack() + 1) * frame.getChannel(); + } + + private List getSegment(Frame frame) + { + return segments.get(segmentKey(frame)); + } + + private void setSegment(Frame frame, List segment) + { + int key = segmentKey(frame); + if (segments.containsKey(key)) + { + error(new ProtocolError(Frame.L2, "segment in progress: %s", + frame)); + } + segments.put(segmentKey(frame), segment); + } + + private void clearSegment(Frame frame) + { + segments.remove(segmentKey(frame)); + } + + private void emit(int channel, ProtocolEvent event) + { + event.setChannel(channel); + receiver.received(event); + } + + private void emit(Frame frame, ProtocolEvent event) + { + emit(frame.getChannel(), event); + } + + public void received(NetworkEvent event) + { + event.delegate(this); + } + + public void exception(Throwable t) + { + this.receiver.exception(t); + } + + public void closed() + { + this.receiver.closed(); + } + + public void init(ProtocolHeader header) + { + emit(0, header); + } + + public void frame(Frame frame) + { + switch (frame.getType()) + { + case BODY: + emit(frame, new Data(frame.getBody(), frame.isFirstFrame(), + frame.isLastFrame())); + break; + default: + assemble(frame); + break; + } + } + + public void error(ProtocolError error) + { + emit(0, error); + } + + private void assemble(Frame frame) + { + ByteBuffer segment; + if (frame.isFirstFrame() && frame.isLastFrame()) + { + segment = frame.getBody(); + emit(frame, decode(frame, segment)); + } + else + { + List frames; + if (frame.isFirstFrame()) + { + frames = new ArrayList(); + setSegment(frame, frames); + } + else + { + frames = getSegment(frame); + } + + frames.add(frame); + + if (frame.isLastFrame()) + { + clearSegment(frame); + + int size = 0; + for (Frame f : frames) + { + size += f.getSize(); + } + segment = ByteBuffer.allocate(size); + for (Frame f : frames) + { + segment.put(f.getBody()); + } + segment.flip(); + emit(frame, decode(frame, segment)); + } + } + + } + + private ProtocolEvent decode(Frame frame, ByteBuffer segment) + { + BBDecoder dec = decoder.get(); + dec.init(segment); + + switch (frame.getType()) + { + case CONTROL: + int controlType = dec.readUint16(); + Method control = Method.create(controlType); + control.read(dec); + return control; + case COMMAND: + int commandType = dec.readUint16(); + // read in the session header, right now we don't use it + dec.readUint16(); + Method command = Method.create(commandType); + command.read(dec); + return command; + case HEADER: + List structs = new ArrayList(); + while (dec.hasRemaining()) + { + structs.add(dec.readStruct32()); + } + return new Header(structs, frame.isLastFrame() && frame.isLastSegment()); + default: + throw new IllegalStateException("unknown frame type: " + frame.getType()); + } + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/Disassembler.java b/java/common/src/main/java/org/apache/qpid/transport/network/Disassembler.java new file mode 100644 index 0000000000..1ed446af2f --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/network/Disassembler.java @@ -0,0 +1,217 @@ +/* + * + * 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.transport.network; + +import org.apache.qpid.transport.codec.BBEncoder; + +import org.apache.qpid.transport.Data; +import org.apache.qpid.transport.Header; +import org.apache.qpid.transport.Method; +import org.apache.qpid.transport.ProtocolDelegate; +import org.apache.qpid.transport.ProtocolError; +import org.apache.qpid.transport.ProtocolEvent; +import org.apache.qpid.transport.ProtocolHeader; +import org.apache.qpid.transport.SegmentType; +import org.apache.qpid.transport.Sender; +import org.apache.qpid.transport.Struct; + +import java.nio.ByteBuffer; +import java.util.Iterator; + +import static org.apache.qpid.transport.network.Frame.*; + +import static java.lang.Math.*; + + +/** + * Disassembler + * + */ + +public class Disassembler implements Sender, + ProtocolDelegate +{ + + private final Sender sender; + private final int maxPayload; + private final ThreadLocal encoder = new ThreadLocal() + { + public BBEncoder initialValue() + { + return new BBEncoder(4*1024); + } + }; + + public Disassembler(Sender sender, int maxFrame) + { + if (maxFrame <= HEADER_SIZE || maxFrame >= 64*1024) + { + throw new IllegalArgumentException + ("maxFrame must be > HEADER_SIZE and < 64K: " + maxFrame); + } + this.sender = sender; + this.maxPayload = maxFrame - HEADER_SIZE; + + } + + public void send(ProtocolEvent event) + { + event.delegate(null, this); + } + + public void flush() + { + sender.flush(); + } + + public void close() + { + sender.close(); + } + + private void fragment(byte flags, SegmentType type, ProtocolEvent event, + ByteBuffer buf, boolean first, boolean last) + { + byte track = event.getEncodedTrack() == Frame.L4 ? (byte) 1 : (byte) 0; + + if(!buf.hasRemaining()) + { + //empty data + byte nflags = flags; + if (first) + { + nflags |= FIRST_FRAME; + first = false; + } + nflags |= LAST_FRAME; + Frame frame = new Frame(nflags, type, track, event.getChannel(), buf.slice()); + sender.send(frame); + } + else + { + while (buf.hasRemaining()) + { + ByteBuffer slice = buf.slice(); + slice.limit(min(maxPayload, slice.remaining())); + buf.position(buf.position() + slice.remaining()); + + byte newflags = flags; + if (first) + { + newflags |= FIRST_FRAME; + first = false; + } + if (last && !buf.hasRemaining()) + { + newflags |= LAST_FRAME; + } + + Frame frame = new Frame(newflags, type, track, event.getChannel(), slice); + sender.send(frame); + } + } + } + + public void init(Void v, ProtocolHeader header) + { + sender.send(header); + } + + public void control(Void v, Method method) + { + method(method, SegmentType.CONTROL); + } + + public void command(Void v, Method method) + { + method(method, SegmentType.COMMAND); + } + + private ByteBuffer copy(ByteBuffer src) + { + ByteBuffer buf = ByteBuffer.allocate(src.remaining()); + buf.put(src); + buf.flip(); + return buf; + } + + private void method(Method method, SegmentType type) + { + BBEncoder enc = encoder.get(); + enc.init(); + enc.writeUint16(method.getEncodedType()); + if (type == SegmentType.COMMAND) + { + if (method.isSync()) + { + enc.writeUint16(0x0101); + } + else + { + enc.writeUint16(0x0100); + } + } + method.write(enc); + ByteBuffer buf = enc.done(); + + byte flags = FIRST_SEG; + + if (!method.hasPayload()) + { + flags |= LAST_SEG; + } + + fragment(flags, type, method, buf, true, true); + } + + public void header(Void v, Header header) + { + ByteBuffer buf; + if (header.getBuf() == null) + { + BBEncoder enc = encoder.get(); + enc.init(); + for (Struct st : header.getStructs()) + { + enc.writeStruct32(st); + } + buf = enc.done(); + header.setBuf(buf); + } + else + { + buf = header.getBuf(); + buf.flip(); + } + fragment((byte) 0x0, SegmentType.HEADER, header, buf, true, true); + } + + public void data(Void v, Data data) + { + fragment(LAST_SEG, SegmentType.BODY, data, data.getData(), data.isFirst(), data.isLast()); + } + + public void error(Void v, ProtocolError error) + { + sender.send(error); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/Frame.java b/java/common/src/main/java/org/apache/qpid/transport/network/Frame.java new file mode 100644 index 0000000000..849355276e --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/network/Frame.java @@ -0,0 +1,151 @@ +/* + * + * 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.transport.network; + +import org.apache.qpid.transport.SegmentType; +import org.apache.qpid.transport.util.SliceIterator; + +import java.nio.ByteBuffer; + +import java.util.ArrayList; +import java.util.List; +import java.util.Iterator; + +import static org.apache.qpid.transport.util.Functions.*; + + +/** + * Frame + * + * @author Rafael H. Schloming + */ + +public final class Frame implements NetworkEvent +{ + public static final int HEADER_SIZE = 12; + + // XXX: enums? + public static final byte L1 = 0; + public static final byte L2 = 1; + public static final byte L3 = 2; + public static final byte L4 = 3; + + public static final byte RESERVED = 0x0; + + public static final byte VERSION = 0x0; + + public static final byte FIRST_SEG = 0x8; + public static final byte LAST_SEG = 0x4; + public static final byte FIRST_FRAME = 0x2; + public static final byte LAST_FRAME = 0x1; + + final private byte flags; + final private SegmentType type; + final private byte track; + final private int channel; + final private ByteBuffer body; + + public Frame(byte flags, SegmentType type, byte track, int channel, + ByteBuffer body) + { + this.flags = flags; + this.type = type; + this.track = track; + this.channel = channel; + this.body = body; + } + + public ByteBuffer getBody() + { + return body.slice(); + } + + public byte getFlags() + { + return flags; + } + + public int getChannel() + { + return channel; + } + + public int getSize() + { + return body.remaining(); + } + + public SegmentType getType() + { + return type; + } + + public byte getTrack() + { + return track; + } + + private boolean flag(byte mask) + { + return (flags & mask) != 0; + } + + public boolean isFirstSegment() + { + return flag(FIRST_SEG); + } + + public boolean isLastSegment() + { + return flag(LAST_SEG); + } + + public boolean isFirstFrame() + { + return flag(FIRST_FRAME); + } + + public boolean isLastFrame() + { + return flag(LAST_FRAME); + } + + public void delegate(NetworkDelegate delegate) + { + delegate.frame(this); + } + + public String toString() + { + StringBuilder str = new StringBuilder(); + + str.append(String.format + ("[%05d %05d %1d %s %d%d%d%d] ", getChannel(), getSize(), + getTrack(), getType(), + isFirstSegment() ? 1 : 0, isLastSegment() ? 1 : 0, + isFirstFrame() ? 1 : 0, isLastFrame() ? 1 : 0)); + + str.append(str(body)); + + return str.toString(); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/InputHandler.java b/java/common/src/main/java/org/apache/qpid/transport/network/InputHandler.java new file mode 100644 index 0000000000..408c95e075 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/network/InputHandler.java @@ -0,0 +1,204 @@ +/* + * + * 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.transport.network; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import org.apache.qpid.transport.ProtocolError; +import org.apache.qpid.transport.ProtocolHeader; +import org.apache.qpid.transport.Receiver; +import org.apache.qpid.transport.SegmentType; + +import static org.apache.qpid.transport.util.Functions.*; + +import static org.apache.qpid.transport.network.InputHandler.State.*; + + +/** + * InputHandler + * + * @author Rafael H. Schloming + */ + +public final class InputHandler implements Receiver +{ + + public enum State + { + PROTO_HDR, + FRAME_HDR, + FRAME_BODY, + ERROR; + } + + private final Receiver receiver; + private State state; + private ByteBuffer input = null; + private int needed; + + private byte flags; + private SegmentType type; + private byte track; + private int channel; + + public InputHandler(Receiver receiver, State state) + { + this.receiver = receiver; + this.state = state; + + switch (state) + { + case PROTO_HDR: + needed = 8; + break; + case FRAME_HDR: + needed = Frame.HEADER_SIZE; + break; + } + } + + public InputHandler(Receiver receiver) + { + this(receiver, PROTO_HDR); + } + + private void error(String fmt, Object ... args) + { + receiver.received(new ProtocolError(Frame.L1, fmt, args)); + } + + public void received(ByteBuffer buf) + { + int limit = buf.limit(); + int remaining = buf.remaining(); + while (remaining > 0) + { + if (remaining >= needed) + { + int consumed = needed; + int pos = buf.position(); + if (input == null) + { + buf.limit(pos + needed); + input = buf; + state = next(pos); + buf.limit(limit); + buf.position(pos + consumed); + } + else + { + buf.limit(pos + needed); + input.put(buf); + buf.limit(limit); + input.flip(); + state = next(0); + } + + remaining -= consumed; + input = null; + } + else + { + if (input == null) + { + input = ByteBuffer.allocate(needed); + } + input.put(buf); + needed -= remaining; + remaining = 0; + } + } + } + + private State next(int pos) + { + input.order(ByteOrder.BIG_ENDIAN); + + switch (state) { + case PROTO_HDR: + if (input.get(pos) != 'A' && + input.get(pos + 1) != 'M' && + input.get(pos + 2) != 'Q' && + input.get(pos + 3) != 'P') + { + error("bad protocol header: %s", str(input)); + return ERROR; + } + + byte instance = input.get(pos + 5); + byte major = input.get(pos + 6); + byte minor = input.get(pos + 7); + receiver.received(new ProtocolHeader(instance, major, minor)); + needed = Frame.HEADER_SIZE; + return FRAME_HDR; + case FRAME_HDR: + flags = input.get(pos); + type = SegmentType.get(input.get(pos + 1)); + int size = (0xFFFF & input.getShort(pos + 2)); + size -= Frame.HEADER_SIZE; + if (size < 0 || size > (64*1024 - 12)) + { + error("bad frame size: %d", size); + return ERROR; + } + byte b = input.get(pos + 5); + if ((b & 0xF0) != 0) { + error("non-zero reserved bits in upper nibble of " + + "frame header byte 5: '%x'", b); + return ERROR; + } else { + track = (byte) (b & 0xF); + } + channel = (0xFFFF & input.getShort(pos + 6)); + if (size == 0) + { + Frame frame = new Frame(flags, type, track, channel, ByteBuffer.allocate(0)); + receiver.received(frame); + needed = Frame.HEADER_SIZE; + return FRAME_HDR; + } + else + { + needed = size; + return FRAME_BODY; + } + case FRAME_BODY: + Frame frame = new Frame(flags, type, track, channel, input.slice()); + receiver.received(frame); + needed = Frame.HEADER_SIZE; + return FRAME_HDR; + default: + throw new IllegalStateException(); + } + } + + public void exception(Throwable t) + { + receiver.exception(t); + } + + public void closed() + { + receiver.closed(); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/NetworkDelegate.java b/java/common/src/main/java/org/apache/qpid/transport/network/NetworkDelegate.java new file mode 100644 index 0000000000..fbdfe6e84c --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/network/NetworkDelegate.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.transport.network; + +import org.apache.qpid.transport.ProtocolError; +import org.apache.qpid.transport.ProtocolHeader; + + +/** + * NetworkDelegate + * + * @author Rafael H. Schloming + */ + +public interface NetworkDelegate +{ + + void init(ProtocolHeader header); + + void frame(Frame frame); + + void error(ProtocolError error); + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/NetworkEvent.java b/java/common/src/main/java/org/apache/qpid/transport/network/NetworkEvent.java new file mode 100644 index 0000000000..91314cd4ad --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/network/NetworkEvent.java @@ -0,0 +1,34 @@ +/* + * + * 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.transport.network; + + +/** + * NetworkEvent + * + */ + +public interface NetworkEvent +{ + + void delegate(NetworkDelegate delegate); + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/OutputHandler.java b/java/common/src/main/java/org/apache/qpid/transport/network/OutputHandler.java new file mode 100644 index 0000000000..b3f400a6e7 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/network/OutputHandler.java @@ -0,0 +1,125 @@ +/* + * + * 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.transport.network; + +import java.nio.ByteBuffer; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.qpid.transport.Constant; +import org.apache.qpid.transport.ProtocolError; +import org.apache.qpid.transport.ProtocolHeader; +import org.apache.qpid.transport.Sender; + +import static org.apache.qpid.transport.network.Frame.*; + + +/** + * OutputHandler + * + */ + +public class OutputHandler implements Sender, NetworkDelegate +{ + + private Sender sender; + private Object lock = new Object(); + private int bytes = 0; + private List frames = new ArrayList(); + + public OutputHandler(Sender sender) + { + this.sender = sender; + } + + public void send(NetworkEvent event) + { + event.delegate(this); + } + + public void close() + { + synchronized (lock) + { + sender.close(); + } + } + + public void init(ProtocolHeader header) + { + synchronized (lock) + { + sender.send(header.toByteBuffer()); + sender.flush(); + } + } + + public void frame(Frame frame) + { + synchronized (lock) + { + frames.add(frame); + bytes += HEADER_SIZE + frame.getSize(); + + if (bytes > 64*1024) + { + flush(); + } + } + } + + public void flush() + { + synchronized (lock) + { + ByteBuffer buf = ByteBuffer.allocate(bytes); + int nframes = frames.size(); + for (int i = 0; i < nframes; i++) + { + Frame frame = frames.get(i); + buf.put(frame.getFlags()); + buf.put((byte) frame.getType().getValue()); + buf.putShort((short) (frame.getSize() + HEADER_SIZE)); + // RESERVED + buf.put(RESERVED); + buf.put(frame.getTrack()); + buf.putShort((short) frame.getChannel()); + // RESERVED + buf.putInt(0); + buf.put(frame.getBody()); + } + buf.flip(); + + frames.clear(); + bytes = 0; + + sender.send(buf); + sender.flush(); + } + } + + public void error(ProtocolError error) + { + throw new IllegalStateException("XXX"); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/io/IoReceiver.java b/java/common/src/main/java/org/apache/qpid/transport/network/io/IoReceiver.java new file mode 100644 index 0000000000..5e64bdfba1 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/network/io/IoReceiver.java @@ -0,0 +1,106 @@ +/* + * + * 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.transport.network.io; + +import org.apache.qpid.transport.Receiver; +import org.apache.qpid.transport.TransportException; +import org.apache.qpid.transport.util.Logger; + +import java.io.InputStream; +import java.io.IOException; +import java.net.Socket; +import java.nio.ByteBuffer; + +/** + * IoReceiver + * + */ + +final class IoReceiver extends Thread +{ + + private static final Logger log = Logger.get(IoReceiver.class); + + private final IoTransport transport; + private final Receiver receiver; + private final int bufferSize; + private final Socket socket; + + public IoReceiver(IoTransport transport, Receiver receiver, int bufferSize) + { + this.transport = transport; + this.receiver = receiver; + this.bufferSize = bufferSize; + this.socket = transport.getSocket(); + + setName(String.format("IoReceive - %s", socket.getRemoteSocketAddress())); + start(); + } + + public void run() + { + final int threshold = bufferSize / 2; + + // I set the read buffer size simillar to SO_RCVBUF + // Haven't tested with a lower value to see if it's better or worse + byte[] buffer = new byte[bufferSize]; + try + { + InputStream in = socket.getInputStream(); + int read = 0; + int offset = 0; + while ((read = in.read(buffer, offset, bufferSize-offset)) != -1) + { + if (read > 0) + { + ByteBuffer b = ByteBuffer.wrap(buffer,offset,read); + receiver.received(b); + offset+=read; + if (offset > threshold) + { + offset = 0; + buffer = new byte[bufferSize]; + } + } + } + } + catch (Throwable t) + { + receiver.exception(new TransportException("error in read thread", t)); + } + finally + { + try + { + transport.getSender().close(); + } + catch (TransportException e) + { + log.error(e, "error closing"); + } + finally + { + receiver.closed(); + } + } + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/io/IoSender.java b/java/common/src/main/java/org/apache/qpid/transport/network/io/IoSender.java new file mode 100644 index 0000000000..591b4bba3e --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/network/io/IoSender.java @@ -0,0 +1,262 @@ +/* + * 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.transport.network.io; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; + +import org.apache.qpid.transport.Sender; +import org.apache.qpid.transport.TransportException; +import org.apache.qpid.transport.util.Logger; + +import static org.apache.qpid.transport.util.Functions.*; + + +final class IoSender extends Thread implements Sender +{ + + private static final Logger log = Logger.get(IoSender.class); + + // by starting here, we ensure that we always test the wraparound + // case, we should probably make this configurable somehow so that + // we can test other cases as well + private final static int START = Integer.MAX_VALUE - 10; + + private final IoTransport transport; + private final long timeout; + private final Socket socket; + private final OutputStream out; + + private final byte[] buffer; + private final AtomicInteger head = new AtomicInteger(START); + private final AtomicInteger tail = new AtomicInteger(START); + private final Object notFull = new Object(); + private final Object notEmpty = new Object(); + private final AtomicBoolean closed = new AtomicBoolean(false); + + private IOException exception = null; + + + public IoSender(IoTransport transport, int bufferSize, long timeout) + { + this.transport = transport; + this.socket = transport.getSocket(); + this.buffer = new byte[bufferSize]; + this.timeout = timeout; + + try + { + out = socket.getOutputStream(); + } + catch (IOException e) + { + throw new TransportException("Error getting output stream for socket", e); + } + + setName(String.format("IoSender - %s", socket.getRemoteSocketAddress())); + start(); + } + + private static final int mod(int n, int m) + { + int r = n % m; + return r < 0 ? m + r : r; + } + + public void send(ByteBuffer buf) + { + if (closed.get()) + { + throw new TransportException("sender is closed", exception); + } + + final int size = buffer.length; + int remaining = buf.remaining(); + + while (remaining > 0) + { + final int hd = head.get(); + final int tl = tail.get(); + + if (hd - tl >= size) + { + synchronized (notFull) + { + long start = System.currentTimeMillis(); + long elapsed = 0; + while (head.get() - tail.get() >= size && elapsed < timeout) + { + try + { + notFull.wait(timeout - elapsed); + } + catch (InterruptedException e) + { + // pass + } + elapsed += System.currentTimeMillis() - start; + } + + if (head.get() - tail.get() >= size) + { + throw new TransportException(String.format("write timed out: %s, %s", head.get(), tail.get())); + } + } + continue; + } + + final int hd_idx = mod(hd, size); + final int tl_idx = mod(tl, size); + final int length; + + if (tl_idx > hd_idx) + { + length = Math.min(tl_idx - hd_idx, remaining); + } + else + { + length = Math.min(size - hd_idx, remaining); + } + + buf.get(buffer, hd_idx, length); + head.getAndAdd(length); + if (hd == tail.get()) + { + synchronized (notEmpty) + { + notEmpty.notify(); + } + } + remaining -= length; + } + } + + public void flush() + { + // pass + } + + public void close() + { + if (!closed.getAndSet(true)) + { + synchronized (notEmpty) + { + notEmpty.notify(); + } + + try + { + join(timeout); + if (isAlive()) + { + throw new TransportException("join timed out"); + } + socket.close(); + } + catch (InterruptedException e) + { + throw new TransportException(e); + } + catch (IOException e) + { + throw new TransportException(e); + } + + if (exception != null) + { + throw new TransportException(exception); + } + } + } + + public void run() + { + final int size = buffer.length; + + while (true) + { + final int hd = head.get(); + final int tl = tail.get(); + + if (hd == tl) + { + if (closed.get()) + { + break; + } + + synchronized (notEmpty) + { + while (head.get() == tail.get() && !closed.get()) + { + try + { + notEmpty.wait(); + } + catch (InterruptedException e) + { + // pass + } + } + } + + continue; + } + + final int hd_idx = mod(hd, size); + final int tl_idx = mod(tl, size); + + final int length; + if (tl_idx < hd_idx) + { + length = hd_idx - tl_idx; + } + else + { + length = size - tl_idx; + } + + try + { + out.write(buffer, tl_idx, length); + } + catch (IOException e) + { + log.error(e, "error in write thread"); + exception = e; + break; + } + tail.getAndAdd(length); + if (head.get() - tl >= size) + { + synchronized (notFull) + { + notFull.notify(); + } + } + } + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/io/IoTransport.java b/java/common/src/main/java/org/apache/qpid/transport/network/io/IoTransport.java new file mode 100644 index 0000000000..2f05cf5e55 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/network/io/IoTransport.java @@ -0,0 +1,129 @@ +/* + * 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.transport.network.io; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketException; +import java.nio.ByteBuffer; + +import org.apache.qpid.transport.Connection; +import org.apache.qpid.transport.ConnectionDelegate; +import org.apache.qpid.transport.Receiver; +import org.apache.qpid.transport.TransportException; +import org.apache.qpid.transport.network.Assembler; +import org.apache.qpid.transport.network.Disassembler; +import org.apache.qpid.transport.network.InputHandler; +import org.apache.qpid.transport.network.OutputHandler; +import org.apache.qpid.transport.util.Logger; + +/** + * This class provides a socket based transport using the java.io + * classes. + * + * The following params are configurable via JVM arguments + * TCP_NO_DELAY - amqj.tcpNoDelay + * SO_RCVBUF - amqj.receiveBufferSize + * SO_SNDBUF - amqj.sendBufferSize + */ +public final class IoTransport +{ + + private static final Logger log = Logger.get(IoTransport.class); + + private static int DEFAULT_READ_WRITE_BUFFER_SIZE = 64 * 1024; + + private IoReceiver receiver; + private IoSender sender; + private Socket socket; + private int readBufferSize; + private int writeBufferSize; + private final long timeout = 60000; + + private IoTransport() + { + readBufferSize = Integer.getInteger("amqj.receiveBufferSize",DEFAULT_READ_WRITE_BUFFER_SIZE); + writeBufferSize = Integer.getInteger("amqj.sendBufferSize",DEFAULT_READ_WRITE_BUFFER_SIZE); + } + + public static final Connection connect(String host, int port, + ConnectionDelegate delegate) + { + IoTransport handler = new IoTransport(); + return handler.connectInternal(host,port,delegate); + } + + private Connection connectInternal(String host, int port, + ConnectionDelegate delegate) + { + try + { + InetAddress address = InetAddress.getByName(host); + socket = new Socket(); + socket.setReuseAddress(true); + socket.setTcpNoDelay(Boolean.getBoolean("amqj.tcpNoDelay")); + + log.debug("default-SO_RCVBUF : %s", socket.getReceiveBufferSize()); + log.debug("default-SO_SNDBUF : %s", socket.getSendBufferSize()); + + socket.setSendBufferSize(writeBufferSize); + socket.setReceiveBufferSize(readBufferSize); + + log.debug("new-SO_RCVBUF : %s", socket.getReceiveBufferSize()); + log.debug("new-SO_SNDBUF : %s", socket.getSendBufferSize()); + + socket.connect(new InetSocketAddress(address, port)); + } + catch (SocketException e) + { + throw new TransportException("Error connecting to broker", e); + } + catch (IOException e) + { + throw new TransportException("Error connecting to broker", e); + } + + sender = new IoSender(this, 2*writeBufferSize, timeout); + Connection conn = new Connection + (new Disassembler(new OutputHandler(sender), 64*1024 - 1), + delegate); + receiver = new IoReceiver(this, new InputHandler(new Assembler(conn)), 2*readBufferSize); + + return conn; + } + + IoSender getSender() + { + return sender; + } + + IoReceiver getReceiver() + { + return receiver; + } + + Socket getSocket() + { + return socket; + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaHandler.java b/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaHandler.java new file mode 100644 index 0000000000..bcac7c4e16 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaHandler.java @@ -0,0 +1,305 @@ +/* + * + * 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.transport.network.mina; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.SocketAddress; + +import org.apache.mina.common.*; + +import org.apache.mina.transport.socket.nio.SocketAcceptor; +import org.apache.mina.transport.socket.nio.SocketSessionConfig; +import org.apache.mina.transport.socket.nio.SocketConnector; +import org.apache.mina.filter.ReadThrottleFilterBuilder; +import org.apache.mina.filter.WriteBufferLimitFilterBuilder; +import org.apache.mina.filter.executor.ExecutorFilter; + +import org.apache.qpid.transport.Binding; +import org.apache.qpid.transport.Connection; +import org.apache.qpid.transport.ConnectionDelegate; +import org.apache.qpid.transport.Receiver; +import org.apache.qpid.transport.Sender; + +import org.apache.qpid.transport.util.Logger; + +import org.apache.qpid.transport.network.Assembler; +import org.apache.qpid.transport.network.Disassembler; +import org.apache.qpid.transport.network.InputHandler; +import org.apache.qpid.transport.network.OutputHandler; + +import static org.apache.qpid.transport.util.Functions.*; + +/** + * MinaHandler + * + * @author Rafael H. Schloming + */ +//RA making this public until we sort out the package issues +public class MinaHandler implements IoHandler +{ + private static final int MAX_FRAME_SIZE = 64 * 1024 - 1; + /** Default buffer size for pending messages reads */ + private static final String DEFAULT_READ_BUFFER_LIMIT = "262144"; + /** Default buffer size for pending messages writes */ + private static final String DEFAULT_WRITE_BUFFER_LIMIT = "262144"; + private static final int MAX_RCVBUF = 64*1024; + + private static final Logger log = Logger.get(MinaHandler.class); + + static + { + ByteBuffer.setAllocator(new SimpleByteBufferAllocator()); + ByteBuffer.setUseDirectBuffers(Boolean.getBoolean("amqj.enableDirectBuffers")); + } + + private final Binding binding; + + private MinaHandler(Binding binding) + { + this.binding = binding; + } + + public void messageReceived(IoSession ssn, Object obj) + { + Attachment attachment = (Attachment) ssn.getAttachment(); + ByteBuffer buf = (ByteBuffer) obj; + try + { + attachment.receiver.received(buf.buf()); + } + catch (Throwable t) + { + log.error(t, "exception handling buffer %s", str(buf.buf())); + throw new RuntimeException(t); + } + } + + public void messageSent(IoSession ssn, Object obj) + { + // do nothing + } + + public void exceptionCaught(IoSession ssn, Throwable e) + { + Attachment attachment = (Attachment) ssn.getAttachment(); + attachment.receiver.exception(e); + } + + /** + * Invoked by MINA when a MINA session for a new connection is created. This method sets up the filter chain on the + * session, which filters the events handled by this handler. The filter chain consists of, handing off events + * to an optional protectio + * + * @param session The MINA session. + * @throws Exception Any underlying exceptions are allowed to fall through to MINA. + */ + public void sessionCreated(IoSession session) throws Exception + { + log.debug("Protocol session created for session " + System.identityHashCode(session)); + + if (Boolean.getBoolean("protectio")) + { + try + { + //Add IO Protection Filters + IoFilterChain chain = session.getFilterChain(); + + session.getFilterChain().addLast("tempExecutorFilterForFilterBuilder", new ExecutorFilter()); + + ReadThrottleFilterBuilder readfilter = new ReadThrottleFilterBuilder(); + readfilter.setMaximumConnectionBufferSize( + Integer.parseInt(System.getProperty("qpid.read.buffer.limit", DEFAULT_READ_BUFFER_LIMIT))); + readfilter.attach(chain); + + WriteBufferLimitFilterBuilder writefilter = new WriteBufferLimitFilterBuilder(); + writefilter.setMaximumConnectionBufferSize( + Integer.parseInt(System.getProperty("qpid.write.buffer.limit", DEFAULT_WRITE_BUFFER_LIMIT))); + writefilter.attach(chain); + session.getFilterChain().remove("tempExecutorFilterForFilterBuilder"); + + log.info("Using IO Read/Write Filter Protection"); + } + catch (Exception e) + { + log.error("Unable to attach IO Read/Write Filter Protection :" + e.getMessage()); + } + } + } + + public void sessionOpened(final IoSession ssn) + { + log.debug("opened: %s", this); + E endpoint = binding.endpoint(new MinaSender(ssn)); + Attachment attachment = + new Attachment(endpoint, binding.receiver(endpoint)); + + // We need to synchronize and notify here because the MINA + // connect future returns the session prior to the attachment + // being set. This is arguably a bug in MINA. + synchronized (ssn) + { + ssn.setAttachment(attachment); + ssn.notifyAll(); + } + } + + public void sessionClosed(IoSession ssn) + { + log.debug("closed: %s", ssn); + Attachment attachment = (Attachment) ssn.getAttachment(); + attachment.receiver.closed(); + ssn.setAttachment(null); + } + + public void sessionIdle(IoSession ssn, IdleStatus status) + { + // do nothing + } + + private static class Attachment + { + + E endpoint; + Receiver receiver; + + Attachment(E endpoint, Receiver receiver) + { + this.endpoint = endpoint; + this.receiver = receiver; + } + } + + public static final void accept(String host, int port, + Binding binding) + throws IOException + { + accept(new InetSocketAddress(host, port), binding); + } + + public static final void accept(SocketAddress address, + Binding binding) + throws IOException + { + IoAcceptor acceptor = new SocketAcceptor(); + acceptor.bind(address, new MinaHandler(binding)); + } + + public static final E connect(String host, int port, + Binding binding) + { + return connect(new InetSocketAddress(host, port), binding); + } + + public static final E connect(SocketAddress address, + Binding binding) + { + MinaHandler handler = new MinaHandler(binding); + SocketConnector connector = new SocketConnector(); + IoServiceConfig acceptorConfig = connector.getDefaultConfig(); + acceptorConfig.setThreadModel(ThreadModel.MANUAL); + SocketSessionConfig scfg = (SocketSessionConfig) acceptorConfig.getSessionConfig(); + scfg.setTcpNoDelay(Boolean.getBoolean("amqj.tcpNoDelay")); + Integer sendBufferSize = Integer.getInteger("amqj.sendBufferSize"); + if (sendBufferSize != null && sendBufferSize > 0) + { + scfg.setSendBufferSize(sendBufferSize); + } + Integer receiveBufferSize = Integer.getInteger("amqj.receiveBufferSize"); + if (receiveBufferSize != null && receiveBufferSize > 0) + { + scfg.setReceiveBufferSize(receiveBufferSize); + } + else if (scfg.getReceiveBufferSize() > MAX_RCVBUF) + { + scfg.setReceiveBufferSize(MAX_RCVBUF); + } + connector.setWorkerTimeout(0); + ConnectFuture cf = connector.connect(address, handler); + cf.join(); + IoSession ssn = cf.getSession(); + + // We need to synchronize and wait here because the MINA + // connect future returns the session prior to the attachment + // being set. This is arguably a bug in MINA. + synchronized (ssn) + { + while (ssn.getAttachment() == null) + { + try + { + ssn.wait(); + } + catch (InterruptedException e) + { + throw new RuntimeException(e); + } + } + } + + Attachment attachment = (Attachment) ssn.getAttachment(); + return attachment.endpoint; + } + + public static final void accept(String host, int port, + ConnectionDelegate delegate) + throws IOException + { + accept(host, port, new ConnectionBinding + (delegate, InputHandler.State.PROTO_HDR)); + } + + public static final Connection connect(String host, int port, + ConnectionDelegate delegate) + { + return connect(host, port, new ConnectionBinding + (delegate, InputHandler.State.PROTO_HDR)); + } + + private static class ConnectionBinding + implements Binding + { + + private final ConnectionDelegate delegate; + private final InputHandler.State state; + + ConnectionBinding(ConnectionDelegate delegate, + InputHandler.State state) + { + this.delegate = delegate; + this.state = state; + } + + public Connection endpoint(Sender sender) + { + // XXX: hardcoded max-frame + return new Connection + (new Disassembler(new OutputHandler(sender), MAX_FRAME_SIZE), delegate); + } + + public Receiver receiver(Connection conn) + { + return new InputHandler(new Assembler(conn), state); + } + + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaSender.java b/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaSender.java new file mode 100644 index 0000000000..69d4061e0c --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaSender.java @@ -0,0 +1,81 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.transport.network.mina; + +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.CloseFuture; +import org.apache.mina.common.IoSession; +import org.apache.mina.common.WriteFuture; + +import org.apache.qpid.transport.Sender; +import org.apache.qpid.transport.TransportException; + + +/** + * MinaSender + */ + +public class MinaSender implements Sender +{ + private static final int TIMEOUT = 2 * 60 * 1000; + + private final IoSession session; + private WriteFuture lastWrite = null; + + public MinaSender(IoSession session) + { + this.session = session; + } + + public void send(java.nio.ByteBuffer buf) + { + if (session.isClosing()) + { + throw new TransportException("attempted to write to a closed socket"); + } + + synchronized (this) + { + lastWrite = session.write(ByteBuffer.wrap(buf)); + } + } + + public void flush() + { + // pass + } + + public synchronized void close() + { + // MINA will sometimes throw away in-progress writes when you + // ask it to close + synchronized (this) + { + if (lastWrite != null) + { + lastWrite.join(); + } + } + CloseFuture closed = session.close(); + closed.join(); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/nio/NioHandler.java b/java/common/src/main/java/org/apache/qpid/transport/network/nio/NioHandler.java new file mode 100644 index 0000000000..f0161efe97 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/network/nio/NioHandler.java @@ -0,0 +1,120 @@ +package org.apache.qpid.transport.network.nio; + +import java.io.EOFException; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.net.SocketException; +import java.nio.ByteBuffer; +import java.nio.channels.SocketChannel; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.qpid.transport.Connection; +import org.apache.qpid.transport.ConnectionDelegate; +import org.apache.qpid.transport.Receiver; +import org.apache.qpid.transport.network.Assembler; +import org.apache.qpid.transport.network.Disassembler; +import org.apache.qpid.transport.network.InputHandler; +import org.apache.qpid.transport.network.OutputHandler; + +public class NioHandler implements Runnable +{ + private Receiver _receiver; + private SocketChannel _ch; + private ByteBuffer _readBuf; + private static Map _handlers = new ConcurrentHashMap(); + private AtomicInteger _count = new AtomicInteger(); + + private NioHandler(){} + + public static final Connection connect(String host, int port, + ConnectionDelegate delegate) + { + NioHandler handler = new NioHandler(); + return handler.connectInternal(host,port,delegate); + } + + private Connection connectInternal(String host, int port, + ConnectionDelegate delegate) + { + try + { + SocketAddress address = new InetSocketAddress(host,port); + _ch = SocketChannel.open(); + _ch.socket().setReuseAddress(true); + _ch.configureBlocking(true); + _ch.socket().setTcpNoDelay(true); + if (address != null) + { + _ch.socket().connect(address); + } + while (_ch.isConnectionPending()) + { + + } + + } + catch (SocketException e) + { + + e.printStackTrace(); + } + catch (IOException e) + { + e.printStackTrace(); + } + + NioSender sender = new NioSender(_ch); + Connection con = new Connection + (new Disassembler(new OutputHandler(sender), 64*1024 - 1), + delegate); + + con.setConnectionId(_count.incrementAndGet()); + _handlers.put(con.getConnectionId(),sender); + + _receiver = new InputHandler(new Assembler(con), InputHandler.State.FRAME_HDR); + + Thread t = new Thread(this); + t.start(); + + return con; + } + + public void run() + { + _readBuf = ByteBuffer.allocate(512); + long read = 0; + while(_ch.isConnected() && _ch.isOpen()) + { + try + { + read = _ch.read(_readBuf); + if (read > 0) + { + _readBuf.flip(); + ByteBuffer b = ByteBuffer.allocate(_readBuf.remaining()); + b.put(_readBuf); + b.flip(); + _readBuf.clear(); + _receiver.received(b); + } + } + catch(Exception e) + { + e.printStackTrace(); + } + } + + //throw new EOFException("The underlying socket/channel has closed"); + } + + public static void startBatchingFrames(int connectionId) + { + NioSender sender = _handlers.get(connectionId); + sender.setStartBatching(); + } + + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/nio/NioSender.java b/java/common/src/main/java/org/apache/qpid/transport/network/nio/NioSender.java new file mode 100644 index 0000000000..33e888cc56 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/network/nio/NioSender.java @@ -0,0 +1,100 @@ +package org.apache.qpid.transport.network.nio; + +import java.nio.ByteBuffer; +import java.nio.channels.SocketChannel; + +import org.apache.qpid.transport.Sender; + +public class NioSender implements Sender +{ + private final Object lock = new Object(); + private SocketChannel _ch; + private boolean _batch = false; + private ByteBuffer _batcher; + + public NioSender(SocketChannel ch) + { + this._ch = ch; + } + + public void send(java.nio.ByteBuffer buf) + { + if (_batch) + { + //System.out.println(_batcher.position() + " , " + buf.remaining() + " , " + buf.position() + ","+_batcher.capacity()); + if (_batcher.position() + buf.remaining() >= _batcher.capacity()) + { + _batcher.flip(); + write(_batcher); + _batcher.clear(); + if (buf.remaining() > _batcher.capacity()) + { + write(buf); + } + else + { + _batcher.put(buf); + } + } + else + { + _batcher.put(buf); + } + } + else + { + write(buf); + } + } + + public void flush() + { + // pass + } + + private void write(java.nio.ByteBuffer buf) + { + synchronized (lock) + { + if( _ch.isConnected() && _ch.isOpen()) + { + try + { + _ch.write(buf); + } + catch(Exception e) + { + e.fillInStackTrace(); + } + } + else + { + throw new RuntimeException("Trying to write on a closed socket"); + } + + } + } + + public void setStartBatching() + { + _batch = true; + _batcher = ByteBuffer.allocate(1024); + } + + public void close() + { + // MINA will sometimes throw away in-progress writes when you + // ask it to close + synchronized (lock) + { + try + { + _ch.close(); + } + catch(Exception e) + { + e.printStackTrace(); + } + } + } +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/util/Functions.java b/java/common/src/main/java/org/apache/qpid/transport/util/Functions.java new file mode 100644 index 0000000000..2c6984e302 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/util/Functions.java @@ -0,0 +1,91 @@ +/* + * + * 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.transport.util; + +import java.nio.ByteBuffer; + +import static java.lang.Math.*; + + +/** + * Functions + * + * @author Rafael H. Schloming + */ + +public class Functions +{ + + public static final byte lsb(int i) + { + return (byte) (0xFF & i); + } + + public static final byte lsb(long l) + { + return (byte) (0xFF & l); + } + + public static final String str(ByteBuffer buf) + { + return str(buf, buf.remaining()); + } + + public static final String str(ByteBuffer buf, int limit) + { + StringBuilder str = new StringBuilder(); + str.append('"'); + + for (int i = 0; i < min(buf.remaining(), limit); i++) + { + byte c = buf.get(buf.position() + i); + + if (c > 31 && c < 127 && c != '\\') + { + str.append((char)c); + } + else + { + str.append(String.format("\\x%02x", c)); + } + } + + str.append('"'); + + if (limit < buf.remaining()) + { + str.append("..."); + } + + return str.toString(); + } + + public static final String str(byte[] bytes) + { + return str(ByteBuffer.wrap(bytes)); + } + + public static final String str(byte[] bytes, int limit) + { + return str(ByteBuffer.wrap(bytes), limit); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/util/Logger.java b/java/common/src/main/java/org/apache/qpid/transport/util/Logger.java new file mode 100644 index 0000000000..77f592b6c6 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/util/Logger.java @@ -0,0 +1,125 @@ +/* + * + * 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.transport.util; + +import org.slf4j.LoggerFactory; + +/** + * Logger + * + */ + +public final class Logger +{ + + public static final Logger get(Class klass) + { + return new Logger(LoggerFactory.getLogger(klass)); + } + + private final org.slf4j.Logger log; + + private Logger(org.slf4j.Logger log) + { + this.log = log; + } + + public void debug(String message, Object ... args) + { + if (log.isDebugEnabled()) + { + log.debug(String.format(message, args)); + } + } + + public void debug(Throwable t, String message, Object ... args) + { + if (log.isDebugEnabled()) + { + log.debug(String.format(message, args), t); + } + } + + public void error(String message, Object ... args) + { + if (log.isErrorEnabled()) + { + log.error(String.format(message, args)); + } + } + + public void error(Throwable t, String message, Object ... args) + { + if (log.isErrorEnabled()) + { + log.error(String.format(message, args), t); + } + } + + public void warn(String message, Object ... args) + { + if (log.isWarnEnabled()) + { + log.warn(String.format(message, args)); + } + } + + public void warn(Throwable t, String message, Object ... args) + { + if (log.isWarnEnabled()) + { + log.warn(String.format(message, args), t); + } + } + + public void info(String message, Object ... args) + { + if (log.isInfoEnabled()) + { + log.info(String.format(message, args)); + } + } + + public void info(Throwable t, String message, Object ... args) + { + if (log.isInfoEnabled()) + { + log.info(String.format(message, args), t); + } + } + + public void trace(String message, Object ... args) + { + if (log.isTraceEnabled()) + { + log.trace(String.format(message, args)); + } + } + + public void trace(Throwable t, String message, Object ... args) + { + if (log.isTraceEnabled()) + { + log.trace(String.format(message, args), t); + } + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/transport/util/SliceIterator.java b/java/common/src/main/java/org/apache/qpid/transport/util/SliceIterator.java new file mode 100644 index 0000000000..3db29847b2 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/transport/util/SliceIterator.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.transport.util; + +import java.nio.ByteBuffer; + +import java.util.Iterator; + + +/** + * SliceIterator + * + * @author Rafael H. Schloming + */ + +public class SliceIterator implements Iterator +{ + + final private Iterator iterator; + + public SliceIterator(Iterator iterator) + { + this.iterator = iterator; + } + + public boolean hasNext() + { + return iterator.hasNext(); + } + + public ByteBuffer next() + { + return iterator.next().slice(); + } + + public void remove() + { + throw new UnsupportedOperationException(); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/url/BindingURLImpl.java b/java/common/src/main/java/org/apache/qpid/url/BindingURLImpl.java index 2cf035f601..f12fb2cff2 100644 --- a/java/common/src/main/java/org/apache/qpid/url/BindingURLImpl.java +++ b/java/common/src/main/java/org/apache/qpid/url/BindingURLImpl.java @@ -17,7 +17,7 @@ */ package org.apache.qpid.url; -import org.apache.qpidity.exchange.ExchangeDefaults; +import org.apache.qpid.exchange.ExchangeDefaults; import org.slf4j.LoggerFactory; import org.slf4j.Logger; diff --git a/java/common/src/main/java/org/apache/qpid/url/QpidURL.java b/java/common/src/main/java/org/apache/qpid/url/QpidURL.java index 1d94b31de2..5ab4425323 100644 --- a/java/common/src/main/java/org/apache/qpid/url/QpidURL.java +++ b/java/common/src/main/java/org/apache/qpid/url/QpidURL.java @@ -17,7 +17,7 @@ */ package org.apache.qpid.url; -import org.apache.qpidity.BrokerDetails; +import org.apache.qpid.BrokerDetails; import java.util.List; diff --git a/java/common/src/main/java/org/apache/qpid/url/QpidURLImpl.java b/java/common/src/main/java/org/apache/qpid/url/QpidURLImpl.java index b4a55e2bf4..f92934db7f 100644 --- a/java/common/src/main/java/org/apache/qpid/url/QpidURLImpl.java +++ b/java/common/src/main/java/org/apache/qpid/url/QpidURLImpl.java @@ -17,8 +17,8 @@ */ package org.apache.qpid.url; -import org.apache.qpidity.BrokerDetails; -import org.apache.qpidity.BrokerDetailsImpl; +import org.apache.qpid.BrokerDetails; +import org.apache.qpid.BrokerDetailsImpl; import java.net.MalformedURLException; import java.util.ArrayList; diff --git a/java/common/src/main/java/org/apache/qpidity/BrokerDetails.java b/java/common/src/main/java/org/apache/qpidity/BrokerDetails.java deleted file mode 100644 index 29a4f5a9c0..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/BrokerDetails.java +++ /dev/null @@ -1,138 +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.qpidity; - -import java.util.Map; - -/** - * This interface represents a broker and provides the basic information - * required for opening a connection with a broker. - */ -public interface BrokerDetails -{ - /** - * Those are the supported protocols - */ - public static final String PROTOCOL_TCP = "tcp"; - public static final String PROTOCOL_TLS = "tls"; - - public static final String VIRTUAL_HOST = "virtualhost"; - public static final String CLIENT_ID = "client_id"; - public static final String USERNAME = "username"; - public static final String PASSWORD = "password"; - - /** - * Get the broker host name. - * - * @return The broker host name. - */ - public String getHost(); - - /** - * Get the broker port number. - * - * @return The broker port number. - */ - public int getPort(); - - /** - * Get the virtual host to connect to. - * - * @return The virtual host of this broker. - */ - public String getVirtualHost(); - - /** - * Get the user name. - * - * @return The user name - */ - public String getUserName(); - - /** - * Get the user password - * - * @return The user password - */ - public String getPassword(); - - /** - * Get the protocol used to connect to hise broker. - * - * @return the protocol used to connect to the broker. - */ - public String getProtocol(); - - /** - * Set the broker host name. - * - * @param host The broker host name. - */ - public void setHost(String host); - - /** - * Set the broker port number. - * - * @param port The broker port number. - */ - public void setPort(int port); - - /** - * Set the virtual host to connect to. - * - * @param virtualHost The virtual host of this broker. - */ - public void setVirtualHost(String virtualHost); - - /** - * Set the user name. - * - * @param userName The user name - */ - public void setUserName(String userName); - - /** - * Set the user password - * - * @param password The user password - */ - public void setPassword(String password); - - /** - * Set the protocol used to connect to hise broker. - * - * @param protocol the protocol used to connect to the broker. - */ - public void setProtocol(String protocol); - - /** - * Ex: keystore path - * - * @return the Properties associated with this connection. - */ - public Map getProperties(); - - /** - * Sets the properties associated with this connection - * - * @param props the new p[roperties. - */ - public void setProperties(Map props); - - public void setProperty(String key,String value); -} diff --git a/java/common/src/main/java/org/apache/qpidity/BrokerDetailsImpl.java b/java/common/src/main/java/org/apache/qpidity/BrokerDetailsImpl.java deleted file mode 100644 index 6de6055f1c..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/BrokerDetailsImpl.java +++ /dev/null @@ -1,264 +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.qpidity; - -import java.util.HashMap; -import java.util.Map; - -/** - * Implements the interface BrokerDetails - */ -public class BrokerDetailsImpl implements BrokerDetails -{ - //--- Those are the default values - private final String DEFAULT_USERNAME = "guest"; - private final String DEFAULT_PASSWORD = "guest"; - private final String DEFAULT_VIRTUALHOST = ""; - - //---- The brker details - private String _host; - private int _port = 0; - private String _virtualHost; - private String _userName = DEFAULT_USERNAME; - private String _password = DEFAULT_PASSWORD; - private String _protocol; - private Map _props = new HashMap(); - ; - - //--- Constructors - - public BrokerDetailsImpl() - { - } - - /** - * Create a new broker details given all the reuqired information - * - * @param protocol The protocol used for this broker connection - * @param host The host name. - * @param port The port number. - * @param virtualHost The virtual host. - * @param userName The user name. - * @param password The user password. - */ - public BrokerDetailsImpl(String protocol, String host, int port, String virtualHost, String userName, - String password, Map props) - { - _protocol = protocol; - _host = host; - _port = port; - _virtualHost = virtualHost; - _userName = userName; - _password = password; - _props = props; - } - - /** - * Create a new broker details given the host name and the procol type, - * default values are used for the other details. - * - * @param protocol The protocol used for this broker connection - * @param host The host name. - */ - public BrokerDetailsImpl(String protocol, String host) - { - _protocol = protocol; - _host = host; - _virtualHost = DEFAULT_VIRTUALHOST; - _userName = DEFAULT_USERNAME; - _password = DEFAULT_PASSWORD; - } - - //--- API BrokerDetails - /** - * Get the user password - * - * @return The user password - */ - public String getPassword() - { - return _password; - } - - /** - * Get the broker host name. - * - * @return The broker host name. - */ - public String getHost() - { - return _host; - } - - /** - * Get the broker port number. - * - * @return The broker port number. - */ - public int getPort() - { - if (_port == 0) - { - if (getProtocol().equals(BrokerDetails.PROTOCOL_TCP)) - { - _port = 5672; - } - else if (getProtocol().equals(BrokerDetails.PROTOCOL_TLS)) - { - _port = 5555; - } - } - return _port; - } - - /** - * Get the virtual host to connect to. - * - * @return The virtual host of this broker. - */ - public String getVirtualHost() - { - return _virtualHost; - } - - /** - * Get the user name. - * - * @return The user name - */ - public String getUserName() - { - return _userName; - } - - /** - * Get the protocol used to connect to hise broker. - * - * @return the protocol used to connect to the broker. - */ - public String getProtocol() - { - return _protocol; - } - - /** - * Set the broker host name. - * - * @param host The broker host name. - */ - public void setHost(String host) - { - _host = host; - } - - /** - * Set the broker port number. - * - * @param port The broker port number. - */ - public void setPort(int port) - { - _port = port; - } - - /** - * Set the virtual host to connect to. - * - * @param virtualHost The virtual host of this broker. - */ - public void setVirtualHost(String virtualHost) - { - _virtualHost = virtualHost; - } - - /** - * Set the user name. - * - * @param userName The user name - */ - public void setUserName(String userName) - { - _userName = userName; - } - - /** - * Set the user password - * - * @param password The user password - */ - public void setPassword(String password) - { - _password = password; - } - - /** - * Set the protocol used to connect to hise broker. - * - * @param protocol the protocol used to connect to the broker. - */ - public void setProtocol(String protocol) - { - _protocol = protocol; - } - - /** - * Ex: keystore path - * - * @return the Properties associated with this connection. - */ - public Map getProperties() - { - return _props; - } - - /** - * Sets the properties associated with this connection - * - * @param props - */ - public void setProperties(Map props) - { - _props = props; - } - - public void setProperty(String key, String value) - { - _props.put(key, value); - } - - public String toString() - { - StringBuilder b = new StringBuilder(); - b.append("[username=" + _userName); - b.append(",password=" + _password); - b.append(",transport=" + _protocol); - b.append(",host=" + _host); - b.append(",port=" + getPort() + "]"); - b.append(" - Properties["); - if (_props != null) - { - for (String k : _props.keySet()) - { - b.append(k + "=" + _props.get(k) + ","); - } - } - b.append("]"); - - return b.toString(); - } -} diff --git a/java/common/src/main/java/org/apache/qpidity/ConsoleOutput.java b/java/common/src/main/java/org/apache/qpidity/ConsoleOutput.java deleted file mode 100644 index 6262bd25c6..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/ConsoleOutput.java +++ /dev/null @@ -1,54 +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.qpidity; - -import java.nio.ByteBuffer; - -import org.apache.qpidity.transport.Sender; - -import static org.apache.qpidity.transport.util.Functions.*; - - -/** - * ConsoleOutput - * - * @author Rafael H. Schloming - */ - -public class ConsoleOutput implements Sender -{ - - public void send(ByteBuffer buf) - { - System.out.println(str(buf)); - } - - public void flush() - { - // pass - } - - public void close() - { - System.out.println("CLOSED"); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/ErrorCode.java b/java/common/src/main/java/org/apache/qpidity/ErrorCode.java deleted file mode 100644 index 4b18c46d16..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/ErrorCode.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.apache.qpidity; - -public enum ErrorCode -{ - //Qpid specific - for the time being - UNDEFINED(1,"undefined",true), - MESSAGE_REJECTED(2,"message_rejected",true), - CONNECTION_ERROR(3,"connection was closed",true), - UNSUPPORTED_PROTOCOL(4, "protocol version is unsupported", true), - - //This might change in the spec, the error class is not applicable - NO_ERROR(200,"reply-success",true), - - //From the spec - CONTENT_TOO_LARGE(311,"content-too-large",false), - NO_ROUTE(312,"no-route",false), - NO_CONSUMERS(313,"content-consumers",false), - CONNECTION_FORCED(320,"connection-forced",true), - INVALID_PATH(402,"invalid-path",true), - ACCESS_REFUSED(403,"access-refused",false), - NOT_FOUND(404,"not-found",false), - RESOURCE_LOCKED(405,"resource-locked",false), - PRE_CONDITION_FAILED(406,"precondition-failed",false), - - FRAME_ERROR(501,"frame_error",true), - SYNTAX_ERROR(502,"syntax_error",true), - COMMAND_INVALID(503,"command_invalid",true), - SESSION_ERROR(504,"sesion_error",true), - NOT_ALLOWED(530,"not_allowed",true), - NOT_IMPLEMENTED(540,"not_implemented",true), - INTERNAL_ERROR(541,"internal_error",true), - INVALID_ARGUMENT(542,"invalid_argument",true); - - private int _code; - private String _desc; - private boolean _hardError; - - private ErrorCode(int code,String desc,boolean hardError) - { - _code = code; - _desc= desc; - _hardError = hardError; - } - - public int getCode() - { - return _code; - } - - public String getDesc() - { - return _desc; - } - - private boolean isHardError() - { - return _hardError; - } - - public static ErrorCode get(int code) - { - switch(code) - { - case 200 : return NO_ERROR; - case 311 : return CONTENT_TOO_LARGE; - case 312 : return NO_ROUTE; - case 313 : return NO_CONSUMERS; - case 320 : return CONNECTION_FORCED; - case 402 : return INVALID_PATH; - case 403 : return ACCESS_REFUSED; - case 404 : return NOT_FOUND; - case 405 : return RESOURCE_LOCKED; - case 406 : return PRE_CONDITION_FAILED; - case 501 : return FRAME_ERROR; - case 502 : return SYNTAX_ERROR; - case 503 : return COMMAND_INVALID; - case 504 : return SESSION_ERROR; - case 530 : return NOT_ALLOWED; - case 540 : return NOT_IMPLEMENTED; - case 541 : return INTERNAL_ERROR; - case 542 : return INVALID_ARGUMENT; - - default : return UNDEFINED; - } - } - } - -/* - - - - The server could not complete the method because of an internal error. The server may require - intervention by an operator in order to resume normal operations. - - - - - - An invalid or illegal argument was passed to a method, and the operation could not proceed. - - -*/ \ No newline at end of file diff --git a/java/common/src/main/java/org/apache/qpidity/QpidConfig.java b/java/common/src/main/java/org/apache/qpidity/QpidConfig.java deleted file mode 100644 index b5aad12f10..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/QpidConfig.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.apache.qpidity; - -/** - * API to configure the Security parameters of the client. - * The user can choose to pick the config from any source - * and set it using this class. - * - */ -public class QpidConfig -{ - private static QpidConfig _instance = new QpidConfig(); - - private SecurityMechanism[] securityMechanisms = - new SecurityMechanism[]{new SecurityMechanism("PLAIN","org.apache.qpidity.security.UsernamePasswordCallbackHandler"), - new SecurityMechanism("CRAM_MD5","org.apache.qpidity.security.UsernamePasswordCallbackHandler")}; - - private SaslClientFactory[] saslClientFactories = - new SaslClientFactory[]{new SaslClientFactory("AMQPLAIN","org.apache.qpidity.security.amqplain.AmqPlainSaslClientFactory")}; - - private QpidConfig(){} - - public static QpidConfig get() - { - return _instance; - } - - public void setSecurityMechanisms(SecurityMechanism... securityMechanisms) - { - this.securityMechanisms = securityMechanisms; - } - - public SecurityMechanism[] getSecurityMechanisms() - { - return securityMechanisms; - } - - public void setSaslClientFactories(SaslClientFactory... saslClientFactories) - { - this.saslClientFactories = saslClientFactories; - } - - public SaslClientFactory[] getSaslClientFactories() - { - return saslClientFactories; - } - - public class SecurityMechanism - { - String type; - String handler; - - SecurityMechanism(String type,String handler) - { - this.type = type; - this.handler = handler; - } - - public String getHandler() - { - return handler; - } - - public String getType() - { - return type; - } - } - - public class SaslClientFactory - { - String type; - String factoryClass; - - SaslClientFactory(String type,String factoryClass) - { - this.type = type; - this.factoryClass = factoryClass; - } - - public String getFactoryClass() - { - return factoryClass; - } - - public String getType() - { - return type; - } - } -} diff --git a/java/common/src/main/java/org/apache/qpidity/QpidException.java b/java/common/src/main/java/org/apache/qpidity/QpidException.java deleted file mode 100644 index 81e9145282..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/QpidException.java +++ /dev/null @@ -1,58 +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.qpidity; - -public class QpidException extends Exception -{ - /** - * AMQP error code - */ - private ErrorCode _errorCode; - - /** - * Constructor for a Qpid Exception. - *

This is the only provided constructor and the parameters have to be set to null when - * they are unknown. - * @param message A description of the reason of this exception . - * @param errorCode A string specifyin the error code of this exception. - * @param cause The linked Execption. * - * - */ - public QpidException(String message, ErrorCode errorCode, Throwable cause) - { - super(message, cause); - _errorCode = errorCode; - } - - /*hack to get rid of a compile error from a generated class - public QpidException(String message, String errorCode, Throwable cause) - { - - }*/ - - /** - * Get this execption error code. - * - * @return This exception error code. - */ - public ErrorCode getErrorCode() - { - return _errorCode; - } -} - diff --git a/java/common/src/main/java/org/apache/qpidity/SecurityHelper.java b/java/common/src/main/java/org/apache/qpidity/SecurityHelper.java deleted file mode 100644 index a72997813a..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/SecurityHelper.java +++ /dev/null @@ -1,71 +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.qpidity; - -import java.io.UnsupportedEncodingException; -import java.util.HashSet; -import java.util.List; -import java.util.StringTokenizer; - -import org.apache.qpidity.security.AMQPCallbackHandler; -import org.apache.qpidity.security.CallbackHandlerRegistry; - -public class SecurityHelper -{ - public static String chooseMechanism(List mechanisms) throws UnsupportedEncodingException - { - HashSet mechanismSet = new HashSet(); - for (Object m : mechanisms) - { - mechanismSet.add(m); - } - - String preferredMechanisms = CallbackHandlerRegistry.getInstance().getMechanisms(); - StringTokenizer prefTokenizer = new StringTokenizer(preferredMechanisms, " "); - while (prefTokenizer.hasMoreTokens()) - { - String mech = prefTokenizer.nextToken(); - if (mechanismSet.contains(mech)) - { - return mech; - } - } - return null; - } - - public static AMQPCallbackHandler createCallbackHandler(String mechanism, String username,String password) - throws QpidException - { - Class mechanismClass = CallbackHandlerRegistry.getInstance().getCallbackHandlerClass(mechanism); - try - { - Object instance = mechanismClass.newInstance(); - AMQPCallbackHandler cbh = (AMQPCallbackHandler) instance; - cbh.initialise(username,password); - return cbh; - } - catch (Exception e) - { - throw new QpidException("Unable to create callback handler: " + e,ErrorCode.UNDEFINED, e.getCause()); - } - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/ToyBroker.java b/java/common/src/main/java/org/apache/qpidity/ToyBroker.java deleted file mode 100644 index 0055855c0a..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/ToyBroker.java +++ /dev/null @@ -1,286 +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.qpidity; - -import org.apache.qpidity.transport.*; -import org.apache.qpidity.transport.network.mina.MinaHandler; - -import static org.apache.qpidity.transport.util.Functions.str; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.LinkedBlockingQueue; - - -/** - * ToyBroker - * - * @author Rafael H. Schloming - */ - -class ToyBroker extends SessionDelegate -{ - - private ToyExchange exchange; - private MessageTransfer xfr = null; - private DeliveryProperties props = null; - private Header header = null; - private List body = null; - private Map consumers = new ConcurrentHashMap(); - - public ToyBroker(ToyExchange exchange) - { - this.exchange = exchange; - } - - public void messageAcquire(Session context, MessageAcquire struct) - { - System.out.println("\n==================> messageAcquire " ); - context.executionResult((int) struct.getId(), new Acquired(struct.getTransfers())); - } - - @Override public void queueDeclare(Session ssn, QueueDeclare qd) - { - exchange.createQueue(qd.getQueue()); - System.out.println("\n==================> declared queue: " + qd.getQueue() + "\n"); - } - - @Override public void exchangeBind(Session ssn, ExchangeBind qb) - { - exchange.bindQueue(qb.getExchange(), qb.getBindingKey(),qb.getQueue()); - System.out.println("\n==================> bound queue: " + qb.getQueue() + " with binding key " + qb.getBindingKey() + "\n"); - } - - @Override public void queueQuery(Session ssn, QueueQuery qq) - { - QueueQueryResult result = new QueueQueryResult().queue(qq.getQueue()); - ssn.executionResult((int) qq.getId(), result); - } - - @Override public void messageSubscribe(Session ssn, MessageSubscribe ms) - { - Consumer c = new Consumer(); - c._queueName = ms.getQueue(); - consumers.put(ms.getDestination(),c); - System.out.println("\n==================> message subscribe : " + ms.getDestination() + " queue: " + ms.getQueue() + "\n"); - } - - @Override public void messageFlow(Session ssn,MessageFlow struct) - { - Consumer c = consumers.get(struct.getDestination()); - c._credit = struct.getValue(); - System.out.println("\n==================> message flow : " + struct.getDestination() + " credit: " + struct.getValue() + "\n"); - } - - @Override public void messageFlush(Session ssn,MessageFlush struct) - { - System.out.println("\n==================> message flush for consumer : " + struct.getDestination() + "\n"); - checkAndSendMessagesToConsumer(ssn,struct.getDestination()); - } - - @Override public void messageTransfer(Session ssn, MessageTransfer xfr) - { - this.xfr = xfr; - body = new ArrayList(); - System.out.println("received transfer " + xfr.getDestination()); - } - - @Override public void header(Session ssn, Header header) - { - if (xfr == null || body == null) - { - ssn.connectionClose(ConnectionCloseCode.FRAMING_ERROR, - "no method segment"); - ssn.close(); - return; - } - - props = header.get(DeliveryProperties.class); - if (props != null) - { - System.out.println("received headers routing_key " + props.getRoutingKey()); - } - MessageProperties mp = header.get(MessageProperties.class); - System.out.println("MP: " + mp); - if (mp != null) - { - System.out.println(mp.getApplicationHeaders()); - } - - this.header = header; - } - - @Override public void data(Session ssn, Data data) - { - if (xfr == null || body == null) - { - ssn.connectionClose(ConnectionCloseCode.FRAMING_ERROR, "no method segment"); - ssn.close(); - return; - } - - body.add(data); - - if (data.isLast()) - { - String dest = xfr.getDestination(); - Message m = new Message(header, body); - - if (exchange.route(dest,props.getRoutingKey(),m)) - { - System.out.println("queued " + m); - dispatchMessages(ssn); - } - else - { - - reject(ssn); - } - ssn.processed(xfr); - xfr = null; - body = null; - } - } - - private void reject(Session ssn) - { - if (props != null && props.getDiscardUnroutable()) - { - return; - } - else - { - RangeSet ranges = new RangeSet(); - ranges.add(xfr.getId()); - ssn.messageReject(ranges, MessageRejectCode.UNROUTABLE, - "no such destination"); - } - } - - private void transferMessageToPeer(Session ssn,String dest, Message m) - { - System.out.println("\n==================> Transfering message to: " +dest + "\n"); - ssn.messageTransfer(dest, MessageAcceptMode.EXPLICIT, - MessageAcquireMode.PRE_ACQUIRED); - ssn.header(m.header); - for (Data d : m.body) - { - ssn.data(d.getData()); - } - ssn.endData(); - } - - private void dispatchMessages(Session ssn) - { - for (String dest: consumers.keySet()) - { - checkAndSendMessagesToConsumer(ssn,dest); - } - } - - private void checkAndSendMessagesToConsumer(Session ssn,String dest) - { - Consumer c = consumers.get(dest); - LinkedBlockingQueue queue = exchange.getQueue(c._queueName); - Message m = queue.poll(); - while (m != null && c._credit>0) - { - transferMessageToPeer(ssn,dest,m); - c._credit--; - m = queue.poll(); - } - } - - class Message - { - private final Header header; - private final List body; - - public Message(Header header, List body) - { - this.header = header; - this.body = body; - } - - public String toString() - { - StringBuilder sb = new StringBuilder(); - - if (header != null) - { - boolean first = true; - for (Struct st : header.getStructs()) - { - if (first) { first = false; } - else { sb.append(" "); } - sb.append(st); - } - } - - for (Data d : body) - { - sb.append(" | "); - sb.append(d); - } - - return sb.toString(); - } - - } - - // ugly, but who cares :) - // assumes unit is always no of messages, not bytes - // assumes it's credit mode and not window - private class Consumer - { - long _credit; - String _queueName; - } - - public static final void main(String[] args) throws IOException - { - final ToyExchange exchange = new ToyExchange(); - ConnectionDelegate delegate = new ConnectionDelegate() - { - public SessionDelegate getSessionDelegate() - { - return new ToyBroker(exchange); - } - public void exception(Throwable t) - { - t.printStackTrace(); - } - public void closed() {} - }; - - //hack - delegate.setUsername("guest"); - delegate.setPassword("guest"); - - MinaHandler.accept("0.0.0.0", 5672, delegate); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/ToyClient.java b/java/common/src/main/java/org/apache/qpidity/ToyClient.java deleted file mode 100644 index 0912f3bdd9..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/ToyClient.java +++ /dev/null @@ -1,133 +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.qpidity; - -import java.util.*; - -import org.apache.qpidity.transport.*; -import org.apache.qpidity.transport.network.mina.MinaHandler; - - -/** - * ToyClient - * - * @author Rafael H. Schloming - */ - -class ToyClient extends SessionDelegate -{ - - @Override public void messageReject(Session ssn, MessageReject reject) - { - for (Range range : reject.getTransfers()) - { - for (long l = range.getLower(); l <= range.getUpper(); l++) - { - System.out.println("message rejected: " + - ssn.getCommand((int) l)); - } - } - } - - @Override public void header(Session ssn, Header header) - { - for (Struct st : header.getStructs()) - { - System.out.println("header: " + st); - } - } - - @Override public void data(Session ssn, Data data) - { - System.out.println("got data: " + data); - } - - public static final void main(String[] args) - { - Connection conn = MinaHandler.connect("0.0.0.0", 5672, - new ClientDelegate() - { - public SessionDelegate getSessionDelegate() - { - return new ToyClient(); - } - public void exception(Throwable t) - { - t.printStackTrace(); - } - public void closed() {} - }); - conn.send(new ProtocolHeader - (1, 0, 10)); - - Channel ch = conn.getChannel(0); - Session ssn = new Session("my-session".getBytes()); - ssn.attach(ch); - ssn.sessionAttach(ssn.getName()); - - ssn.queueDeclare("asdf", null, null); - ssn.sync(); - - Map nested = new LinkedHashMap(); - nested.put("list", Arrays.asList("one", "two", "three")); - Map map = new LinkedHashMap(); - - map.put("str", "this is a string"); - - map.put("+int", 3); - map.put("-int", -3); - map.put("maxint", Integer.MAX_VALUE); - map.put("minint", Integer.MIN_VALUE); - - map.put("+short", (short) 1); - map.put("-short", (short) -1); - map.put("maxshort", (short) Short.MAX_VALUE); - map.put("minshort", (short) Short.MIN_VALUE); - - map.put("float", (float) 3.3); - map.put("double", 4.9); - map.put("char", 'c'); - - map.put("table", nested); - map.put("list", Arrays.asList(1, 2, 3)); - map.put("binary", new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); - - ssn.messageTransfer("asdf", MessageAcceptMode.EXPLICIT, - MessageAcquireMode.PRE_ACQUIRED); - ssn.header(new DeliveryProperties(), - new MessageProperties().setApplicationHeaders(map)); - ssn.data("this is the data"); - ssn.endData(); - - ssn.messageTransfer("fdsa", MessageAcceptMode.EXPLICIT, - MessageAcquireMode.PRE_ACQUIRED); - ssn.data("this should be rejected"); - ssn.endData(); - ssn.sync(); - - Future future = ssn.queueQuery("asdf"); - System.out.println(future.get().getQueue()); - ssn.sync(); - ssn.close(); - conn.close(); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/ToyExchange.java b/java/common/src/main/java/org/apache/qpidity/ToyExchange.java deleted file mode 100644 index eab5f6c078..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/ToyExchange.java +++ /dev/null @@ -1,132 +0,0 @@ -package org.apache.qpidity; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.qpidity.ToyBroker.Message; - -public class ToyExchange -{ - final static String DIRECT = "amq.direct"; - final static String TOPIC = "amq.topic"; - - private Map>> directEx = new HashMap>>(); - private Map>> topicEx = new HashMap>>(); - private Map> queues = new HashMap>(); - - public void createQueue(String name) - { - queues.put(name, new LinkedBlockingQueue()); - } - - public LinkedBlockingQueue getQueue(String name) - { - return queues.get(name); - } - - public void bindQueue(String type,String binding,String queueName) - { - LinkedBlockingQueue queue = queues.get(queueName); - binding = normalizeKey(binding); - if(DIRECT.equals(type)) - { - - if (directEx.containsKey(binding)) - { - List> list = directEx.get(binding); - list.add(queue); - } - else - { - List> list = new LinkedList>(); - list.add(queue); - directEx.put(binding,list); - } - } - else - { - if (topicEx.containsKey(binding)) - { - List> list = topicEx.get(binding); - list.add(queue); - } - else - { - List> list = new LinkedList>(); - list.add(queue); - topicEx.put(binding,list); - } - } - } - - public boolean route(String dest,String routingKey,Message msg) - { - List> queues; - if(DIRECT.equals(dest)) - { - queues = directEx.get(routingKey); - } - else - { - queues = matchWildCard(routingKey); - } - if(queues != null && queues.size()>0) - { - System.out.println("Message stored in " + queues.size() + " queues"); - storeMessage(msg,queues); - return true; - } - else - { - System.out.println("Message unroutable " + msg); - return false; - } - } - - private String normalizeKey(String routingKey) - { - if(routingKey.indexOf(".*")>1) - { - return routingKey.substring(0,routingKey.indexOf(".*")); - } - else - { - return routingKey; - } - } - - private List> matchWildCard(String routingKey) - { - List> selected = new ArrayList>(); - - for(String key: topicEx.keySet()) - { - Pattern p = Pattern.compile(key); - Matcher m = p.matcher(routingKey); - if (m.find()) - { - for(LinkedBlockingQueue queue : topicEx.get(key)) - { - selected.add(queue); - } - } - } - - return selected; - } - - private void storeMessage(Message msg,List> selected) - { - for(LinkedBlockingQueue queue : selected) - { - queue.offer(msg); - } - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/api/Message.java b/java/common/src/main/java/org/apache/qpidity/api/Message.java deleted file mode 100644 index f5488fde52..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/api/Message.java +++ /dev/null @@ -1,126 +0,0 @@ -package org.apache.qpidity.api; - -import java.io.IOException; -import java.nio.ByteBuffer; - -import org.apache.qpidity.transport.MessageProperties; -import org.apache.qpidity.transport.DeliveryProperties; -import org.apache.qpidity.transport.Header; - -/* - * 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. - */ - -public interface Message -{ - public Header getHeader(); - - public void setHeader(Header header); - - public MessageProperties getMessageProperties(); - - public DeliveryProperties getDeliveryProperties(); - - /** - * This will abstract the underlying message data. - * The Message implementation may not hold all message - * data in memory (especially in the case of large messages) - * - * The appendData function might write data to - *
    - *
  • Memory (Ex: ByteBuffer) - *
  • To Disk - *
  • To Socket (Stream) - *
- * @param src - the data to append - */ - public void appendData(byte[] src) throws IOException; - - - /** - * This will abstract the underlying message data. - * The Message implementation may not hold all message - * data in memory (especially in the case of large messages) - * - * The appendData function might write data to - *
    - *
  • Memory (Ex: ByteBuffer) - *
  • To Disk - *
  • To Socket (Stream) - *
- * @param src - the data to append - */ - public void appendData(ByteBuffer src) throws IOException; - - /** - * This will abstract the underlying message data. - * The Message implementation may not hold all message - * data in memory (especially in the case of large messages) - * - * The read function might copy data from - *
    - *
  • From memory (Ex: ByteBuffer) - *
  • From Disk - *
  • From Socket as and when it gets streamed - *
- * @param target The target byte[] which the data gets copied to - */ - public void readData(byte[] target) throws IOException; - - /** - * * This will abstract the underlying message data. - * The Message implementation may not hold all message - * data in memory (especially in the case of large messages) - * - * The read function might copy data from - *
    - *
  • From memory (Ex: ByteBuffer) - *
  • From Disk - *
  • From Socket as and when it gets streamed - *
- * - * @return A ByteBuffer containing data - * @throws IOException - */ - public ByteBuffer readData() throws IOException; - - /** - * This should clear the body of the message. - */ - public void clearData(); - - /** - * The provides access to the command Id assigned to the - * message transfer. - * This id is useful when you do - *
    - *
  • For message acquiring - If the transfer happend in no-acquire mode - * you could use this id to accquire it. - *
  • For releasing a message. You can use this id to release an acquired - * message - *
  • For Acknowledging a message - You need to pass this ID, in order to - * acknowledge the message - *
  • For Rejecting a message - You need to pass this ID, in order to reject - * the message. - *
- * - * @return the message transfer id. - */ - public int getMessageTransferId(); - -} diff --git a/java/common/src/main/java/org/apache/qpidity/dtx/XidImpl.java b/java/common/src/main/java/org/apache/qpidity/dtx/XidImpl.java deleted file mode 100644 index 89d7e7917f..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/dtx/XidImpl.java +++ /dev/null @@ -1,250 +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.qpidity.dtx; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.apache.qpidity.QpidException; - -import javax.transaction.xa.Xid; - -import java.io.*; - -/** - * Implements javax.transaction.dtx.Xid - */ -public class XidImpl implements Xid -{ - /** - * this session's logger - */ - private static final Logger _logger = LoggerFactory.getLogger(XidImpl.class); - - /** - * the transaction branch identifier part of XID as an array of bytes - */ - private byte[] _branchQualifier; - - /** - * the format identifier part of the XID. - */ - private int _formatID; - - /** - * the global transaction identifier part of XID as an array of bytes. - */ - private byte[] _globalTransactionID; - - //--- Constructors - - /** - * Create new Xid. - * this is an empty constructor. - */ - public XidImpl() - { - - } - - /** - * Create a new XidImpl from an existing Xid. - *

Usefull for casting external Xids - * - * @param xid Foreign Xid. - */ - public XidImpl(Xid xid) - { - _branchQualifier = xid.getBranchQualifier(); - _formatID = xid.getFormatId(); - _globalTransactionID = xid.getGlobalTransactionId(); - } - - /** - * Create a new Xid. - * - * @param branchQualifier The transaction branch identifier part of XID as an array of bytes. - * @param format The format identifier part of the XID. - * @param globalTransactionID The global transaction identifier part of XID as an array of bytes. - */ - public XidImpl(byte[] branchQualifier, int format, byte[] globalTransactionID) - { - _branchQualifier = branchQualifier; - _formatID = format; - _globalTransactionID = globalTransactionID; - } - - /** - * Create a new Xid form its String form - * 4 1 1 g b - * +---+---+---+---+---+---+---+- -+---+---+- -+---+ - * | format_id | g | b | txn-id | br-id | - * +---+---+---+---+---+---+---+- -+---+---+- -+---+ - * 0 4 5 6 6+g 6+g+b - * format_id: an implementation specific format identifier - *

- * gtrid_length: how many bytes of this form the transaction id - *

- * bqual_length: how many bytes of this form the branch id - *

- * data: a sequence of octets of at most 128 bytes containing the txn id and the - * branch id - *

- * Note - The sum of the two lengths must equal the length of the data field. - * - * @param xid an XID STring Form - * @throws QpidException If the string does not represent a valid Xid - */ - public XidImpl(String xid) throws QpidException - { - if (_logger.isDebugEnabled()) - { - _logger.debug("converting string " + xid + " into XidImpl"); - } - try - { - DataInputStream input = new DataInputStream(new ByteArrayInputStream(xid.getBytes())); - _formatID = (int) input.readLong(); - int g = input.readByte(); - int b = input.readByte(); - _globalTransactionID = new byte[g]; - _branchQualifier = new byte[b]; - if (input.read(_globalTransactionID, 0, g) != g) - { - throw new QpidException("Cannot convert the string " + xid + " into an Xid", null, null); - } - if (input.read(_branchQualifier, 0, b) != b) - { - throw new QpidException("Cannot convert the string " + xid + " into an Xid", null, null); - } - } - catch (IOException e) - { - throw new QpidException("cannot convert the string " + xid + " into an Xid", null, e); - } - } - - //--- Xid interface implementation - - /** - * Format identifier. O means the OSI CCR format. - * - * @return Global transaction identifier. - */ - public byte[] getGlobalTransactionId() - { - return _globalTransactionID; - } - - /** - * Obtain the transaction branch identifier part of XID as an array of bytes. - * - * @return Branch identifier part of XID. - */ - public byte[] getBranchQualifier() - { - return _branchQualifier; - } - - /** - * Obtain the format identifier part of the XID. - * - * @return Format identifier. O means the OSI CCR format. - */ - public int getFormatId() - { - return _formatID; - } - - //--- Object operations - - /** - * Indicates whether some other Xid is "equal to" this one. - *

Two Xids are equal if and only if their three elementary parts are equal - * - * @param o the object to compare this XidImpl against. - * @return true if the XidImpl are equal, false otherwise. - */ - public boolean equals(Object o) - { - if (this == o) - { - return true; - } - if (o instanceof XidImpl) - { - XidImpl other = (XidImpl) o; - if (_formatID == other.getFormatId()) - { - if (_branchQualifier.length == other.getBranchQualifier().length) - { - for (int i = 0; i < _branchQualifier.length; i++) - { - if (_branchQualifier[i] != other.getBranchQualifier()[i]) - { - return false; - } - } - if (_globalTransactionID.length == other.getGlobalTransactionId().length) - { - for (int i = 0; i < _globalTransactionID.length; i++) - { - if (_globalTransactionID[i] != other.getGlobalTransactionId()[i]) - { - return false; - } - } - // everithing is equal - return true; - } - } - } - } - return false; - } - - //-- Static helper method - /** - * Convert an Xid into the AMQP String format. - * - * 4 1 1 g b - * +---+---+---+---+---+---+---+- -+---+---+- -+---+ - * | format_id | g | b | txn-id | br-id | - * +---+---+---+---+---+---+---+- -+---+---+- -+---+ - * 0 4 5 6 6+g 6+g+b - * format_id: an implementation specific format identifier - *

- * gtrid_length: how many bytes of this form the transaction id - *

- * bqual_length: how many bytes of this form the branch id - *

- * data: a sequence of octets of at most 128 bytes containing the txn id and the - * branch id - *

- * Note - The sum of the two lengths must equal the length of the data field. - * - * @param xid an Xid to convert. - * @return The String representation of this Xid - * @throws QpidException In case of problem when converting this Xid into a string. - */ - public static org.apache.qpidity.transport.Xid convert(Xid xid) throws QpidException - { - return new org.apache.qpidity.transport.Xid(xid.getFormatId(), - xid.getGlobalTransactionId(), - xid.getBranchQualifier()); - } -} diff --git a/java/common/src/main/java/org/apache/qpidity/exchange/ExchangeDefaults.java b/java/common/src/main/java/org/apache/qpidity/exchange/ExchangeDefaults.java deleted file mode 100644 index a99ea56d69..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/exchange/ExchangeDefaults.java +++ /dev/null @@ -1,51 +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.qpidity.exchange; - -/** - * Default exchange names - */ -public class ExchangeDefaults -{ - /** The default direct exchange, which is a special internal exchange that cannot be explicitly bound to. */ - public static final String DEFAULT_EXCHANGE_NAME = "<>"; - - /** The pre-defined topic exchange, the broker SHOULD provide this. */ - public static final String TOPIC_EXCHANGE_NAME = "amq.topic"; - - /** Defines the identifying type name of topic exchanges. */ - public static final String TOPIC_EXCHANGE_CLASS = "topic"; - - /** The pre-defined direct exchange, the broker MUST provide this. */ - public static final String DIRECT_EXCHANGE_NAME = "amq.direct"; - - /** Defines the identifying type name of direct exchanges. */ - public static final String DIRECT_EXCHANGE_CLASS = "direct"; - - /** The pre-defined headers exchange, the specification does not say this needs to be provided. */ - public static final String HEADERS_EXCHANGE_NAME = "amq.match"; - - /** Defines the identifying type name of headers exchanges. */ - public static final String HEADERS_EXCHANGE_CLASS = "headers"; - - /** The pre-defined fanout exchange, the boker MUST provide this. */ - public static final String FANOUT_EXCHANGE_NAME = "amq.fanout"; - - /** Defines the identifying type name of fanout exchanges. */ - public static final String FANOUT_EXCHANGE_CLASS = "fanout"; -} diff --git a/java/common/src/main/java/org/apache/qpidity/security/AMQPCallbackHandler.java b/java/common/src/main/java/org/apache/qpidity/security/AMQPCallbackHandler.java deleted file mode 100644 index 2e7afa1b87..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/security/AMQPCallbackHandler.java +++ /dev/null @@ -1,28 +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.qpidity.security; - -import javax.security.auth.callback.CallbackHandler; - -public interface AMQPCallbackHandler extends CallbackHandler -{ - void initialise(String username,String password); -} diff --git a/java/common/src/main/java/org/apache/qpidity/security/CallbackHandlerRegistry.java b/java/common/src/main/java/org/apache/qpidity/security/CallbackHandlerRegistry.java deleted file mode 100644 index b23fea7e4a..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/security/CallbackHandlerRegistry.java +++ /dev/null @@ -1,94 +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.qpidity.security; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.qpidity.QpidConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class CallbackHandlerRegistry -{ - private static final Logger _logger = LoggerFactory.getLogger(CallbackHandlerRegistry.class); - private static CallbackHandlerRegistry _instance = new CallbackHandlerRegistry(); - - private Map _mechanismToHandlerClassMap = new HashMap(); - - private StringBuilder _mechanisms; - - public static CallbackHandlerRegistry getInstance() - { - return _instance; - } - - public Class getCallbackHandlerClass(String mechanism) - { - return _mechanismToHandlerClassMap.get(mechanism); - } - - public String getMechanisms() - { - return _mechanisms.toString(); - } - - private CallbackHandlerRegistry() - { - // first we register any Sasl client factories - DynamicSaslRegistrar.registerSaslProviders(); - registerMechanisms(); - } - - private void registerMechanisms() - { - for (QpidConfig.SecurityMechanism securityMechanism: QpidConfig.get().getSecurityMechanisms() ) - { - Class clazz = null; - try - { - clazz = Class.forName(securityMechanism.getHandler()); - if (!AMQPCallbackHandler.class.isAssignableFrom(clazz)) - { - _logger.debug("SASL provider " + clazz + " does not implement " + AMQPCallbackHandler.class + - ". Skipping"); - continue; - } - _mechanismToHandlerClassMap.put(securityMechanism.getType(), clazz); - if (_mechanisms == null) - { - - _mechanisms = new StringBuilder(); - _mechanisms.append(securityMechanism.getType()); - } - else - { - _mechanisms.append(" " + securityMechanism.getType()); - } - } - catch (ClassNotFoundException ex) - { - _logger.debug("Unable to load class " + securityMechanism.getHandler() + ". Skipping that SASL provider"); - continue; - } - } - } -} diff --git a/java/common/src/main/java/org/apache/qpidity/security/DynamicSaslRegistrar.java b/java/common/src/main/java/org/apache/qpidity/security/DynamicSaslRegistrar.java deleted file mode 100644 index 1798f0c210..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/security/DynamicSaslRegistrar.java +++ /dev/null @@ -1,74 +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.qpidity.security; - -import java.security.Security; -import java.util.Map; -import java.util.TreeMap; - -import javax.security.sasl.SaslClientFactory; - -import org.apache.qpidity.QpidConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DynamicSaslRegistrar -{ - private static final Logger _logger = LoggerFactory.getLogger(DynamicSaslRegistrar.class); - - public static void registerSaslProviders() - { - Map factories = registerSaslClientFactories(); - if (factories.size() > 0) - { - Security.addProvider(new JCAProvider(factories)); - _logger.debug("Dynamic SASL provider added as a security provider"); - } - } - - private static Map registerSaslClientFactories() - { - TreeMap factoriesToRegister = - new TreeMap(); - - for (QpidConfig.SaslClientFactory factory: QpidConfig.get().getSaslClientFactories()) - { - String className = factory.getFactoryClass(); - try - { - Class clazz = Class.forName(className); - if (!(SaslClientFactory.class.isAssignableFrom(clazz))) - { - _logger.debug("Class " + clazz + " does not implement " + SaslClientFactory.class + " - skipping"); - continue; - } - factoriesToRegister.put(factory.getType(), clazz); - } - catch (Exception ex) - { - _logger.debug("Error instantiating SaslClientFactory calss " + className + " - skipping"); - } - } - return factoriesToRegister; - } - - -} diff --git a/java/common/src/main/java/org/apache/qpidity/security/JCAProvider.java b/java/common/src/main/java/org/apache/qpidity/security/JCAProvider.java deleted file mode 100644 index c775171a5f..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/security/JCAProvider.java +++ /dev/null @@ -1,44 +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.qpidity.security; - -import java.security.Provider; -import java.security.Security; -import java.util.Map; - -public class JCAProvider extends Provider -{ - public JCAProvider(Map providerMap) - { - super("AMQSASLProvider", 1.0, "A JCA provider that registers all " + - "AMQ SASL providers that want to be registered"); - register(providerMap); - Security.addProvider(this); - } - - private void register(Map providerMap) - { - for (Map.Entry me :providerMap.entrySet()) - { - put("SaslClientFactory." + me.getKey(), me.getValue().getName()); - } - } -} \ No newline at end of file diff --git a/java/common/src/main/java/org/apache/qpidity/security/UsernamePasswordCallbackHandler.java b/java/common/src/main/java/org/apache/qpidity/security/UsernamePasswordCallbackHandler.java deleted file mode 100644 index 0fd647e015..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/security/UsernamePasswordCallbackHandler.java +++ /dev/null @@ -1,60 +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.qpidity.security; - -import java.io.IOException; - -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.NameCallback; -import javax.security.auth.callback.PasswordCallback; -import javax.security.auth.callback.UnsupportedCallbackException; - -public class UsernamePasswordCallbackHandler implements AMQPCallbackHandler -{ - private String _username; - private String _password; - - public void initialise(String username,String password) - { - _username = username; - _password = password; - } - - public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException - { - for (int i = 0; i < callbacks.length; i++) - { - Callback cb = callbacks[i]; - if (cb instanceof NameCallback) - { - ((NameCallback)cb).setName(_username); - } - else if (cb instanceof PasswordCallback) - { - ((PasswordCallback)cb).setPassword((_password).toCharArray()); - } - else - { - throw new UnsupportedCallbackException(cb); - } - } - } -} diff --git a/java/common/src/main/java/org/apache/qpidity/security/amqplain/AmqPlainSaslClient.java b/java/common/src/main/java/org/apache/qpidity/security/amqplain/AmqPlainSaslClient.java deleted file mode 100644 index 6e4a0218d2..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/security/amqplain/AmqPlainSaslClient.java +++ /dev/null @@ -1,105 +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.qpidity.security.amqplain; - -import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.framing.FieldTableFactory; - -import javax.security.sasl.SaslClient; -import javax.security.sasl.SaslException; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.NameCallback; -import javax.security.auth.callback.PasswordCallback; -import javax.security.auth.callback.Callback; - -/** - * Implements the "AMQPlain" authentication protocol that uses FieldTables to send username and pwd. - * - */ -public class AmqPlainSaslClient implements SaslClient -{ - /** - * The name of this mechanism - */ - public static final String MECHANISM = "AMQPLAIN"; - - private CallbackHandler _cbh; - - public AmqPlainSaslClient(CallbackHandler cbh) - { - _cbh = cbh; - } - - public String getMechanismName() - { - return "AMQPLAIN"; - } - - public boolean hasInitialResponse() - { - return true; - } - - public byte[] evaluateChallenge(byte[] challenge) throws SaslException - { - // we do not care about the prompt or the default name - NameCallback nameCallback = new NameCallback("prompt", "defaultName"); - PasswordCallback pwdCallback = new PasswordCallback("prompt", false); - Callback[] callbacks = new Callback[]{nameCallback, pwdCallback}; - try - { - _cbh.handle(callbacks); - } - catch (Exception e) - { - throw new SaslException("Error handling SASL callbacks: " + e, e); - } - FieldTable table = FieldTableFactory.newFieldTable(); - table.setString("LOGIN", nameCallback.getName()); - table.setString("PASSWORD", new String(pwdCallback.getPassword())); - return table.getDataAsBytes(); - } - - public boolean isComplete() - { - return true; - } - - public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException - { - throw new SaslException("Not supported"); - } - - public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException - { - throw new SaslException("Not supported"); - } - - public Object getNegotiatedProperty(String propName) - { - return null; - } - - public void dispose() throws SaslException - { - _cbh = null; - } -} diff --git a/java/common/src/main/java/org/apache/qpidity/security/amqplain/AmqPlainSaslClientFactory.java b/java/common/src/main/java/org/apache/qpidity/security/amqplain/AmqPlainSaslClientFactory.java deleted file mode 100644 index abc881f433..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/security/amqplain/AmqPlainSaslClientFactory.java +++ /dev/null @@ -1,62 +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.qpidity.security.amqplain; - -import javax.security.sasl.SaslClientFactory; -import javax.security.sasl.SaslClient; -import javax.security.sasl.SaslException; -import javax.security.sasl.Sasl; -import javax.security.auth.callback.CallbackHandler; -import java.util.Map; - -public class AmqPlainSaslClientFactory implements SaslClientFactory -{ - public SaslClient createSaslClient(String[] mechanisms, String authorizationId, String protocol, String serverName, Map props, CallbackHandler cbh) throws SaslException - { - for (int i = 0; i < mechanisms.length; i++) - { - if (mechanisms[i].equals(AmqPlainSaslClient.MECHANISM)) - { - if (cbh == null) - { - throw new SaslException("CallbackHandler must not be null"); - } - return new AmqPlainSaslClient(cbh); - } - } - return null; - } - - public String[] getMechanismNames(Map props) - { - if (props.containsKey(Sasl.POLICY_NOPLAINTEXT) || - props.containsKey(Sasl.POLICY_NODICTIONARY) || - props.containsKey(Sasl.POLICY_NOACTIVE)) - { - // returned array must be non null according to interface documentation - return new String[0]; - } - else - { - return new String[]{AmqPlainSaslClient.MECHANISM}; - } - } -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/Binary.java b/java/common/src/main/java/org/apache/qpidity/transport/Binary.java deleted file mode 100644 index 1a1112d424..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/Binary.java +++ /dev/null @@ -1,129 +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.qpidity.transport; - - -/** - * Binary - * - */ - -public final class Binary -{ - - private byte[] bytes; - private int offset; - private int size; - private int hash = 0; - - public Binary(byte[] bytes, int offset, int size) - { - if (offset + size > bytes.length) - { - throw new ArrayIndexOutOfBoundsException(); - } - - this.bytes = bytes; - this.offset = offset; - this.size = size; - } - - public Binary(byte[] bytes) - { - this(bytes, 0, bytes.length); - } - - public final byte[] array() - { - return bytes; - } - - public final int offset() - { - return offset; - } - - public final int size() - { - return size; - } - - public final Binary slice(int low, int high) - { - int sz; - - if (high < 0) - { - sz = size + high; - } - else - { - sz = high - low; - } - - if (sz < 0) - { - sz = 0; - } - - return new Binary(bytes, offset + low, sz); - } - - public final int hashCode() - { - if (hash == 0) - { - int hc = 0; - for (int i = 0; i < size; i++) - { - hc = 31*hc + (0xFF & bytes[offset + i]); - } - hash = hc; - } - - return hash; - } - - public final boolean equals(Object o) - { - if (!(o instanceof Binary)) - { - return false; - } - - Binary buf = (Binary) o; - if (this.size != buf.size) - { - return false; - } - - for (int i = 0; i < size; i++) - { - if (bytes[offset + i] != buf.bytes[buf.offset + i]) - { - return false; - } - } - - return true; - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/Binding.java b/java/common/src/main/java/org/apache/qpidity/transport/Binding.java deleted file mode 100644 index 18ed97098d..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/Binding.java +++ /dev/null @@ -1,36 +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.qpidity.transport; - - -/** - * Binding - * - */ - -public interface Binding -{ - - E endpoint(Sender sender); - - Receiver receiver(E endpoint); - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/Channel.java b/java/common/src/main/java/org/apache/qpidity/transport/Channel.java deleted file mode 100644 index 50341d2c20..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/Channel.java +++ /dev/null @@ -1,233 +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.qpidity.transport; - -import org.apache.qpidity.transport.network.Frame; -import org.apache.qpidity.transport.util.Logger; - -import java.nio.ByteBuffer; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -import static org.apache.qpidity.transport.network.Frame.*; -import static org.apache.qpidity.transport.util.Functions.*; - - -/** - * Channel - * - * @author Rafael H. Schloming - */ - -public class Channel extends Invoker - implements Receiver, ProtocolDelegate -{ - - private static final Logger log = Logger.get(Channel.class); - - final private Connection connection; - final private int channel; - final private MethodDelegate delegate; - final private SessionDelegate sessionDelegate; - // session may be null - private Session session; - - private Lock commandLock = new ReentrantLock(); - private boolean first = true; - private ByteBuffer data = null; - private boolean batch = false; - - public Channel(Connection connection, int channel, SessionDelegate delegate) - { - this.connection = connection; - this.channel = channel; - this.delegate = new ChannelDelegate(); - this.sessionDelegate = delegate; - } - - public Connection getConnection() - { - return connection; - } - - public void received(ProtocolEvent event) - { - event.delegate(null, this); - } - - public void init(Void v, ProtocolHeader hdr) - { - connection.getConnectionDelegate().init(this, hdr); - } - - public void control(Void v, Method method) - { - switch (method.getEncodedTrack()) - { - case L1: - method.dispatch(this, connection.getConnectionDelegate()); - break; - case L2: - method.dispatch(this, delegate); - break; - case L3: - method.delegate(session, sessionDelegate); - break; - default: - throw new IllegalStateException - ("unknown track: " + method.getEncodedTrack()); - } - } - - public void command(Void v, Method method) - { - method.delegate(session, sessionDelegate); - } - - public void header(Void v, Header header) - { - header.delegate(session, sessionDelegate); - } - - public void data(Void v, Data data) - { - data.delegate(session, sessionDelegate); - } - - public void error(Void v, ProtocolError error) - { - throw new RuntimeException(error.getMessage()); - } - - public void exception(Throwable t) - { - session.exception(t); - } - - public void closed() - { - log.debug("channel closed: ", this); - if (session != null) - { - session.closed(); - } - connection.removeChannel(channel); - } - - public int getEncodedChannel() { - return channel; - } - - public Session getSession() - { - return session; - } - - void setSession(Session session) - { - this.session = session; - } - - private void emit(ProtocolEvent event) - { - event.setChannel(channel); - connection.send(event); - } - - public void method(Method m) - { - if (m.getEncodedTrack() == Frame.L4) - { - commandLock.lock(); - } - - emit(m); - - if (!m.isBatch() && !m.hasPayload()) - { - connection.flush(); - } - - batch = m.isBatch(); - - if (m.getEncodedTrack() == Frame.L4 && !m.hasPayload()) - { - commandLock.unlock(); - } - } - - public void header(Header header) - { - emit(header); - } - - public void data(ByteBuffer buf) - { - if (data != null) - { - emit(new Data(data, first, false)); - first = false; - } - - data = buf; - } - - public void data(String str) - { - data(str.getBytes()); - } - - public void data(byte[] bytes) - { - data(ByteBuffer.wrap(bytes)); - } - - public void end() - { - emit(new Data(data, first, true)); - first = true; - data = null; - if (!batch) - { - connection.flush(); - } - commandLock.unlock(); - } - - protected void invoke(Method m) - { - method(m); - } - - protected Future invoke(Method m, Class cls) - { - throw new UnsupportedOperationException(); - } - - public String toString() - { - return String.format("%s:%s", connection, channel); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/ChannelDelegate.java b/java/common/src/main/java/org/apache/qpidity/transport/ChannelDelegate.java deleted file mode 100644 index 96578ffeb8..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/ChannelDelegate.java +++ /dev/null @@ -1,54 +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.qpidity.transport; - -import java.util.UUID; - - -/** - * ChannelDelegate - * - * @author Rafael H. Schloming - */ - -class ChannelDelegate extends MethodDelegate -{ - - public @Override void sessionAttach(Channel channel, SessionAttach atch) - { - Session ssn = new Session(atch.getName()); - ssn.attach(channel); - ssn.sessionAttached(ssn.getName()); - } - - public @Override void sessionDetached(Channel channel, SessionDetached closed) - { - channel.closed(); - } - - public @Override void sessionDetach(Channel channel, SessionDetach dtc) - { - channel.getSession().closed(); - channel.sessionDetached(dtc.getName(), SessionDetachCode.NORMAL); - channel.closed(); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/ClientDelegate.java b/java/common/src/main/java/org/apache/qpidity/transport/ClientDelegate.java deleted file mode 100644 index e770157af4..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/ClientDelegate.java +++ /dev/null @@ -1,40 +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.qpidity.transport; - - -/** - * ClientDelegate - * - */ - -public abstract class ClientDelegate extends ConnectionDelegate -{ - - public void init(Channel ch, ProtocolHeader hdr) - { - if (hdr.getMajor() != 0 && hdr.getMinor() != 10) - { - throw new ProtocolVersionException(hdr.getMajor(), hdr.getMinor()); - } - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/Connection.java b/java/common/src/main/java/org/apache/qpidity/transport/Connection.java deleted file mode 100644 index d83bc7d2f5..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/Connection.java +++ /dev/null @@ -1,175 +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.qpidity.transport; - -import org.apache.qpidity.transport.util.Logger; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import java.nio.ByteBuffer; - - -/** - * Connection - * - * @author Rafael H. Schloming - * - * @todo the channels map should probably be replaced with something - * more efficient, e.g. an array or a map implementation that can use - * short instead of Short - */ - -public class Connection - implements Receiver, Sender -{ - - private static final Logger log = Logger.get(Connection.class); - - final private Sender sender; - final private ConnectionDelegate delegate; - private int channelMax = 1; - // want to make this final - private int _connectionId; - - final private Map channels = new HashMap(); - - public Connection(Sender sender, - ConnectionDelegate delegate) - { - this.sender = sender; - this.delegate = delegate; - } - - public void setConnectionId(int id) - { - _connectionId = id; - } - - public int getConnectionId() - { - return _connectionId; - } - - public ConnectionDelegate getConnectionDelegate() - { - return delegate; - } - - public void received(ProtocolEvent event) - { - log.debug("RECV: [%s] %s", this, event); - Channel channel = getChannel(event.getChannel()); - channel.received(event); - } - - public void send(ProtocolEvent event) - { - log.debug("SEND: [%s] %s", this, event); - sender.send(event); - } - - public void flush() - { - log.debug("FLUSH: [%s]", this); - sender.flush(); - } - - public int getChannelMax() - { - return channelMax; - } - - void setChannelMax(int max) - { - channelMax = max; - } - - public Channel getChannel() - { - synchronized (channels) - { - for (int i = 0; i < getChannelMax(); i++) - { - if (!channels.containsKey(i)) - { - return getChannel(i); - } - } - - throw new RuntimeException("no more channels available"); - } - } - - public Channel getChannel(int number) - { - synchronized (channels) - { - Channel channel = channels.get(number); - if (channel == null) - { - channel = new Channel(this, number, delegate.getSessionDelegate()); - channels.put(number, channel); - } - return channel; - } - } - - void removeChannel(int number) - { - synchronized (channels) - { - channels.remove(number); - } - } - - public void exception(Throwable t) - { - delegate.exception(t); - } - - public void closed() - { - log.debug("connection closed: %s", this); - synchronized (channels) - { - List values = new ArrayList(channels.values()); - for (Channel ch : values) - { - ch.closed(); - } - } - delegate.closed(); - } - - public void close() - { - sender.close(); - } - - public String toString() - { - return String.format("conn:%x", System.identityHashCode(this)); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/ConnectionDelegate.java b/java/common/src/main/java/org/apache/qpidity/transport/ConnectionDelegate.java deleted file mode 100644 index 14bde3f18d..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/ConnectionDelegate.java +++ /dev/null @@ -1,281 +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.qpidity.transport; - -import org.apache.qpidity.transport.util.Logger; - -import org.apache.qpidity.SecurityHelper; -import org.apache.qpidity.QpidException; - -import java.io.UnsupportedEncodingException; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.Lock; - -import javax.security.sasl.Sasl; -import javax.security.sasl.SaslClient; -import javax.security.sasl.SaslException; -import javax.security.sasl.SaslServer; - - -/** - * ConnectionDelegate - * - * @author Rafael H. Schloming - */ - -/** - * Currently only implemented client specific methods - * the server specific methods are dummy impls for testing - * - * the connectionClose is kind of different for both sides - */ -public abstract class ConnectionDelegate extends MethodDelegate -{ - - private static final Logger log = Logger.get(ConnectionDelegate.class); - - private String _username = "guest"; - private String _password = "guest";; - private String _mechanism; - private String _virtualHost; - private SaslClient saslClient; - private SaslServer saslServer; - private String _locale = "utf8"; - private int maxFrame = 64*1024; - private Condition _negotiationComplete; - private Lock _negotiationCompleteLock; - - public abstract SessionDelegate getSessionDelegate(); - - public abstract void exception(Throwable t); - - public abstract void closed(); - - public void setCondition(Lock negotiationCompleteLock,Condition negotiationComplete) - { - _negotiationComplete = negotiationComplete; - _negotiationCompleteLock = negotiationCompleteLock; - } - - public void init(Channel ch, ProtocolHeader hdr) - { - ch.getConnection().send(new ProtocolHeader (1, hdr.getMajor(), hdr.getMinor())); - List plain = new ArrayList(); - plain.add("PLAIN"); - List utf8 = new ArrayList(); - utf8.add("utf8"); - ch.connectionStart(null, plain, utf8); - } - - // ---------------------------------------------- - // Client side - //----------------------------------------------- - @Override public void connectionStart(Channel context, ConnectionStart struct) - { - String mechanism = null; - byte[] response = null; - try - { - mechanism = SecurityHelper.chooseMechanism(struct.getMechanisms()); - saslClient = Sasl.createSaslClient(new String[]{ mechanism },null, "AMQP", "localhost", null, - SecurityHelper.createCallbackHandler(mechanism,_username,_password )); - response = saslClient.evaluateChallenge(new byte[0]); - } - catch (UnsupportedEncodingException e) - { - // need error handling - } - catch (SaslException e) - { - // need error handling - } - catch (QpidException e) - { - // need error handling - } - - Map props = new HashMap(); - context.connectionStartOk(props, mechanism, response, _locale); - } - - @Override public void connectionSecure(Channel context, ConnectionSecure struct) - { - try - { - byte[] response = saslClient.evaluateChallenge(struct.getChallenge()); - context.connectionSecureOk(response); - } - catch (SaslException e) - { - // need error handling - } - } - - @Override public void connectionTune(Channel context, ConnectionTune struct) - { - context.getConnection().setChannelMax(struct.getChannelMax()); - context.connectionTuneOk(struct.getChannelMax(), struct.getMaxFrameSize(), struct.getHeartbeatMax()); - context.connectionOpen(_virtualHost, null, Option.INSIST); - } - - - @Override public void connectionOpenOk(Channel context, ConnectionOpenOk struct) - { - List knownHosts = struct.getKnownHosts(); - if(_negotiationCompleteLock != null) - { - _negotiationCompleteLock.lock(); - try - { - _negotiationComplete.signalAll(); - } - finally - { - _negotiationCompleteLock.unlock(); - } - } - } - - public void connectionRedirect(Channel context, ConnectionRedirect struct) - { - // not going to bother at the moment - } - - // ---------------------------------------------- - // Server side - //----------------------------------------------- - @Override public void connectionStartOk(Channel context, ConnectionStartOk struct) - { - //set the client side locale on the server side - _locale = struct.getLocale(); - _mechanism = struct.getMechanism(); - - //try - //{ - //saslServer = Sasl.createSaslServer(_mechanism, "AMQP", "ABC",null,SecurityHelper.createCallbackHandler(_mechanism,_username,_password)); - //byte[] challenge = saslServer.evaluateResponse(struct.getResponse().getBytes()); - byte[] challenge = null; - if ( challenge == null) - { - context.connectionTune(Integer.MAX_VALUE, maxFrame, 0, Integer.MAX_VALUE); - } - else - { - try - { - context.connectionSecure(challenge); - } - catch(Exception e) - { - - } - } - - - /*} - catch (SaslException e) - { - // need error handling - } - catch (QpidException e) - { - // need error handling - }*/ - } - - @Override public void connectionSecureOk(Channel context, ConnectionSecureOk struct) - { - try - { - saslServer = Sasl.createSaslServer(_mechanism, "AMQP", "ABC",new HashMap(),SecurityHelper.createCallbackHandler(_mechanism,_username,_password)); - byte[] challenge = saslServer.evaluateResponse(struct.getResponse()); - if ( challenge == null) - { - context.connectionTune(Integer.MAX_VALUE, maxFrame, 0, Integer.MAX_VALUE); - } - else - { - try - { - context.connectionSecure(challenge); - } - catch(Exception e) - { - - } - } - - - } - catch (SaslException e) - { - // need error handling - } - catch (QpidException e) - { - // need error handling - } - } - - - @Override public void connectionOpen(Channel context, ConnectionOpen struct) - { - List hosts = new ArrayList(); - hosts.add("amqp:1223243232325"); - context.connectionOpenOk(hosts); - } - - public String getPassword() - { - return _password; - } - - public void setPassword(String password) - { - _password = password; - } - - public String getUsername() - { - return _username; - } - - public void setUsername(String username) - { - _username = username; - } - - public String getVirtualHost() - { - return _virtualHost; - } - - public void setVirtualHost(String host) - { - _virtualHost = host; - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/Data.java b/java/common/src/main/java/org/apache/qpidity/transport/Data.java deleted file mode 100644 index 31e5a99935..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/Data.java +++ /dev/null @@ -1,98 +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.qpidity.transport; - -import org.apache.qpidity.transport.network.Frame; - -import java.nio.ByteBuffer; - -import java.util.Collections; - -import static org.apache.qpidity.transport.util.Functions.*; - - -/** - * Data - * - */ - -public class Data implements ProtocolEvent -{ - - private final ByteBuffer data; - private final boolean first; - private final boolean last; - private int channel; - - public Data(ByteBuffer data, boolean first, boolean last) - { - this.data = data; - this.first = first; - this.last = last; - } - - public ByteBuffer getData() - { - return data.slice(); - } - - public boolean isFirst() - { - return first; - } - - public boolean isLast() - { - return last; - } - - public final int getChannel() - { - return channel; - } - - public final void setChannel(int channel) - { - this.channel = channel; - } - - public byte getEncodedTrack() - { - return Frame.L4; - } - - public void delegate(C context, ProtocolDelegate delegate) - { - delegate.data(context, this); - } - - public String toString() - { - StringBuffer str = new StringBuffer(); - str.append("ch="); - str.append(" "); - str.append("Data("); - str.append(str(data, 64)); - str.append(")"); - return str.toString(); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/Echo.java b/java/common/src/main/java/org/apache/qpidity/transport/Echo.java deleted file mode 100644 index ed323c7eac..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/Echo.java +++ /dev/null @@ -1,84 +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.qpidity.transport; - -import java.io.IOException; -import java.nio.ByteBuffer; - -import org.apache.qpidity.transport.network.mina.MinaHandler; - - -/** - * Echo - * - */ - -public class Echo extends SessionDelegate -{ - - private MessageTransfer xfr = null; - - public void messageTransfer(Session ssn, MessageTransfer xfr) - { - this.xfr = xfr; - ssn.invoke(xfr); - } - - public void header(Session ssn, Header hdr) - { - ssn.header(hdr); - } - - public void data(Session ssn, Data data) - { - ssn.data(data.getData()); - if (data.isLast()) - { - ssn.endData(); - } - - // XXX: should be able to get command-id from any segment - ssn.processed(xfr); - } - - public static final void main(String[] args) throws IOException - { - ConnectionDelegate delegate = new ConnectionDelegate() - { - public SessionDelegate getSessionDelegate() - { - return new Echo(); - } - public void exception(Throwable t) - { - t.printStackTrace(); - } - public void closed() {} - }; - - //hack - delegate.setUsername("guest"); - delegate.setPassword("guest"); - - MinaHandler.accept("0.0.0.0", 5672, delegate); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/Field.java b/java/common/src/main/java/org/apache/qpidity/transport/Field.java deleted file mode 100644 index ebbd59288b..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/Field.java +++ /dev/null @@ -1,83 +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.qpidity.transport; - -import org.apache.qpidity.transport.codec.Decoder; -import org.apache.qpidity.transport.codec.Encoder; - - -/** - * Field - * - */ - -public abstract class Field -{ - - private final Class container; - private final Class type; - private final String name; - private final int index; - - Field(Class container, Class type, String name, int index) - { - this.container = container; - this.type = type; - this.name = name; - this.index = index; - } - - public final Class getContainer() - { - return container; - } - - public final Class getType() - { - return type; - } - - public final String getName() - { - return name; - } - - public final int getIndex() - { - return index; - } - - protected final C check(Object struct) - { - return container.cast(struct); - } - - public abstract boolean has(Object struct); - - public abstract void has(Object struct, boolean value); - - public abstract T get(Object struct); - - public abstract void read(Decoder dec, Object struct); - - public abstract void write(Encoder enc, Object struct); - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/Future.java b/java/common/src/main/java/org/apache/qpidity/transport/Future.java deleted file mode 100644 index 8936f06831..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/Future.java +++ /dev/null @@ -1,37 +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.qpidity.transport; - - -/** - * Future - * - * @author Rafael H. Schloming - */ - -public interface Future -{ - - T get(); - - boolean isDone(); - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/Header.java b/java/common/src/main/java/org/apache/qpidity/transport/Header.java deleted file mode 100644 index 221fc37f58..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/Header.java +++ /dev/null @@ -1,123 +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.qpidity.transport; - -import org.apache.qpidity.transport.network.Frame; - -import java.util.List; -import java.nio.ByteBuffer; - - -/** - * Header - * - * @author Rafael H. Schloming - */ - -public class Header implements ProtocolEvent { - - private final List structs; - private ByteBuffer _buf; - private boolean _noPayload; - private int channel; - - public Header(List structs, boolean lastframe) - { - this.structs = structs; - _noPayload= lastframe; - } - - public List getStructs() - { - return structs; - } - - public void setBuf(ByteBuffer buf) - { - _buf = buf; - } - - public ByteBuffer getBuf() - { - return _buf; - } - public T get(Class klass) - { - for (Struct st : structs) - { - if (klass.isInstance(st)) - { - return klass.cast(st); - } - } - - return null; - } - - public final int getChannel() - { - return channel; - } - - public final void setChannel(int channel) - { - this.channel = channel; - } - - public byte getEncodedTrack() - { - return Frame.L4; - } - - public void delegate(C context, ProtocolDelegate delegate) - { - delegate.header(context, this); - } - - public boolean hasNoPayload() - { - return _noPayload; - } - - public String toString() - { - StringBuffer str = new StringBuffer(); - str.append("ch="); - str.append(channel); - str.append(" Header("); - boolean first = true; - for (Struct s : structs) - { - if (first) - { - first = false; - } - else - { - str.append(", "); - } - str.append(s); - } - str.append(")"); - return str.toString(); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/Method.java b/java/common/src/main/java/org/apache/qpidity/transport/Method.java deleted file mode 100644 index 6589cc79b4..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/Method.java +++ /dev/null @@ -1,141 +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.qpidity.transport; - -import org.apache.qpidity.transport.network.Frame; - -/** - * Method - * - * @author Rafael H. Schloming - */ - -public abstract class Method extends Struct implements ProtocolEvent -{ - - public static final Method create(int type) - { - // XXX: should generate separate factories for separate - // namespaces - return (Method) StructFactory.createInstruction(type); - } - - // XXX: command subclass? - private int id; - private int channel; - private boolean idSet = false; - private boolean sync = false; - private boolean batch = false; - - public final int getId() - { - return id; - } - - void setId(int id) - { - this.id = id; - this.idSet = true; - } - - public final int getChannel() - { - return channel; - } - - public final void setChannel(int channel) - { - this.channel = channel; - } - - public final boolean isSync() - { - return sync; - } - - final void setSync(boolean value) - { - this.sync = value; - } - - public final boolean isBatch() - { - return batch; - } - - final void setBatch(boolean value) - { - this.batch = value; - } - - public abstract boolean hasPayload(); - - public abstract byte getEncodedTrack(); - - public abstract void dispatch(C context, MethodDelegate delegate); - - public void delegate(C context, ProtocolDelegate delegate) - { - if (getEncodedTrack() == Frame.L4) - { - delegate.command(context, this); - } - else - { - delegate.control(context, this); - } - } - - public String toString() - { - StringBuilder str = new StringBuilder(); - - str.append("ch="); - str.append(channel); - - if (getEncodedTrack() == Frame.L4 && idSet) - { - str.append(" id="); - str.append(id); - } - - if (sync || batch) - { - str.append(" "); - str.append("["); - if (sync) - { - str.append("S"); - } - if (batch) - { - str.append("B"); - } - str.append("]"); - } - - str.append(" "); - str.append(super.toString()); - - return str.toString(); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/ProtocolDelegate.java b/java/common/src/main/java/org/apache/qpidity/transport/ProtocolDelegate.java deleted file mode 100644 index 028d570416..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/ProtocolDelegate.java +++ /dev/null @@ -1,44 +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.qpidity.transport; - - -/** - * ProtocolDelegate - * - */ - -public interface ProtocolDelegate -{ - - void init(C context, ProtocolHeader header); - - void control(C context, Method control); - - void command(C context, Method command); - - void header(C context, Header header); - - void data(C context, Data data); - - void error(C context, ProtocolError error); - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/ProtocolError.java b/java/common/src/main/java/org/apache/qpidity/transport/ProtocolError.java deleted file mode 100644 index 586695af22..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/ProtocolError.java +++ /dev/null @@ -1,83 +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.qpidity.transport; - -import org.apache.qpidity.transport.network.NetworkDelegate; -import org.apache.qpidity.transport.network.NetworkEvent; - - -/** - * ProtocolError - * - * @author Rafael H. Schloming - */ - -public final class ProtocolError implements NetworkEvent, ProtocolEvent -{ - - private int channel; - private final byte track; - private final String format; - private final Object[] args; - - public ProtocolError(byte track, String format, Object ... args) - { - this.track = track; - this.format = format; - this.args = args; - } - - public int getChannel() - { - return channel; - } - - public void setChannel(int channel) - { - this.channel = channel; - } - - public byte getEncodedTrack() - { - return track; - } - - public String getMessage() - { - return String.format(format, args); - } - - public void delegate(C context, ProtocolDelegate delegate) - { - delegate.error(context, this); - } - - public void delegate(NetworkDelegate delegate) - { - delegate.error(this); - } - - public String toString() - { - return String.format("protocol error: %s", getMessage()); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/ProtocolEvent.java b/java/common/src/main/java/org/apache/qpidity/transport/ProtocolEvent.java deleted file mode 100644 index 03439be9ce..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/ProtocolEvent.java +++ /dev/null @@ -1,40 +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.qpidity.transport; - - -/** - * ProtocolEvent - * - */ - -public interface ProtocolEvent -{ - - int getChannel(); - - void setChannel(int channel); - - byte getEncodedTrack(); - - void delegate(C context, ProtocolDelegate delegate); - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/ProtocolHeader.java b/java/common/src/main/java/org/apache/qpidity/transport/ProtocolHeader.java deleted file mode 100644 index eea945c7c6..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/ProtocolHeader.java +++ /dev/null @@ -1,116 +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.qpidity.transport; - -import java.nio.ByteBuffer; - -import org.apache.qpidity.transport.network.NetworkDelegate; -import org.apache.qpidity.transport.network.NetworkEvent; -import org.apache.qpidity.transport.network.Frame; - - -/** - * ProtocolHeader - * - * @author Rafael H. Schloming - */ - -public final class ProtocolHeader implements NetworkEvent, ProtocolEvent -{ - - private static final byte[] AMQP = {'A', 'M', 'Q', 'P' }; - private static final byte CLASS = 1; - - final private byte instance; - final private byte major; - final private byte minor; - private int channel; - - public ProtocolHeader(byte instance, byte major, byte minor) - { - this.instance = instance; - this.major = major; - this.minor = minor; - } - - public ProtocolHeader(int instance, int major, int minor) - { - this((byte) instance, (byte) major, (byte) minor); - } - - public byte getInstance() - { - return instance; - } - - public byte getMajor() - { - return major; - } - - public byte getMinor() - { - return minor; - } - - public int getChannel() - { - return channel; - } - - public void setChannel(int channel) - { - this.channel = channel; - } - - public byte getEncodedTrack() - { - return Frame.L1; - } - - public ByteBuffer toByteBuffer() - { - ByteBuffer buf = ByteBuffer.allocate(8); - buf.put(AMQP); - buf.put(CLASS); - buf.put(instance); - buf.put(major); - buf.put(minor); - buf.flip(); - return buf; - } - - public void delegate(C context, ProtocolDelegate delegate) - { - delegate.init(context, this); - } - - public void delegate(NetworkDelegate delegate) - { - delegate.init(this); - } - - public String toString() - { - return String.format("AMQP.%d %d-%d", instance, major, minor); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/ProtocolVersionException.java b/java/common/src/main/java/org/apache/qpidity/transport/ProtocolVersionException.java deleted file mode 100644 index 86fe7a3f3f..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/ProtocolVersionException.java +++ /dev/null @@ -1,52 +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.qpidity.transport; - - -/** - * ProtocolVersionException - * - */ - -public final class ProtocolVersionException extends TransportException -{ - - private final byte major; - private final byte minor; - - public ProtocolVersionException(byte major, byte minor) - { - super(String.format("version missmatch: %s-%s", major, minor)); - this.major = major; - this.minor = minor; - } - - public byte getMajor() - { - return this.major; - } - - public byte getMinor() - { - return this.minor; - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/Range.java b/java/common/src/main/java/org/apache/qpidity/transport/Range.java deleted file mode 100644 index 14522cd45f..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/Range.java +++ /dev/null @@ -1,125 +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.qpidity.transport; - -import java.util.ArrayList; -import java.util.List; - -import static org.apache.qpid.util.Serial.*; - - -/** - * Range - * - * @author Rafael H. Schloming - */ - -public final class Range -{ - private final int lower; - private final int upper; - - public Range(int lower, int upper) - { - this.lower = lower; - this.upper = upper; - } - - public int getLower() - { - return lower; - } - - public int getUpper() - { - return upper; - } - - public boolean includes(int value) - { - return le(lower, value) && le(value, upper); - } - - public boolean includes(Range range) - { - return includes(range.lower) && includes(range.upper); - } - - public boolean intersects(Range range) - { - return (includes(range.lower) || includes(range.upper) || - range.includes(lower) || range.includes(upper)); - } - - public boolean touches(Range range) - { - return (intersects(range) || - includes(range.upper + 1) || includes(range.lower - 1) || - range.includes(upper + 1) || range.includes(lower - 1)); - } - - public Range span(Range range) - { - return new Range(min(lower, range.lower), max(upper, range.upper)); - } - - public List subtract(Range range) - { - List result = new ArrayList(); - - if (includes(range.lower) && le(lower, range.lower - 1)) - { - result.add(new Range(lower, range.lower - 1)); - } - - if (includes(range.upper) && le(range.upper + 1, upper)) - { - result.add(new Range(range.upper + 1, upper)); - } - - if (result.isEmpty() && !range.includes(this)) - { - result.add(this); - } - - return result; - } - - public Range intersect(Range range) - { - int l = max(lower, range.lower); - int r = min(upper, range.upper); - if (gt(l, r)) - { - return null; - } - else - { - return new Range(l, r); - } - } - - public String toString() - { - return "[" + lower + ", " + upper + "]"; - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/RangeSet.java b/java/common/src/main/java/org/apache/qpidity/transport/RangeSet.java deleted file mode 100644 index e05e399262..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/RangeSet.java +++ /dev/null @@ -1,142 +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.qpidity.transport; - -import java.util.Iterator; -import java.util.ListIterator; -import java.util.LinkedList; - -import static org.apache.qpid.util.Serial.*; - -/** - * RangeSet - * - * @author Rafael H. Schloming - */ - -public final class RangeSet implements Iterable -{ - - private LinkedList ranges = new LinkedList(); - - public int size() - { - return ranges.size(); - } - - public Iterator iterator() - { - return ranges.iterator(); - } - - public boolean includes(Range range) - { - for (Range r : this) - { - if (r.includes(range)) - { - return true; - } - } - - return false; - } - - public boolean includes(int n) - { - for (Range r : this) - { - if (r.includes(n)) - { - return true; - } - } - - return false; - } - - public void add(Range range) - { - ListIterator it = ranges.listIterator(); - - while (it.hasNext()) - { - Range next = it.next(); - if (range.touches(next)) - { - it.remove(); - range = range.span(next); - } - else if (lt(range.getUpper(), next.getLower())) - { - it.previous(); - it.add(range); - return; - } - } - - it.add(range); - } - - public void add(int lower, int upper) - { - add(new Range(lower, upper)); - } - - public void add(int value) - { - add(value, value); - } - - public void clear() - { - ranges.clear(); - } - - public RangeSet copy() - { - RangeSet copy = new RangeSet(); - copy.ranges.addAll(ranges); - return copy; - } - - public String toString() - { - StringBuffer str = new StringBuffer(); - str.append("{"); - boolean first = true; - for (Range range : ranges) - { - if (first) - { - first = false; - } - else - { - str.append(", "); - } - str.append(range); - } - str.append("}"); - return str.toString(); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/Receiver.java b/java/common/src/main/java/org/apache/qpidity/transport/Receiver.java deleted file mode 100644 index 8952ebf2a5..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/Receiver.java +++ /dev/null @@ -1,38 +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.qpidity.transport; - - -/** - * Receiver - * - */ - -public interface Receiver -{ - - void received(T msg); - - void exception(Throwable t); - - void closed(); - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/Result.java b/java/common/src/main/java/org/apache/qpidity/transport/Result.java deleted file mode 100644 index 2126a76a53..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/Result.java +++ /dev/null @@ -1,30 +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.qpidity.transport; - - -/** - * Result - * - * @author Rafael H. Schloming - */ - -public abstract class Result extends Struct {} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/Sender.java b/java/common/src/main/java/org/apache/qpidity/transport/Sender.java deleted file mode 100644 index ba3e67e578..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/Sender.java +++ /dev/null @@ -1,38 +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.qpidity.transport; - - -/** - * Sender - * - */ - -public interface Sender -{ - - void send(T msg); - - void flush(); - - void close(); - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/Session.java b/java/common/src/main/java/org/apache/qpidity/transport/Session.java deleted file mode 100644 index 75dd9fc2ff..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/Session.java +++ /dev/null @@ -1,558 +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.qpidity.transport; - - -import org.apache.qpidity.transport.network.Frame; - -import org.apache.qpidity.transport.util.Logger; - -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; - -import static org.apache.qpidity.transport.Option.*; -import static org.apache.qpidity.transport.util.Functions.*; -import static org.apache.qpid.util.Serial.*; - -/** - * Session - * - * @author Rafael H. Schloming - */ - -public class Session extends Invoker -{ - - private static final Logger log = Logger.get(Session.class); - - private static boolean ENABLE_REPLAY = false; - - static - { - String enableReplay = "enable_command_replay"; - try - { - ENABLE_REPLAY = new Boolean(System.getProperties().getProperty(enableReplay, "false")); - } - catch (Exception e) - { - ENABLE_REPLAY = false; - } - } - - private byte[] name; - private long timeout = 60000; - private boolean autoSync = false; - - // channel may be null - Channel channel; - - // incoming command count - int commandsIn = 0; - // completed incoming commands - private final Object processedLock = new Object(); - private RangeSet processed = new RangeSet(); - private Range syncPoint = null; - - // outgoing command count - private int commandsOut = 0; - private Map commands = new HashMap(); - private int maxComplete = commandsOut - 1; - private boolean needSync = false; - - private AtomicBoolean closed = new AtomicBoolean(false); - - public Session(byte[] name) - { - this.name = name; - } - - public byte[] getName() - { - return name; - } - - public void setAutoSync(boolean value) - { - synchronized (commands) - { - this.autoSync = value; - } - } - - public Map getOutstandingCommands() - { - return commands; - } - - public int getCommandsOut() - { - return commandsOut; - } - - public int getCommandsIn() - { - return commandsIn; - } - - public int nextCommandId() - { - return commandsIn++; - } - - final void identify(Method cmd) - { - int id = nextCommandId(); - cmd.setId(id); - log.debug("ID: [%s] %s", this.channel, id); - if ((id % 65536) == 0) - { - flushProcessed(TIMELY_REPLY); - } - } - - public void processed(Method command) - { - processed(command.getId()); - } - - public void processed(int command) - { - processed(new Range(command, command)); - } - - public void processed(int lower, int upper) - { - - processed(new Range(lower, upper)); - } - - public void processed(Range range) - { - log.debug("%s processed(%s)", this, range); - - boolean flush; - synchronized (processedLock) - { - processed.add(range); - flush = syncPoint != null && processed.includes(syncPoint); - } - if (flush) - { - flushProcessed(); - } - } - - public void flushProcessed(Option ... options) - { - RangeSet copy; - synchronized (processedLock) - { - copy = processed.copy(); - } - sessionCompleted(copy, options); - } - - void knownComplete(RangeSet kc) - { - synchronized (processedLock) - { - RangeSet newProcessed = new RangeSet(); - for (Range pr : processed) - { - for (Range kr : kc) - { - for (Range r : pr.subtract(kr)) - { - newProcessed.add(r); - } - } - } - this.processed = newProcessed; - } - } - - void syncPoint() - { - int id = getCommandsIn() - 1; - log.debug("%s synced to %d", this, id); - Range range = new Range(0, id - 1); - boolean flush; - synchronized (processedLock) - { - flush = processed.includes(range); - if (!flush) - { - syncPoint = range; - } - } - if (flush) - { - flushProcessed(); - } - } - - public void attach(Channel channel) - { - this.channel = channel; - channel.setSession(this); - } - - public Method getCommand(int id) - { - synchronized (commands) - { - return commands.get(id); - } - } - - boolean complete(int lower, int upper) - { - log.debug("%s complete(%d, %d)", this, lower, upper); - synchronized (commands) - { - int old = maxComplete; - for (int id = max(maxComplete, lower); le(id, upper); id++) - { - commands.remove(id); - } - if (le(lower, maxComplete + 1)) - { - maxComplete = max(maxComplete, upper); - } - log.debug("%s commands remaining: %s", this, commands); - commands.notifyAll(); - return gt(maxComplete, old); - } - } - - public void invoke(Method m) - { - if (m.getEncodedTrack() == Frame.L4) - { - synchronized (commands) - { - int next = commandsOut++; - m.setId(next); - if (next == 0) - { - sessionCommandPoint(0, 0); - } - if (ENABLE_REPLAY) - { - commands.put(next, m); - } - if (autoSync) - { - m.setSync(true); - } - needSync = !m.isSync(); - channel.method(m); - if (autoSync && !m.hasPayload()) - { - sync(); - } - - // flush every 64K commands to avoid ambiguity on - // wraparound - if ((next % 65536) == 0) - { - sessionFlush(COMPLETED); - } - } - } - else - { - channel.method(m); - } - } - - public void header(Header header) - { - channel.header(header); - } - - public Header header(List structs) - { - Header res = new Header(structs, false); - header(res); - return res; - } - - public Header header(Struct ... structs) - { - return header(Arrays.asList(structs)); - } - - public void data(ByteBuffer buf) - { - channel.data(buf); - } - - public void data(String str) - { - channel.data(str); - } - - public void data(byte[] bytes) - { - channel.data(bytes); - } - - public void endData() - { - channel.end(); - synchronized (commands) - { - if (autoSync) - { - sync(); - } - } - } - - public void sync() - { - sync(timeout); - } - - public void sync(long timeout) - { - log.debug("%s sync()", this); - synchronized (commands) - { - int point = commandsOut - 1; - - if (needSync && lt(maxComplete, point)) - { - executionSync(SYNC); - } - - long start = System.currentTimeMillis(); - long elapsed = 0; - while (!closed.get() && elapsed < timeout && lt(maxComplete, point)) - { - try { - log.debug("%s waiting for[%d]: %d, %s", this, point, - maxComplete, commands); - commands.wait(timeout - elapsed); - elapsed = System.currentTimeMillis() - start; - } - catch (InterruptedException e) - { - throw new RuntimeException(e); - } - } - - if (lt(maxComplete, point)) - { - if (closed.get()) - { - throw new SessionException(getExceptions()); - } - else - { - throw new RuntimeException - (String.format - ("timed out waiting for sync: complete = %s, point = %s", maxComplete, point)); - } - } - } - } - - private Map> results = - new HashMap>(); - private List exceptions = - new ArrayList(); - - void result(int command, Struct result) - { - ResultFuture future; - synchronized (results) - { - future = results.remove(command); - } - future.set(result); - } - - void addException(ExecutionException exc) - { - synchronized (exceptions) - { - exceptions.add(exc); - } - } - - List getExceptions() - { - synchronized (exceptions) - { - return new ArrayList(exceptions); - } - } - - protected Future invoke(Method m, Class klass) - { - synchronized (commands) - { - int command = commandsOut; - ResultFuture future = new ResultFuture(klass); - synchronized (results) - { - results.put(command, future); - } - invoke(m); - return future; - } - } - - private class ResultFuture implements Future - { - - private final Class klass; - private T result; - - private ResultFuture(Class klass) - { - this.klass = klass; - } - - private void set(Struct result) - { - synchronized (this) - { - this.result = klass.cast(result); - notifyAll(); - } - } - - public T get(long timeout) - { - synchronized (this) - { - long start = System.currentTimeMillis(); - long elapsed = 0; - while (!closed.get() && timeout - elapsed > 0 && !isDone()) - { - try - { - log.debug("%s waiting for result: %s", Session.this, this); - wait(timeout - elapsed); - elapsed = System.currentTimeMillis() - start; - } - catch (InterruptedException e) - { - throw new RuntimeException(e); - } - } - } - - if (isDone()) - { - return result; - } - else if (closed.get()) - { - throw new SessionException(getExceptions()); - } - else - { - return null; - } - } - - public T get() - { - return get(timeout); - } - - public boolean isDone() - { - return result != null; - } - - public String toString() - { - return String.format("Future(%s)", isDone() ? result : klass); - } - - } - - public void close() - { - sessionRequestTimeout(0); - sessionDetach(name); - synchronized (commands) - { - long start = System.currentTimeMillis(); - long elapsed = 0; - try - { - while (!closed.get() && elapsed < timeout) - { - commands.wait(timeout - elapsed); - elapsed = System.currentTimeMillis() - start; - } - } - catch (InterruptedException e) - { - throw new RuntimeException(e); - } - } - } - - public void exception(Throwable t) - { - log.error(t, "caught exception"); - } - - public void closed() - { - closed.set(true); - synchronized (commands) - { - commands.notifyAll(); - } - synchronized (results) - { - for (ResultFuture result : results.values()) - { - synchronized(result) - { - result.notifyAll(); - } - } - } - channel.setSession(null); - channel = null; - } - - public String toString() - { - return String.format("ssn:%s", str(name)); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/SessionDelegate.java b/java/common/src/main/java/org/apache/qpidity/transport/SessionDelegate.java deleted file mode 100644 index 0e289c54e9..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/SessionDelegate.java +++ /dev/null @@ -1,129 +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.qpidity.transport; - -import org.apache.qpidity.transport.network.Frame; - - -/** - * SessionDelegate - * - * @author Rafael H. Schloming - */ - -public abstract class SessionDelegate - extends MethodDelegate - implements ProtocolDelegate -{ - public void init(Session ssn, ProtocolHeader hdr) { } - - public void control(Session ssn, Method method) { - method.dispatch(ssn, this); - } - - public void command(Session ssn, Method method) { - ssn.identify(method); - method.dispatch(ssn, this); - if (!method.hasPayload()) - { - ssn.processed(method); - } - } - - public void header(Session ssn, Header header) { } - - public void data(Session ssn, Data data) { } - - public void error(Session ssn, ProtocolError error) { } - - @Override public void executionResult(Session ssn, ExecutionResult result) - { - ssn.result(result.getCommandId(), result.getValue()); - } - - @Override public void executionException(Session ssn, ExecutionException exc) - { - ssn.addException(exc); - } - - @Override public void sessionCompleted(Session ssn, SessionCompleted cmp) - { - RangeSet ranges = cmp.getCommands(); - RangeSet known = null; - if (cmp.getTimelyReply()) - { - known = new RangeSet(); - } - - if (ranges != null) - { - for (Range range : ranges) - { - boolean advanced = ssn.complete(range.getLower(), range.getUpper()); - if (advanced && known != null) - { - known.add(range); - } - } - } - - if (known != null) - { - ssn.sessionKnownCompleted(known); - } - } - - @Override public void sessionKnownCompleted(Session ssn, SessionKnownCompleted kcmp) - { - RangeSet kc = kcmp.getCommands(); - if (kc != null) - { - ssn.knownComplete(kc); - } - } - - @Override public void sessionFlush(Session ssn, SessionFlush flush) - { - if (flush.getCompleted()) - { - ssn.flushProcessed(); - } - if (flush.getConfirmed()) - { - ssn.flushProcessed(); - } - if (flush.getExpected()) - { - throw new Error("not implemented"); - } - } - - @Override public void sessionCommandPoint(Session ssn, SessionCommandPoint scp) - { - ssn.commandsIn = scp.getCommandId(); - } - - @Override public void executionSync(Session ssn, ExecutionSync sync) - { - ssn.syncPoint(); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/SessionException.java b/java/common/src/main/java/org/apache/qpidity/transport/SessionException.java deleted file mode 100644 index fc866f3694..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/SessionException.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.qpidity.transport; - -import java.util.List; - -/** - * SessionException - * - */ - -public class SessionException extends RuntimeException -{ - - private List exceptions; - - public SessionException(List exceptions) - { - super(exceptions.isEmpty() ? "" : exceptions.toString()); - this.exceptions = exceptions; - } - - public List getExceptions() - { - return exceptions; - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/Struct.java b/java/common/src/main/java/org/apache/qpidity/transport/Struct.java deleted file mode 100644 index a15d0a1fb8..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/Struct.java +++ /dev/null @@ -1,142 +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.qpidity.transport; - -import java.util.List; -import java.util.Map; - -import org.apache.qpidity.transport.codec.Decoder; -import org.apache.qpidity.transport.codec.Encodable; -import org.apache.qpidity.transport.codec.Encoder; - - -/** - * Struct - * - * @author Rafael H. Schloming - */ - -public abstract class Struct implements Encodable -{ - - public static Struct create(int type) - { - return StructFactory.create(type); - } - - boolean dirty = true; - - public boolean isDirty() - { - return dirty; - } - - public void setDirty(boolean dirty) - { - this.dirty = dirty; - } - - public abstract int getStructType(); - - public abstract int getSizeWidth(); - - public abstract int getPackWidth(); - - public final int getEncodedType() - { - int type = getStructType(); - if (type < 0) - { - throw new UnsupportedOperationException(); - } - return type; - } - - private final boolean isBit(Field f) - { - return f.getType().equals(Boolean.class); - } - - private final boolean packed() - { - return getPackWidth() > 0; - } - - private final boolean encoded(Field f) - { - return !packed() || !isBit(f) && f.has(this); - } - - private final int getFlagWidth() - { - return (getFields().size() + 7)/8; - } - - private final int getPaddWidth() - { - int pw = getPackWidth() - getFlagWidth(); - assert pw > 0; - return pw; - } - - private final int getFlagCount() - { - return 8*getPackWidth(); - } - - private final int getReservedFlagCount() - { - return getFlagCount() - getFields().size(); - } - - public abstract void read(Decoder dec); - - public abstract void write(Encoder enc); - - public abstract Map getFields(); - - public String toString() - { - StringBuilder str = new StringBuilder(); - str.append(getClass().getSimpleName()); - - str.append("("); - boolean first = true; - for (Map.Entry me : getFields().entrySet()) - { - if (first) - { - first = false; - } - else - { - str.append(", "); - } - str.append(me.getKey()); - str.append("="); - str.append(me.getValue()); - } - str.append(")"); - - return str.toString(); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/TransportException.java b/java/common/src/main/java/org/apache/qpidity/transport/TransportException.java deleted file mode 100644 index 593209df82..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/TransportException.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.qpidity.transport; - - -/** - * TransportException - */ - -public class TransportException extends RuntimeException -{ - - public TransportException(String msg) - { - super(msg); - } - - public TransportException(String msg, Throwable cause) - { - super(msg, cause); - } - - public TransportException(Throwable cause) - { - super(cause); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractDecoder.java b/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractDecoder.java deleted file mode 100644 index 77899ad712..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractDecoder.java +++ /dev/null @@ -1,470 +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.qpidity.transport.codec; - -import java.io.UnsupportedEncodingException; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import org.apache.qpidity.transport.Binary; -import org.apache.qpidity.transport.RangeSet; -import org.apache.qpidity.transport.Struct; -import org.apache.qpidity.transport.Type; - -import static org.apache.qpidity.transport.util.Functions.*; - - -/** - * AbstractDecoder - * - * @author Rafael H. Schloming - */ - -abstract class AbstractDecoder implements Decoder -{ - - private final Map str8cache = new LinkedHashMap() - { - @Override protected boolean removeEldestEntry(Map.Entry me) - { - return size() > 4*1024; - } - }; - - protected abstract byte doGet(); - - protected abstract void doGet(byte[] bytes); - - protected byte get() - { - return doGet(); - } - - protected void get(byte[] bytes) - { - doGet(bytes); - } - - protected Binary get(int size) - { - byte[] bytes = new byte[size]; - get(bytes); - return new Binary(bytes); - } - - protected short uget() - { - return (short) (0xFF & get()); - } - - public short readUint8() - { - return uget(); - } - - public int readUint16() - { - int i = uget() << 8; - i |= uget(); - return i; - } - - public long readUint32() - { - long l = uget() << 24; - l |= uget() << 16; - l |= uget() << 8; - l |= uget(); - return l; - } - - public int readSequenceNo() - { - return (int) readUint32(); - } - - public long readUint64() - { - long l = 0; - for (int i = 0; i < 8; i++) - { - l |= ((long) (0xFF & get())) << (56 - i*8); - } - return l; - } - - public long readDatetime() - { - return readUint64(); - } - - private static final String decode(byte[] bytes, int offset, int length, String charset) - { - try - { - return new String(bytes, offset, length, charset); - } - catch (UnsupportedEncodingException e) - { - throw new RuntimeException(e); - } - } - - private static final String decode(byte[] bytes, String charset) - { - return decode(bytes, 0, bytes.length, charset); - } - - public String readStr8() - { - short size = readUint8(); - Binary bin = get(size); - String str = str8cache.get(bin); - if (str == null) - { - str = decode(bin.array(), bin.offset(), bin.size(), "UTF-8"); - str8cache.put(bin, str); - } - return str; - } - - public String readStr16() - { - int size = readUint16(); - byte[] bytes = new byte[size]; - get(bytes); - return decode(bytes, "UTF-8"); - } - - public byte[] readVbin8() - { - int size = readUint8(); - byte[] bytes = new byte[size]; - get(bytes); - return bytes; - } - - public byte[] readVbin16() - { - int size = readUint16(); - byte[] bytes = new byte[size]; - get(bytes); - return bytes; - } - - public byte[] readVbin32() - { - int size = (int) readUint32(); - byte[] bytes = new byte[size]; - get(bytes); - return bytes; - } - - public RangeSet readSequenceSet() - { - int count = readUint16()/8; - if (count == 0) - { - return null; - } - else - { - RangeSet ranges = new RangeSet(); - for (int i = 0; i < count; i++) - { - ranges.add(readSequenceNo(), readSequenceNo()); - } - return ranges; - } - } - - public RangeSet readByteRanges() - { - throw new Error("not implemented"); - } - - public UUID readUuid() - { - long msb = readUint64(); - long lsb = readUint64(); - return new UUID(msb, lsb); - } - - public String readContent() - { - throw new Error("Deprecated"); - } - - public Struct readStruct(int type) - { - Struct st = Struct.create(type); - int width = st.getSizeWidth(); - if (width > 0) - { - long size = readSize(width); - if (size == 0) - { - return null; - } - } - if (type > 0) - { - int code = readUint16(); - assert code == type; - } - st.read(this); - return st; - } - - public Struct readStruct32() - { - long size = readUint32(); - if (size == 0) - { - return null; - } - else - { - int type = readUint16(); - Struct result = Struct.create(type); - result.read(this); - return result; - } - } - - public Map readMap() - { - long size = readUint32(); - - if (size == 0) - { - return null; - } - - long count = readUint32(); - - if (count == 0) - { - return Collections.EMPTY_MAP; - } - - Map result = new LinkedHashMap(); - for (int i = 0; i < count; i++) - { - String key = readStr8(); - byte code = get(); - Type t = getType(code); - Object value = read(t); - result.put(key, value); - } - - return result; - } - - public List readList() - { - long size = readUint32(); - - if (size == 0) - { - return null; - } - - long count = readUint32(); - - if (count == 0) - { - return Collections.EMPTY_LIST; - } - - List result = new ArrayList(); - for (int i = 0; i < count; i++) - { - byte code = get(); - Type t = getType(code); - Object value = read(t); - result.add(value); - } - return result; - } - - public List readArray() - { - long size = readUint32(); - - if (size == 0) - { - return null; - } - - byte code = get(); - Type t = getType(code); - long count = readUint32(); - - if (count == 0) - { - return Collections.EMPTY_LIST; - } - - List result = new ArrayList(); - for (int i = 0; i < count; i++) - { - Object value = read(t); - result.add(value); - } - return result; - } - - private Type getType(byte code) - { - Type type = Type.get(code); - if (type == null) - { - throw new IllegalArgumentException("unknown code: " + code); - } - else - { - return type; - } - } - - private long readSize(Type t) - { - if (t.fixed) - { - return t.width; - } - else - { - return readSize(t.width); - } - } - - private long readSize(int width) - { - switch (width) - { - case 1: - return readUint8(); - case 2: - return readUint16(); - case 4: - return readUint32(); - default: - throw new IllegalStateException("illegal width: " + width); - } - } - - private byte[] readBytes(Type t) - { - long size = readSize(t); - byte[] result = new byte[(int) size]; - get(result); - return result; - } - - private Object read(Type t) - { - switch (t) - { - case BIN8: - case UINT8: - return readUint8(); - case INT8: - return get(); - case CHAR: - return (char) get(); - case BOOLEAN: - return get() > 0; - - case BIN16: - case UINT16: - return readUint16(); - - case INT16: - return (short) readUint16(); - - case BIN32: - case UINT32: - return readUint32(); - - case CHAR_UTF32: - case INT32: - return (int) readUint32(); - - case FLOAT: - return Float.intBitsToFloat((int) readUint32()); - - case BIN64: - case UINT64: - case INT64: - case DATETIME: - return readUint64(); - - case DOUBLE: - return Double.longBitsToDouble(readUint64()); - - case UUID: - return readUuid(); - - case STR8: - return readStr8(); - - case STR16: - return readStr16(); - - case STR8_LATIN: - case STR8_UTF16: - case STR16_LATIN: - case STR16_UTF16: - // XXX: need to do character conversion - return new String(readBytes(t)); - - case MAP: - return readMap(); - case LIST: - return readList(); - case ARRAY: - return readArray(); - case STRUCT32: - return readStruct32(); - - case BIN40: - case DEC32: - case BIN72: - case DEC64: - // XXX: what types are we supposed to use here? - return readBytes(t); - - case VOID: - return null; - - default: - return readBytes(t); - } - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractEncoder.java b/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractEncoder.java deleted file mode 100644 index 8908b94ed3..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractEncoder.java +++ /dev/null @@ -1,620 +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.qpidity.transport.codec; - -import java.io.UnsupportedEncodingException; - -import java.nio.ByteBuffer; - -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import org.apache.qpidity.transport.Range; -import org.apache.qpidity.transport.RangeSet; -import org.apache.qpidity.transport.Struct; -import org.apache.qpidity.transport.Type; - -import static org.apache.qpidity.transport.util.Functions.*; - - -/** - * AbstractEncoder - * - * @author Rafael H. Schloming - */ - -abstract class AbstractEncoder implements Encoder -{ - - private static Map,Type> ENCODINGS = new HashMap,Type>(); - static - { - ENCODINGS.put(Boolean.class, Type.BOOLEAN); - ENCODINGS.put(String.class, Type.STR16); - ENCODINGS.put(Long.class, Type.INT64); - ENCODINGS.put(Integer.class, Type.INT32); - ENCODINGS.put(Short.class, Type.INT16); - ENCODINGS.put(Byte.class, Type.INT8); - ENCODINGS.put(Map.class, Type.MAP); - ENCODINGS.put(List.class, Type.LIST); - ENCODINGS.put(Float.class, Type.FLOAT); - ENCODINGS.put(Double.class, Type.DOUBLE); - ENCODINGS.put(Character.class, Type.CHAR); - ENCODINGS.put(byte[].class, Type.VBIN32); - } - - private final Map str8cache = new LinkedHashMap() - { - @Override protected boolean removeEldestEntry(Map.Entry me) - { - return size() > 4*1024; - } - }; - - protected abstract void doPut(byte b); - - protected abstract void doPut(ByteBuffer src); - - protected void put(byte b) - { - doPut(b); - } - - protected void put(ByteBuffer src) - { - doPut(src); - } - - protected void put(byte[] bytes) - { - put(ByteBuffer.wrap(bytes)); - } - - protected abstract int beginSize8(); - protected abstract void endSize8(int pos); - - protected abstract int beginSize16(); - protected abstract void endSize16(int pos); - - protected abstract int beginSize32(); - protected abstract void endSize32(int pos); - - public void writeUint8(short b) - { - assert b < 0x100; - - put((byte) b); - } - - public void writeUint16(int s) - { - assert s < 0x10000; - - put(lsb(s >>> 8)); - put(lsb(s)); - } - - public void writeUint32(long i) - { - assert i < 0x100000000L; - - put(lsb(i >>> 24)); - put(lsb(i >>> 16)); - put(lsb(i >>> 8)); - put(lsb(i)); - } - - public void writeSequenceNo(int i) - { - writeUint32(i); - } - - public void writeUint64(long l) - { - for (int i = 0; i < 8; i++) - { - put(lsb(l >> (56 - i*8))); - } - } - - - public void writeDatetime(long l) - { - writeUint64(l); - } - - private static final byte[] encode(String s, String charset) - { - try - { - return s.getBytes(charset); - } - catch (UnsupportedEncodingException e) - { - throw new RuntimeException(e); - } - } - - public void writeStr8(String s) - { - if (s == null) - { - s = ""; - } - - byte[] bytes = str8cache.get(s); - if (bytes == null) - { - bytes = encode(s, "UTF-8"); - str8cache.put(s, bytes); - } - writeUint8((short) bytes.length); - put(bytes); - } - - public void writeStr16(String s) - { - if (s == null) - { - s = ""; - } - - byte[] bytes = encode(s, "UTF-8"); - writeUint16(bytes.length); - put(bytes); - } - - public void writeVbin8(byte[] bytes) - { - if (bytes == null) { bytes = new byte[0]; } - if (bytes.length > 255) - { - throw new IllegalArgumentException("array too long: " + bytes.length); - } - writeUint8((short) bytes.length); - put(ByteBuffer.wrap(bytes)); - } - - public void writeVbin16(byte[] bytes) - { - if (bytes == null) { bytes = new byte[0]; } - writeUint16(bytes.length); - put(ByteBuffer.wrap(bytes)); - } - - public void writeVbin32(byte[] bytes) - { - if (bytes == null) { bytes = new byte[0]; } - writeUint32(bytes.length); - put(ByteBuffer.wrap(bytes)); - } - - public void writeSequenceSet(RangeSet ranges) - { - if (ranges == null) - { - writeUint16((short) 0); - } - else - { - writeUint16(ranges.size() * 8); - for (Range range : ranges) - { - writeSequenceNo(range.getLower()); - writeSequenceNo(range.getUpper()); - } - } - } - - public void writeByteRanges(RangeSet ranges) - { - throw new Error("not implemented"); - } - - public void writeUuid(UUID uuid) - { - long msb = 0; - long lsb = 0; - if (uuid != null) - { - msb = uuid.getMostSignificantBits(); - lsb = uuid.getLeastSignificantBits(); - } - writeUint64(msb); - writeUint64(lsb); - } - - public void writeStruct(int type, Struct s) - { - boolean empty = false; - if (s == null) - { - s = Struct.create(type); - empty = true; - } - - int width = s.getSizeWidth(); - int pos = -1; - if (width > 0) - { - pos = beginSize(width); - } - - if (type > 0) - { - writeUint16(type); - } - - s.write(this); - - if (width > 0) - { - endSize(width, pos); - } - } - - public void writeStruct32(Struct s) - { - if (s == null) - { - writeUint32(0); - } - else - { - int pos = beginSize32(); - writeUint16(s.getEncodedType()); - s.write(this); - endSize32(pos); - } - } - - private Type encoding(Object value) - { - if (value == null) - { - return Type.VOID; - } - - Class klass = value.getClass(); - Type type = resolve(klass); - - if (type == null) - { - throw new IllegalArgumentException - ("unable to resolve type: " + klass + ", " + value); - } - else - { - return type; - } - } - - static final Type resolve(Class klass) - { - Type type = ENCODINGS.get(klass); - if (type != null) - { - return type; - } - - Class sup = klass.getSuperclass(); - if (sup != null) - { - type = resolve(klass.getSuperclass()); - - if (type != null) - { - return type; - } - } - - for (Class iface : klass.getInterfaces()) - { - type = resolve(iface); - if (type != null) - { - return type; - } - } - - return null; - } - - public void writeMap(Map map) - { - int pos = beginSize32(); - if (map != null) - { - writeUint32(map.size()); - writeMapEntries(map); - } - endSize32(pos); - } - - protected void writeMapEntries(Map map) - { - for (Map.Entry entry : map.entrySet()) - { - String key = entry.getKey(); - Object value = entry.getValue(); - Type type = encoding(value); - writeStr8(key); - put(type.code); - write(type, value); - } - } - - public void writeList(List list) - { - int pos = beginSize32(); - if (list != null) - { - writeUint32(list.size()); - writeListEntries(list); - } - endSize32(pos); - } - - protected void writeListEntries(List list) - { - for (Object value : list) - { - Type type = encoding(value); - put(type.code); - write(type, value); - } - } - - public void writeArray(List array) - { - int pos = beginSize32(); - if (array != null) - { - writeArrayEntries(array); - } - endSize32(pos); - } - - protected void writeArrayEntries(List array) - { - Type type; - - if (array.isEmpty()) - { - return; - } - else - { - type = encoding(array.get(0)); - } - - put(type.code); - - writeUint32(array.size()); - - for (Object value : array) - { - write(type, value); - } - } - - private void writeSize(Type t, int size) - { - if (t.fixed) - { - if (size != t.width) - { - throw new IllegalArgumentException - ("size does not match fixed width " + t.width + ": " + - size); - } - } - else - { - writeSize(t.width, size); - } - } - - private void writeSize(int width, int size) - { - // XXX: should check lengths - switch (width) - { - case 1: - writeUint8((short) size); - break; - case 2: - writeUint16(size); - break; - case 4: - writeUint32(size); - break; - default: - throw new IllegalStateException("illegal width: " + width); - } - } - - private int beginSize(int width) - { - switch (width) - { - case 1: - return beginSize8(); - case 2: - return beginSize16(); - case 4: - return beginSize32(); - default: - throw new IllegalStateException("illegal width: " + width); - } - } - - private void endSize(int width, int pos) - { - switch (width) - { - case 1: - endSize8(pos); - break; - case 2: - endSize16(pos); - break; - case 4: - endSize32(pos); - break; - default: - throw new IllegalStateException("illegal width: " + width); - } - } - - private void writeBytes(Type t, byte[] bytes) - { - writeSize(t, bytes.length); - put(bytes); - } - - private T coerce(Class klass, Object value) - { - if (klass.isInstance(value)) - { - return klass.cast(value); - } - else - { - throw new IllegalArgumentException("" + value); - } - } - - private void write(Type t, Object value) - { - switch (t) - { - case BIN8: - case UINT8: - writeUint8(coerce(Short.class, value)); - break; - case INT8: - put(coerce(Byte.class, value)); - break; - case CHAR: - put((byte) ((char)coerce(Character.class, value))); - break; - case BOOLEAN: - if (coerce(Boolean.class, value)) - { - put((byte) 1); - } - else - { - put((byte) 0); - } - break; - - case BIN16: - case UINT16: - writeUint16(coerce(Integer.class, value)); - break; - - case INT16: - writeUint16(coerce(Short.class, value)); - break; - - case BIN32: - case UINT32: - writeUint32(coerce(Long.class, value)); - break; - - case CHAR_UTF32: - case INT32: - writeUint32(coerce(Integer.class, value)); - break; - - case FLOAT: - writeUint32(Float.floatToIntBits(coerce(Float.class, value))); - break; - - case BIN64: - case UINT64: - case INT64: - case DATETIME: - writeUint64(coerce(Long.class, value)); - break; - - case DOUBLE: - long bits = Double.doubleToLongBits(coerce(Double.class, value)); - writeUint64(bits); - break; - - case UUID: - writeUuid(coerce(UUID.class, value)); - break; - - case STR8: - writeStr8(coerce(String.class, value)); - break; - - case STR16: - writeStr16(coerce(String.class, value)); - break; - - case STR8_LATIN: - case STR8_UTF16: - case STR16_LATIN: - case STR16_UTF16: - // XXX: need to do character conversion - writeBytes(t, coerce(String.class, value).getBytes()); - break; - - case MAP: - writeMap((Map) coerce(Map.class, value)); - break; - case LIST: - writeList(coerce(List.class, value)); - break; - case ARRAY: - writeArray(coerce(List.class, value)); - break; - case STRUCT32: - writeStruct32(coerce(Struct.class, value)); - break; - - case BIN40: - case DEC32: - case BIN72: - case DEC64: - // XXX: what types are we supposed to use here? - writeBytes(t, coerce(byte[].class, value)); - break; - - case VOID: - break; - - default: - writeBytes(t, coerce(byte[].class, value)); - break; - } - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/codec/BBDecoder.java b/java/common/src/main/java/org/apache/qpidity/transport/codec/BBDecoder.java deleted file mode 100644 index f036fd8dee..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/codec/BBDecoder.java +++ /dev/null @@ -1,96 +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.qpidity.transport.codec; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -import org.apache.qpidity.transport.Binary; - - -/** - * BBDecoder - * - * @author Rafael H. Schloming - */ - -public final class BBDecoder extends AbstractDecoder -{ - - private ByteBuffer in; - - public void init(ByteBuffer in) - { - this.in = in; - this.in.order(ByteOrder.BIG_ENDIAN); - } - - protected byte doGet() - { - return in.get(); - } - - protected void doGet(byte[] bytes) - { - in.get(bytes); - } - - protected Binary get(int size) - { - if (in.hasArray()) - { - byte[] bytes = in.array(); - Binary bin = new Binary(bytes, in.arrayOffset() + in.position(), size); - in.position(in.position() + size); - return bin; - } - else - { - return super.get(size); - } - } - - public boolean hasRemaining() - { - return in.hasRemaining(); - } - - public short readUint8() - { - return (short) (0xFF & in.get()); - } - - public int readUint16() - { - return 0xFFFF & in.getShort(); - } - - public long readUint32() - { - return 0xFFFFFFFFL & in.getInt(); - } - - public long readUint64() - { - return in.getLong(); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/codec/BBEncoder.java b/java/common/src/main/java/org/apache/qpidity/transport/codec/BBEncoder.java deleted file mode 100644 index a976d38efc..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/codec/BBEncoder.java +++ /dev/null @@ -1,227 +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.qpidity.transport.codec; - -import java.nio.BufferOverflowException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - - -/** - * BBEncoder - * - * @author Rafael H. Schloming - */ - -public final class BBEncoder extends AbstractEncoder -{ - - private ByteBuffer out; - - public BBEncoder(int capacity) { - out = ByteBuffer.allocate(capacity); - out.order(ByteOrder.BIG_ENDIAN); - } - - public void init() - { - out.clear(); - } - - public ByteBuffer done() - { - out.flip(); - ByteBuffer encoded = ByteBuffer.allocate(out.remaining()); - encoded.put(out); - encoded.flip(); - return encoded; - } - - private void grow(int size) - { - ByteBuffer old = out; - int capacity = old.capacity(); - out = ByteBuffer.allocate(Math.max(capacity + size, 2*capacity)); - out.order(ByteOrder.BIG_ENDIAN); - out.put(old); - } - - protected void doPut(byte b) - { - try - { - out.put(b); - } - catch (BufferOverflowException e) - { - grow(1); - out.put(b); - } - } - - protected void doPut(ByteBuffer src) - { - try - { - out.put(src); - } - catch (BufferOverflowException e) - { - grow(src.remaining()); - out.put(src); - } - } - - protected void put(byte[] bytes) - { - try - { - out.put(bytes); - } - catch (BufferOverflowException e) - { - grow(bytes.length); - out.put(bytes); - } - } - - public void writeUint8(short b) - { - assert b < 0x100; - - try - { - out.put((byte) b); - } - catch (BufferOverflowException e) - { - grow(1); - out.put((byte) b); - } - } - - public void writeUint16(int s) - { - assert s < 0x10000; - - try - { - out.putShort((short) s); - } - catch (BufferOverflowException e) - { - grow(2); - out.putShort((short) s); - } - } - - public void writeUint32(long i) - { - assert i < 0x100000000L; - - try - { - out.putInt((int) i); - } - catch (BufferOverflowException e) - { - grow(4); - out.putInt((int) i); - } - } - - public void writeUint64(long l) - { - try - { - out.putLong(l); - } - catch (BufferOverflowException e) - { - grow(8); - out.putLong(l); - } - } - - public int beginSize8() - { - int pos = out.position(); - try - { - out.put((byte) 0); - } - catch (BufferOverflowException e) - { - grow(1); - out.put((byte) 0); - } - return pos; - } - - public void endSize8(int pos) - { - int cur = out.position(); - out.put(pos, (byte) (cur - pos - 1)); - } - - public int beginSize16() - { - int pos = out.position(); - try - { - out.putShort((short) 0); - } - catch (BufferOverflowException e) - { - grow(2); - out.putShort((short) 0); - } - return pos; - } - - public void endSize16(int pos) - { - int cur = out.position(); - out.putShort(pos, (short) (cur - pos - 2)); - } - - public int beginSize32() - { - int pos = out.position(); - try - { - out.putInt(0); - } - catch (BufferOverflowException e) - { - grow(4); - out.putInt(0); - } - return pos; - } - - public void endSize32(int pos) - { - int cur = out.position(); - out.putInt(pos, (cur - pos - 4)); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/codec/Decoder.java b/java/common/src/main/java/org/apache/qpidity/transport/codec/Decoder.java deleted file mode 100644 index dec901748d..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/codec/Decoder.java +++ /dev/null @@ -1,68 +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.qpidity.transport.codec; - -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import org.apache.qpidity.transport.RangeSet; -import org.apache.qpidity.transport.Struct; - - -/** - * Decoder - * - * @author Rafael H. Schloming - */ - -public interface Decoder -{ - - boolean hasRemaining(); - - short readUint8(); - int readUint16(); - long readUint32(); - long readUint64(); - - long readDatetime(); - UUID readUuid(); - - int readSequenceNo(); - RangeSet readSequenceSet(); // XXX - RangeSet readByteRanges(); // XXX - - String readStr8(); - String readStr16(); - - byte[] readVbin8(); - byte[] readVbin16(); - byte[] readVbin32(); - - Struct readStruct32(); - Map readMap(); - List readList(); - List readArray(); - - Struct readStruct(int type); - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/codec/Encodable.java b/java/common/src/main/java/org/apache/qpidity/transport/codec/Encodable.java deleted file mode 100644 index 60c2ea97b8..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/codec/Encodable.java +++ /dev/null @@ -1,37 +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.qpidity.transport.codec; - - -/** - * Encodable - * - * @author Rafael H. Schloming - */ - -public interface Encodable -{ - - void write(Encoder enc); - - void read(Decoder dec); - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/codec/Encoder.java b/java/common/src/main/java/org/apache/qpidity/transport/codec/Encoder.java deleted file mode 100644 index 9d7a1a695d..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/codec/Encoder.java +++ /dev/null @@ -1,66 +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.qpidity.transport.codec; - -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import org.apache.qpidity.transport.RangeSet; -import org.apache.qpidity.transport.Struct; - - -/** - * Encoder - * - * @author Rafael H. Schloming - */ - -public interface Encoder -{ - - void writeUint8(short b); - void writeUint16(int s); - void writeUint32(long i); - void writeUint64(long l); - - void writeDatetime(long l); - void writeUuid(UUID uuid); - - void writeSequenceNo(int s); - void writeSequenceSet(RangeSet ranges); // XXX - void writeByteRanges(RangeSet ranges); // XXX - - void writeStr8(String s); - void writeStr16(String s); - - void writeVbin8(byte[] bytes); - void writeVbin16(byte[] bytes); - void writeVbin32(byte[] bytes); - - void writeStruct32(Struct s); - void writeMap(Map map); - void writeList(List list); - void writeArray(List array); - - void writeStruct(int type, Struct s); - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/codec/Validator.java b/java/common/src/main/java/org/apache/qpidity/transport/codec/Validator.java deleted file mode 100644 index 743e9f3cae..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/codec/Validator.java +++ /dev/null @@ -1,177 +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.qpidity.transport.codec; - -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import org.apache.qpidity.transport.RangeSet; -import org.apache.qpidity.transport.Struct; - - -/** - * Validator - * - */ - -public class Validator -{ - - public static final void checkBit(boolean b) - { - // no illegal values - } - - public static final void checkUint8(short s) - { - if (s > 0xFF || s < 0) - { - throw new IllegalArgumentException("" + s); - } - } - - public static final void checkUint16(int i) - { - if (i > 0xFFFF || i < 0) - { - throw new IllegalArgumentException("" + i); - } - } - - public static final void checkUint32(long l) - { - // XXX: we can't currently validate this because we do thinks - // like pass in -1 for 0xFFFFFFFF - // if (l > 0xFFFFFFFFL || l < 0) - // { - // throw new IllegalArgumentException("" + l); - // } - } - - public static final void checkSequenceNo(int s) - { - // no illegal values - } - - public static final void checkUint64(long l) - { - // no illegal values - } - - public static final void checkDatetime(long l) - { - // no illegal values - } - - public static final void checkUuid(UUID u) - { - // no illegal values - } - - public static final void checkStr8(String value) - { - if (value != null && value.length() > 255) - { - throw new IllegalArgumentException("" + value); - } - } - - public static final void checkStr16(String value) - { - if (value != null && value.length() > 0xFFFF) - { - throw new IllegalArgumentException("" + value); - } - } - - public static final void checkVbin8(byte[] value) - { - if (value != null && value.length > 255) - { - throw new IllegalArgumentException("" + value); - } - } - - public static final void checkVbin16(byte[] value) - { - if (value != null && value.length > 0xFFFF) - { - throw new IllegalArgumentException("" + value); - } - } - - public static final void checkByteRanges(RangeSet r) - { - // no illegal values - } - - public static final void checkSequenceSet(RangeSet r) - { - // no illegal values - } - - public static final void checkVbin32(byte[] value) - { - // no illegal values - } - - public static final void checkStruct32(Struct s) - { - // no illegal values - } - - public static final void checkArray(List array) - { - if (array == null) - { - return; - } - - for (Object o : array) - { - checkObject(o); - } - } - - public static final void checkMap(Map map) - { - if (map == null) - { - return; - } - - for (Map.Entry entry : map.entrySet()) - { - checkStr8(entry.getKey()); - checkObject(entry.getValue()); - } - } - - public static final void checkObject(Object o) - { - if (o != null && AbstractEncoder.resolve(o.getClass()) == null) - { - throw new IllegalArgumentException("cannot encode " + o.getClass()); - } - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/network/Assembler.java b/java/common/src/main/java/org/apache/qpidity/transport/network/Assembler.java deleted file mode 100644 index 45e2576e7b..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/network/Assembler.java +++ /dev/null @@ -1,219 +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.qpidity.transport.network; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import java.nio.ByteBuffer; - -import org.apache.qpidity.transport.codec.BBDecoder; -import org.apache.qpidity.transport.codec.Decoder; - -import org.apache.qpidity.transport.Data; -import org.apache.qpidity.transport.Header; -import org.apache.qpidity.transport.Method; -import org.apache.qpidity.transport.ProtocolError; -import org.apache.qpidity.transport.ProtocolEvent; -import org.apache.qpidity.transport.ProtocolHeader; -import org.apache.qpidity.transport.Receiver; -import org.apache.qpidity.transport.SegmentType; -import org.apache.qpidity.transport.Struct; - - -/** - * Assembler - * - */ - -public class Assembler implements Receiver, NetworkDelegate -{ - - private final Receiver receiver; - private final Map> segments; - private final ThreadLocal decoder = new ThreadLocal() - { - public BBDecoder initialValue() - { - return new BBDecoder(); - } - }; - - public Assembler(Receiver receiver) - { - this.receiver = receiver; - segments = new HashMap>(); - } - - private int segmentKey(Frame frame) - { - return (frame.getTrack() + 1) * frame.getChannel(); - } - - private List getSegment(Frame frame) - { - return segments.get(segmentKey(frame)); - } - - private void setSegment(Frame frame, List segment) - { - int key = segmentKey(frame); - if (segments.containsKey(key)) - { - error(new ProtocolError(Frame.L2, "segment in progress: %s", - frame)); - } - segments.put(segmentKey(frame), segment); - } - - private void clearSegment(Frame frame) - { - segments.remove(segmentKey(frame)); - } - - private void emit(int channel, ProtocolEvent event) - { - event.setChannel(channel); - receiver.received(event); - } - - private void emit(Frame frame, ProtocolEvent event) - { - emit(frame.getChannel(), event); - } - - public void received(NetworkEvent event) - { - event.delegate(this); - } - - public void exception(Throwable t) - { - this.receiver.exception(t); - } - - public void closed() - { - this.receiver.closed(); - } - - public void init(ProtocolHeader header) - { - emit(0, header); - } - - public void frame(Frame frame) - { - switch (frame.getType()) - { - case BODY: - emit(frame, new Data(frame.getBody(), frame.isFirstFrame(), - frame.isLastFrame())); - break; - default: - assemble(frame); - break; - } - } - - public void error(ProtocolError error) - { - emit(0, error); - } - - private void assemble(Frame frame) - { - ByteBuffer segment; - if (frame.isFirstFrame() && frame.isLastFrame()) - { - segment = frame.getBody(); - emit(frame, decode(frame, segment)); - } - else - { - List frames; - if (frame.isFirstFrame()) - { - frames = new ArrayList(); - setSegment(frame, frames); - } - else - { - frames = getSegment(frame); - } - - frames.add(frame); - - if (frame.isLastFrame()) - { - clearSegment(frame); - - int size = 0; - for (Frame f : frames) - { - size += f.getSize(); - } - segment = ByteBuffer.allocate(size); - for (Frame f : frames) - { - segment.put(f.getBody()); - } - segment.flip(); - emit(frame, decode(frame, segment)); - } - } - - } - - private ProtocolEvent decode(Frame frame, ByteBuffer segment) - { - BBDecoder dec = decoder.get(); - dec.init(segment); - - switch (frame.getType()) - { - case CONTROL: - int controlType = dec.readUint16(); - Method control = Method.create(controlType); - control.read(dec); - return control; - case COMMAND: - int commandType = dec.readUint16(); - // read in the session header, right now we don't use it - dec.readUint16(); - Method command = Method.create(commandType); - command.read(dec); - return command; - case HEADER: - List structs = new ArrayList(); - while (dec.hasRemaining()) - { - structs.add(dec.readStruct32()); - } - return new Header(structs, frame.isLastFrame() && frame.isLastSegment()); - default: - throw new IllegalStateException("unknown frame type: " + frame.getType()); - } - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/network/Disassembler.java b/java/common/src/main/java/org/apache/qpidity/transport/network/Disassembler.java deleted file mode 100644 index fe7939c0d8..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/network/Disassembler.java +++ /dev/null @@ -1,217 +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.qpidity.transport.network; - -import org.apache.qpidity.transport.codec.BBEncoder; - -import org.apache.qpidity.transport.Data; -import org.apache.qpidity.transport.Header; -import org.apache.qpidity.transport.Method; -import org.apache.qpidity.transport.ProtocolDelegate; -import org.apache.qpidity.transport.ProtocolError; -import org.apache.qpidity.transport.ProtocolEvent; -import org.apache.qpidity.transport.ProtocolHeader; -import org.apache.qpidity.transport.SegmentType; -import org.apache.qpidity.transport.Sender; -import org.apache.qpidity.transport.Struct; - -import java.nio.ByteBuffer; -import java.util.Iterator; - -import static org.apache.qpidity.transport.network.Frame.*; - -import static java.lang.Math.*; - - -/** - * Disassembler - * - */ - -public class Disassembler implements Sender, - ProtocolDelegate -{ - - private final Sender sender; - private final int maxPayload; - private final ThreadLocal encoder = new ThreadLocal() - { - public BBEncoder initialValue() - { - return new BBEncoder(4*1024); - } - }; - - public Disassembler(Sender sender, int maxFrame) - { - if (maxFrame <= HEADER_SIZE || maxFrame >= 64*1024) - { - throw new IllegalArgumentException - ("maxFrame must be > HEADER_SIZE and < 64K: " + maxFrame); - } - this.sender = sender; - this.maxPayload = maxFrame - HEADER_SIZE; - - } - - public void send(ProtocolEvent event) - { - event.delegate(null, this); - } - - public void flush() - { - sender.flush(); - } - - public void close() - { - sender.close(); - } - - private void fragment(byte flags, SegmentType type, ProtocolEvent event, - ByteBuffer buf, boolean first, boolean last) - { - byte track = event.getEncodedTrack() == Frame.L4 ? (byte) 1 : (byte) 0; - - if(!buf.hasRemaining()) - { - //empty data - byte nflags = flags; - if (first) - { - nflags |= FIRST_FRAME; - first = false; - } - nflags |= LAST_FRAME; - Frame frame = new Frame(nflags, type, track, event.getChannel(), buf.slice()); - sender.send(frame); - } - else - { - while (buf.hasRemaining()) - { - ByteBuffer slice = buf.slice(); - slice.limit(min(maxPayload, slice.remaining())); - buf.position(buf.position() + slice.remaining()); - - byte newflags = flags; - if (first) - { - newflags |= FIRST_FRAME; - first = false; - } - if (last && !buf.hasRemaining()) - { - newflags |= LAST_FRAME; - } - - Frame frame = new Frame(newflags, type, track, event.getChannel(), slice); - sender.send(frame); - } - } - } - - public void init(Void v, ProtocolHeader header) - { - sender.send(header); - } - - public void control(Void v, Method method) - { - method(method, SegmentType.CONTROL); - } - - public void command(Void v, Method method) - { - method(method, SegmentType.COMMAND); - } - - private ByteBuffer copy(ByteBuffer src) - { - ByteBuffer buf = ByteBuffer.allocate(src.remaining()); - buf.put(src); - buf.flip(); - return buf; - } - - private void method(Method method, SegmentType type) - { - BBEncoder enc = encoder.get(); - enc.init(); - enc.writeUint16(method.getEncodedType()); - if (type == SegmentType.COMMAND) - { - if (method.isSync()) - { - enc.writeUint16(0x0101); - } - else - { - enc.writeUint16(0x0100); - } - } - method.write(enc); - ByteBuffer buf = enc.done(); - - byte flags = FIRST_SEG; - - if (!method.hasPayload()) - { - flags |= LAST_SEG; - } - - fragment(flags, type, method, buf, true, true); - } - - public void header(Void v, Header header) - { - ByteBuffer buf; - if (header.getBuf() == null) - { - BBEncoder enc = encoder.get(); - enc.init(); - for (Struct st : header.getStructs()) - { - enc.writeStruct32(st); - } - buf = enc.done(); - header.setBuf(buf); - } - else - { - buf = header.getBuf(); - buf.flip(); - } - fragment((byte) 0x0, SegmentType.HEADER, header, buf, true, true); - } - - public void data(Void v, Data data) - { - fragment(LAST_SEG, SegmentType.BODY, data, data.getData(), data.isFirst(), data.isLast()); - } - - public void error(Void v, ProtocolError error) - { - sender.send(error); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/network/Frame.java b/java/common/src/main/java/org/apache/qpidity/transport/network/Frame.java deleted file mode 100644 index 7b8675b39d..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/network/Frame.java +++ /dev/null @@ -1,151 +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.qpidity.transport.network; - -import org.apache.qpidity.transport.SegmentType; -import org.apache.qpidity.transport.util.SliceIterator; - -import java.nio.ByteBuffer; - -import java.util.ArrayList; -import java.util.List; -import java.util.Iterator; - -import static org.apache.qpidity.transport.util.Functions.*; - - -/** - * Frame - * - * @author Rafael H. Schloming - */ - -public final class Frame implements NetworkEvent -{ - public static final int HEADER_SIZE = 12; - - // XXX: enums? - public static final byte L1 = 0; - public static final byte L2 = 1; - public static final byte L3 = 2; - public static final byte L4 = 3; - - public static final byte RESERVED = 0x0; - - public static final byte VERSION = 0x0; - - public static final byte FIRST_SEG = 0x8; - public static final byte LAST_SEG = 0x4; - public static final byte FIRST_FRAME = 0x2; - public static final byte LAST_FRAME = 0x1; - - final private byte flags; - final private SegmentType type; - final private byte track; - final private int channel; - final private ByteBuffer body; - - public Frame(byte flags, SegmentType type, byte track, int channel, - ByteBuffer body) - { - this.flags = flags; - this.type = type; - this.track = track; - this.channel = channel; - this.body = body; - } - - public ByteBuffer getBody() - { - return body.slice(); - } - - public byte getFlags() - { - return flags; - } - - public int getChannel() - { - return channel; - } - - public int getSize() - { - return body.remaining(); - } - - public SegmentType getType() - { - return type; - } - - public byte getTrack() - { - return track; - } - - private boolean flag(byte mask) - { - return (flags & mask) != 0; - } - - public boolean isFirstSegment() - { - return flag(FIRST_SEG); - } - - public boolean isLastSegment() - { - return flag(LAST_SEG); - } - - public boolean isFirstFrame() - { - return flag(FIRST_FRAME); - } - - public boolean isLastFrame() - { - return flag(LAST_FRAME); - } - - public void delegate(NetworkDelegate delegate) - { - delegate.frame(this); - } - - public String toString() - { - StringBuilder str = new StringBuilder(); - - str.append(String.format - ("[%05d %05d %1d %s %d%d%d%d] ", getChannel(), getSize(), - getTrack(), getType(), - isFirstSegment() ? 1 : 0, isLastSegment() ? 1 : 0, - isFirstFrame() ? 1 : 0, isLastFrame() ? 1 : 0)); - - str.append(str(body)); - - return str.toString(); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/network/InputHandler.java b/java/common/src/main/java/org/apache/qpidity/transport/network/InputHandler.java deleted file mode 100644 index 8963f831da..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/network/InputHandler.java +++ /dev/null @@ -1,204 +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.qpidity.transport.network; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -import org.apache.qpidity.transport.ProtocolError; -import org.apache.qpidity.transport.ProtocolHeader; -import org.apache.qpidity.transport.Receiver; -import org.apache.qpidity.transport.SegmentType; - -import static org.apache.qpidity.transport.util.Functions.*; - -import static org.apache.qpidity.transport.network.InputHandler.State.*; - - -/** - * InputHandler - * - * @author Rafael H. Schloming - */ - -public final class InputHandler implements Receiver -{ - - public enum State - { - PROTO_HDR, - FRAME_HDR, - FRAME_BODY, - ERROR; - } - - private final Receiver receiver; - private State state; - private ByteBuffer input = null; - private int needed; - - private byte flags; - private SegmentType type; - private byte track; - private int channel; - - public InputHandler(Receiver receiver, State state) - { - this.receiver = receiver; - this.state = state; - - switch (state) - { - case PROTO_HDR: - needed = 8; - break; - case FRAME_HDR: - needed = Frame.HEADER_SIZE; - break; - } - } - - public InputHandler(Receiver receiver) - { - this(receiver, PROTO_HDR); - } - - private void error(String fmt, Object ... args) - { - receiver.received(new ProtocolError(Frame.L1, fmt, args)); - } - - public void received(ByteBuffer buf) - { - int limit = buf.limit(); - int remaining = buf.remaining(); - while (remaining > 0) - { - if (remaining >= needed) - { - int consumed = needed; - int pos = buf.position(); - if (input == null) - { - buf.limit(pos + needed); - input = buf; - state = next(pos); - buf.limit(limit); - buf.position(pos + consumed); - } - else - { - buf.limit(pos + needed); - input.put(buf); - buf.limit(limit); - input.flip(); - state = next(0); - } - - remaining -= consumed; - input = null; - } - else - { - if (input == null) - { - input = ByteBuffer.allocate(needed); - } - input.put(buf); - needed -= remaining; - remaining = 0; - } - } - } - - private State next(int pos) - { - input.order(ByteOrder.BIG_ENDIAN); - - switch (state) { - case PROTO_HDR: - if (input.get(pos) != 'A' && - input.get(pos + 1) != 'M' && - input.get(pos + 2) != 'Q' && - input.get(pos + 3) != 'P') - { - error("bad protocol header: %s", str(input)); - return ERROR; - } - - byte instance = input.get(pos + 5); - byte major = input.get(pos + 6); - byte minor = input.get(pos + 7); - receiver.received(new ProtocolHeader(instance, major, minor)); - needed = Frame.HEADER_SIZE; - return FRAME_HDR; - case FRAME_HDR: - flags = input.get(pos); - type = SegmentType.get(input.get(pos + 1)); - int size = (0xFFFF & input.getShort(pos + 2)); - size -= Frame.HEADER_SIZE; - if (size < 0 || size > (64*1024 - 12)) - { - error("bad frame size: %d", size); - return ERROR; - } - byte b = input.get(pos + 5); - if ((b & 0xF0) != 0) { - error("non-zero reserved bits in upper nibble of " + - "frame header byte 5: '%x'", b); - return ERROR; - } else { - track = (byte) (b & 0xF); - } - channel = (0xFFFF & input.getShort(pos + 6)); - if (size == 0) - { - Frame frame = new Frame(flags, type, track, channel, ByteBuffer.allocate(0)); - receiver.received(frame); - needed = Frame.HEADER_SIZE; - return FRAME_HDR; - } - else - { - needed = size; - return FRAME_BODY; - } - case FRAME_BODY: - Frame frame = new Frame(flags, type, track, channel, input.slice()); - receiver.received(frame); - needed = Frame.HEADER_SIZE; - return FRAME_HDR; - default: - throw new IllegalStateException(); - } - } - - public void exception(Throwable t) - { - receiver.exception(t); - } - - public void closed() - { - receiver.closed(); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/network/NetworkDelegate.java b/java/common/src/main/java/org/apache/qpidity/transport/network/NetworkDelegate.java deleted file mode 100644 index 48655edd0c..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/network/NetworkDelegate.java +++ /dev/null @@ -1,42 +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.qpidity.transport.network; - -import org.apache.qpidity.transport.ProtocolError; -import org.apache.qpidity.transport.ProtocolHeader; - - -/** - * NetworkDelegate - * - * @author Rafael H. Schloming - */ - -public interface NetworkDelegate -{ - - void init(ProtocolHeader header); - - void frame(Frame frame); - - void error(ProtocolError error); - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/network/NetworkEvent.java b/java/common/src/main/java/org/apache/qpidity/transport/network/NetworkEvent.java deleted file mode 100644 index 080efee704..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/network/NetworkEvent.java +++ /dev/null @@ -1,34 +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.qpidity.transport.network; - - -/** - * NetworkEvent - * - */ - -public interface NetworkEvent -{ - - void delegate(NetworkDelegate delegate); - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/network/OutputHandler.java b/java/common/src/main/java/org/apache/qpidity/transport/network/OutputHandler.java deleted file mode 100644 index e2ef8ca0d5..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/network/OutputHandler.java +++ /dev/null @@ -1,125 +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.qpidity.transport.network; - -import java.nio.ByteBuffer; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.qpidity.transport.Constant; -import org.apache.qpidity.transport.ProtocolError; -import org.apache.qpidity.transport.ProtocolHeader; -import org.apache.qpidity.transport.Sender; - -import static org.apache.qpidity.transport.network.Frame.*; - - -/** - * OutputHandler - * - */ - -public class OutputHandler implements Sender, NetworkDelegate -{ - - private Sender sender; - private Object lock = new Object(); - private int bytes = 0; - private List frames = new ArrayList(); - - public OutputHandler(Sender sender) - { - this.sender = sender; - } - - public void send(NetworkEvent event) - { - event.delegate(this); - } - - public void close() - { - synchronized (lock) - { - sender.close(); - } - } - - public void init(ProtocolHeader header) - { - synchronized (lock) - { - sender.send(header.toByteBuffer()); - sender.flush(); - } - } - - public void frame(Frame frame) - { - synchronized (lock) - { - frames.add(frame); - bytes += HEADER_SIZE + frame.getSize(); - - if (bytes > 64*1024) - { - flush(); - } - } - } - - public void flush() - { - synchronized (lock) - { - ByteBuffer buf = ByteBuffer.allocate(bytes); - int nframes = frames.size(); - for (int i = 0; i < nframes; i++) - { - Frame frame = frames.get(i); - buf.put(frame.getFlags()); - buf.put((byte) frame.getType().getValue()); - buf.putShort((short) (frame.getSize() + HEADER_SIZE)); - // RESERVED - buf.put(RESERVED); - buf.put(frame.getTrack()); - buf.putShort((short) frame.getChannel()); - // RESERVED - buf.putInt(0); - buf.put(frame.getBody()); - } - buf.flip(); - - frames.clear(); - bytes = 0; - - sender.send(buf); - sender.flush(); - } - } - - public void error(ProtocolError error) - { - throw new IllegalStateException("XXX"); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/network/io/IoReceiver.java b/java/common/src/main/java/org/apache/qpidity/transport/network/io/IoReceiver.java deleted file mode 100644 index 426c41dd55..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/network/io/IoReceiver.java +++ /dev/null @@ -1,106 +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.qpidity.transport.network.io; - -import org.apache.qpidity.transport.Receiver; -import org.apache.qpidity.transport.TransportException; -import org.apache.qpidity.transport.util.Logger; - -import java.io.InputStream; -import java.io.IOException; -import java.net.Socket; -import java.nio.ByteBuffer; - -/** - * IoReceiver - * - */ - -final class IoReceiver extends Thread -{ - - private static final Logger log = Logger.get(IoReceiver.class); - - private final IoTransport transport; - private final Receiver receiver; - private final int bufferSize; - private final Socket socket; - - public IoReceiver(IoTransport transport, Receiver receiver, int bufferSize) - { - this.transport = transport; - this.receiver = receiver; - this.bufferSize = bufferSize; - this.socket = transport.getSocket(); - - setName(String.format("IoReceive - %s", socket.getRemoteSocketAddress())); - start(); - } - - public void run() - { - final int threshold = bufferSize / 2; - - // I set the read buffer size simillar to SO_RCVBUF - // Haven't tested with a lower value to see if it's better or worse - byte[] buffer = new byte[bufferSize]; - try - { - InputStream in = socket.getInputStream(); - int read = 0; - int offset = 0; - while ((read = in.read(buffer, offset, bufferSize-offset)) != -1) - { - if (read > 0) - { - ByteBuffer b = ByteBuffer.wrap(buffer,offset,read); - receiver.received(b); - offset+=read; - if (offset > threshold) - { - offset = 0; - buffer = new byte[bufferSize]; - } - } - } - } - catch (Throwable t) - { - receiver.exception(new TransportException("error in read thread", t)); - } - finally - { - try - { - transport.getSender().close(); - } - catch (TransportException e) - { - log.error(e, "error closing"); - } - finally - { - receiver.closed(); - } - } - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/network/io/IoSender.java b/java/common/src/main/java/org/apache/qpidity/transport/network/io/IoSender.java deleted file mode 100644 index 0c65b583ff..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/network/io/IoSender.java +++ /dev/null @@ -1,262 +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.qpidity.transport.network.io; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.Socket; -import java.nio.ByteBuffer; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; - -import org.apache.qpidity.transport.Sender; -import org.apache.qpidity.transport.TransportException; -import org.apache.qpidity.transport.util.Logger; - -import static org.apache.qpidity.transport.util.Functions.*; - - -final class IoSender extends Thread implements Sender -{ - - private static final Logger log = Logger.get(IoSender.class); - - // by starting here, we ensure that we always test the wraparound - // case, we should probably make this configurable somehow so that - // we can test other cases as well - private final static int START = Integer.MAX_VALUE - 10; - - private final IoTransport transport; - private final long timeout; - private final Socket socket; - private final OutputStream out; - - private final byte[] buffer; - private final AtomicInteger head = new AtomicInteger(START); - private final AtomicInteger tail = new AtomicInteger(START); - private final Object notFull = new Object(); - private final Object notEmpty = new Object(); - private final AtomicBoolean closed = new AtomicBoolean(false); - - private IOException exception = null; - - - public IoSender(IoTransport transport, int bufferSize, long timeout) - { - this.transport = transport; - this.socket = transport.getSocket(); - this.buffer = new byte[bufferSize]; - this.timeout = timeout; - - try - { - out = socket.getOutputStream(); - } - catch (IOException e) - { - throw new TransportException("Error getting output stream for socket", e); - } - - setName(String.format("IoSender - %s", socket.getRemoteSocketAddress())); - start(); - } - - private static final int mod(int n, int m) - { - int r = n % m; - return r < 0 ? m + r : r; - } - - public void send(ByteBuffer buf) - { - if (closed.get()) - { - throw new TransportException("sender is closed", exception); - } - - final int size = buffer.length; - int remaining = buf.remaining(); - - while (remaining > 0) - { - final int hd = head.get(); - final int tl = tail.get(); - - if (hd - tl >= size) - { - synchronized (notFull) - { - long start = System.currentTimeMillis(); - long elapsed = 0; - while (head.get() - tail.get() >= size && elapsed < timeout) - { - try - { - notFull.wait(timeout - elapsed); - } - catch (InterruptedException e) - { - // pass - } - elapsed += System.currentTimeMillis() - start; - } - - if (head.get() - tail.get() >= size) - { - throw new TransportException(String.format("write timed out: %s, %s", head.get(), tail.get())); - } - } - continue; - } - - final int hd_idx = mod(hd, size); - final int tl_idx = mod(tl, size); - final int length; - - if (tl_idx > hd_idx) - { - length = Math.min(tl_idx - hd_idx, remaining); - } - else - { - length = Math.min(size - hd_idx, remaining); - } - - buf.get(buffer, hd_idx, length); - head.getAndAdd(length); - if (hd == tail.get()) - { - synchronized (notEmpty) - { - notEmpty.notify(); - } - } - remaining -= length; - } - } - - public void flush() - { - // pass - } - - public void close() - { - if (!closed.getAndSet(true)) - { - synchronized (notEmpty) - { - notEmpty.notify(); - } - - try - { - join(timeout); - if (isAlive()) - { - throw new TransportException("join timed out"); - } - socket.close(); - } - catch (InterruptedException e) - { - throw new TransportException(e); - } - catch (IOException e) - { - throw new TransportException(e); - } - - if (exception != null) - { - throw new TransportException(exception); - } - } - } - - public void run() - { - final int size = buffer.length; - - while (true) - { - final int hd = head.get(); - final int tl = tail.get(); - - if (hd == tl) - { - if (closed.get()) - { - break; - } - - synchronized (notEmpty) - { - while (head.get() == tail.get() && !closed.get()) - { - try - { - notEmpty.wait(); - } - catch (InterruptedException e) - { - // pass - } - } - } - - continue; - } - - final int hd_idx = mod(hd, size); - final int tl_idx = mod(tl, size); - - final int length; - if (tl_idx < hd_idx) - { - length = hd_idx - tl_idx; - } - else - { - length = size - tl_idx; - } - - try - { - out.write(buffer, tl_idx, length); - } - catch (IOException e) - { - log.error(e, "error in write thread"); - exception = e; - break; - } - tail.getAndAdd(length); - if (head.get() - tl >= size) - { - synchronized (notFull) - { - notFull.notify(); - } - } - } - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/network/io/IoTransport.java b/java/common/src/main/java/org/apache/qpidity/transport/network/io/IoTransport.java deleted file mode 100644 index 07a2c70965..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/network/io/IoTransport.java +++ /dev/null @@ -1,129 +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.qpidity.transport.network.io; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.SocketException; -import java.nio.ByteBuffer; - -import org.apache.qpidity.transport.Connection; -import org.apache.qpidity.transport.ConnectionDelegate; -import org.apache.qpidity.transport.Receiver; -import org.apache.qpidity.transport.TransportException; -import org.apache.qpidity.transport.network.Assembler; -import org.apache.qpidity.transport.network.Disassembler; -import org.apache.qpidity.transport.network.InputHandler; -import org.apache.qpidity.transport.network.OutputHandler; -import org.apache.qpidity.transport.util.Logger; - -/** - * This class provides a socket based transport using the java.io - * classes. - * - * The following params are configurable via JVM arguments - * TCP_NO_DELAY - amqj.tcpNoDelay - * SO_RCVBUF - amqj.receiveBufferSize - * SO_SNDBUF - amqj.sendBufferSize - */ -public final class IoTransport -{ - - private static final Logger log = Logger.get(IoTransport.class); - - private static int DEFAULT_READ_WRITE_BUFFER_SIZE = 64 * 1024; - - private IoReceiver receiver; - private IoSender sender; - private Socket socket; - private int readBufferSize; - private int writeBufferSize; - private final long timeout = 60000; - - private IoTransport() - { - readBufferSize = Integer.getInteger("amqj.receiveBufferSize",DEFAULT_READ_WRITE_BUFFER_SIZE); - writeBufferSize = Integer.getInteger("amqj.sendBufferSize",DEFAULT_READ_WRITE_BUFFER_SIZE); - } - - public static final Connection connect(String host, int port, - ConnectionDelegate delegate) - { - IoTransport handler = new IoTransport(); - return handler.connectInternal(host,port,delegate); - } - - private Connection connectInternal(String host, int port, - ConnectionDelegate delegate) - { - try - { - InetAddress address = InetAddress.getByName(host); - socket = new Socket(); - socket.setReuseAddress(true); - socket.setTcpNoDelay(Boolean.getBoolean("amqj.tcpNoDelay")); - - log.debug("default-SO_RCVBUF : %s", socket.getReceiveBufferSize()); - log.debug("default-SO_SNDBUF : %s", socket.getSendBufferSize()); - - socket.setSendBufferSize(writeBufferSize); - socket.setReceiveBufferSize(readBufferSize); - - log.debug("new-SO_RCVBUF : %s", socket.getReceiveBufferSize()); - log.debug("new-SO_SNDBUF : %s", socket.getSendBufferSize()); - - socket.connect(new InetSocketAddress(address, port)); - } - catch (SocketException e) - { - throw new TransportException("Error connecting to broker", e); - } - catch (IOException e) - { - throw new TransportException("Error connecting to broker", e); - } - - sender = new IoSender(this, 2*writeBufferSize, timeout); - Connection conn = new Connection - (new Disassembler(new OutputHandler(sender), 64*1024 - 1), - delegate); - receiver = new IoReceiver(this, new InputHandler(new Assembler(conn)), 2*readBufferSize); - - return conn; - } - - IoSender getSender() - { - return sender; - } - - IoReceiver getReceiver() - { - return receiver; - } - - Socket getSocket() - { - return socket; - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/network/mina/MinaHandler.java b/java/common/src/main/java/org/apache/qpidity/transport/network/mina/MinaHandler.java deleted file mode 100644 index c6855e3d48..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/network/mina/MinaHandler.java +++ /dev/null @@ -1,305 +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.qpidity.transport.network.mina; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.SocketAddress; - -import org.apache.mina.common.*; - -import org.apache.mina.transport.socket.nio.SocketAcceptor; -import org.apache.mina.transport.socket.nio.SocketSessionConfig; -import org.apache.mina.transport.socket.nio.SocketConnector; -import org.apache.mina.filter.ReadThrottleFilterBuilder; -import org.apache.mina.filter.WriteBufferLimitFilterBuilder; -import org.apache.mina.filter.executor.ExecutorFilter; - -import org.apache.qpidity.transport.Binding; -import org.apache.qpidity.transport.Connection; -import org.apache.qpidity.transport.ConnectionDelegate; -import org.apache.qpidity.transport.Receiver; -import org.apache.qpidity.transport.Sender; - -import org.apache.qpidity.transport.util.Logger; - -import org.apache.qpidity.transport.network.Assembler; -import org.apache.qpidity.transport.network.Disassembler; -import org.apache.qpidity.transport.network.InputHandler; -import org.apache.qpidity.transport.network.OutputHandler; - -import static org.apache.qpidity.transport.util.Functions.*; - -/** - * MinaHandler - * - * @author Rafael H. Schloming - */ -//RA making this public until we sort out the package issues -public class MinaHandler implements IoHandler -{ - private static final int MAX_FRAME_SIZE = 64 * 1024 - 1; - /** Default buffer size for pending messages reads */ - private static final String DEFAULT_READ_BUFFER_LIMIT = "262144"; - /** Default buffer size for pending messages writes */ - private static final String DEFAULT_WRITE_BUFFER_LIMIT = "262144"; - private static final int MAX_RCVBUF = 64*1024; - - private static final Logger log = Logger.get(MinaHandler.class); - - static - { - ByteBuffer.setAllocator(new SimpleByteBufferAllocator()); - ByteBuffer.setUseDirectBuffers(Boolean.getBoolean("amqj.enableDirectBuffers")); - } - - private final Binding binding; - - private MinaHandler(Binding binding) - { - this.binding = binding; - } - - public void messageReceived(IoSession ssn, Object obj) - { - Attachment attachment = (Attachment) ssn.getAttachment(); - ByteBuffer buf = (ByteBuffer) obj; - try - { - attachment.receiver.received(buf.buf()); - } - catch (Throwable t) - { - log.error(t, "exception handling buffer %s", str(buf.buf())); - throw new RuntimeException(t); - } - } - - public void messageSent(IoSession ssn, Object obj) - { - // do nothing - } - - public void exceptionCaught(IoSession ssn, Throwable e) - { - Attachment attachment = (Attachment) ssn.getAttachment(); - attachment.receiver.exception(e); - } - - /** - * Invoked by MINA when a MINA session for a new connection is created. This method sets up the filter chain on the - * session, which filters the events handled by this handler. The filter chain consists of, handing off events - * to an optional protectio - * - * @param session The MINA session. - * @throws Exception Any underlying exceptions are allowed to fall through to MINA. - */ - public void sessionCreated(IoSession session) throws Exception - { - log.debug("Protocol session created for session " + System.identityHashCode(session)); - - if (Boolean.getBoolean("protectio")) - { - try - { - //Add IO Protection Filters - IoFilterChain chain = session.getFilterChain(); - - session.getFilterChain().addLast("tempExecutorFilterForFilterBuilder", new ExecutorFilter()); - - ReadThrottleFilterBuilder readfilter = new ReadThrottleFilterBuilder(); - readfilter.setMaximumConnectionBufferSize( - Integer.parseInt(System.getProperty("qpid.read.buffer.limit", DEFAULT_READ_BUFFER_LIMIT))); - readfilter.attach(chain); - - WriteBufferLimitFilterBuilder writefilter = new WriteBufferLimitFilterBuilder(); - writefilter.setMaximumConnectionBufferSize( - Integer.parseInt(System.getProperty("qpid.write.buffer.limit", DEFAULT_WRITE_BUFFER_LIMIT))); - writefilter.attach(chain); - session.getFilterChain().remove("tempExecutorFilterForFilterBuilder"); - - log.info("Using IO Read/Write Filter Protection"); - } - catch (Exception e) - { - log.error("Unable to attach IO Read/Write Filter Protection :" + e.getMessage()); - } - } - } - - public void sessionOpened(final IoSession ssn) - { - log.debug("opened: %s", this); - E endpoint = binding.endpoint(new MinaSender(ssn)); - Attachment attachment = - new Attachment(endpoint, binding.receiver(endpoint)); - - // We need to synchronize and notify here because the MINA - // connect future returns the session prior to the attachment - // being set. This is arguably a bug in MINA. - synchronized (ssn) - { - ssn.setAttachment(attachment); - ssn.notifyAll(); - } - } - - public void sessionClosed(IoSession ssn) - { - log.debug("closed: %s", ssn); - Attachment attachment = (Attachment) ssn.getAttachment(); - attachment.receiver.closed(); - ssn.setAttachment(null); - } - - public void sessionIdle(IoSession ssn, IdleStatus status) - { - // do nothing - } - - private static class Attachment - { - - E endpoint; - Receiver receiver; - - Attachment(E endpoint, Receiver receiver) - { - this.endpoint = endpoint; - this.receiver = receiver; - } - } - - public static final void accept(String host, int port, - Binding binding) - throws IOException - { - accept(new InetSocketAddress(host, port), binding); - } - - public static final void accept(SocketAddress address, - Binding binding) - throws IOException - { - IoAcceptor acceptor = new SocketAcceptor(); - acceptor.bind(address, new MinaHandler(binding)); - } - - public static final E connect(String host, int port, - Binding binding) - { - return connect(new InetSocketAddress(host, port), binding); - } - - public static final E connect(SocketAddress address, - Binding binding) - { - MinaHandler handler = new MinaHandler(binding); - SocketConnector connector = new SocketConnector(); - IoServiceConfig acceptorConfig = connector.getDefaultConfig(); - acceptorConfig.setThreadModel(ThreadModel.MANUAL); - SocketSessionConfig scfg = (SocketSessionConfig) acceptorConfig.getSessionConfig(); - scfg.setTcpNoDelay(Boolean.getBoolean("amqj.tcpNoDelay")); - Integer sendBufferSize = Integer.getInteger("amqj.sendBufferSize"); - if (sendBufferSize != null && sendBufferSize > 0) - { - scfg.setSendBufferSize(sendBufferSize); - } - Integer receiveBufferSize = Integer.getInteger("amqj.receiveBufferSize"); - if (receiveBufferSize != null && receiveBufferSize > 0) - { - scfg.setReceiveBufferSize(receiveBufferSize); - } - else if (scfg.getReceiveBufferSize() > MAX_RCVBUF) - { - scfg.setReceiveBufferSize(MAX_RCVBUF); - } - connector.setWorkerTimeout(0); - ConnectFuture cf = connector.connect(address, handler); - cf.join(); - IoSession ssn = cf.getSession(); - - // We need to synchronize and wait here because the MINA - // connect future returns the session prior to the attachment - // being set. This is arguably a bug in MINA. - synchronized (ssn) - { - while (ssn.getAttachment() == null) - { - try - { - ssn.wait(); - } - catch (InterruptedException e) - { - throw new RuntimeException(e); - } - } - } - - Attachment attachment = (Attachment) ssn.getAttachment(); - return attachment.endpoint; - } - - public static final void accept(String host, int port, - ConnectionDelegate delegate) - throws IOException - { - accept(host, port, new ConnectionBinding - (delegate, InputHandler.State.PROTO_HDR)); - } - - public static final Connection connect(String host, int port, - ConnectionDelegate delegate) - { - return connect(host, port, new ConnectionBinding - (delegate, InputHandler.State.PROTO_HDR)); - } - - private static class ConnectionBinding - implements Binding - { - - private final ConnectionDelegate delegate; - private final InputHandler.State state; - - ConnectionBinding(ConnectionDelegate delegate, - InputHandler.State state) - { - this.delegate = delegate; - this.state = state; - } - - public Connection endpoint(Sender sender) - { - // XXX: hardcoded max-frame - return new Connection - (new Disassembler(new OutputHandler(sender), MAX_FRAME_SIZE), delegate); - } - - public Receiver receiver(Connection conn) - { - return new InputHandler(new Assembler(conn), state); - } - - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/network/mina/MinaSender.java b/java/common/src/main/java/org/apache/qpidity/transport/network/mina/MinaSender.java deleted file mode 100644 index a53c36ae2e..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/network/mina/MinaSender.java +++ /dev/null @@ -1,81 +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.qpidity.transport.network.mina; - -import org.apache.mina.common.ByteBuffer; -import org.apache.mina.common.CloseFuture; -import org.apache.mina.common.IoSession; -import org.apache.mina.common.WriteFuture; - -import org.apache.qpidity.transport.Sender; -import org.apache.qpidity.transport.TransportException; - - -/** - * MinaSender - */ - -public class MinaSender implements Sender -{ - private static final int TIMEOUT = 2 * 60 * 1000; - - private final IoSession session; - private WriteFuture lastWrite = null; - - public MinaSender(IoSession session) - { - this.session = session; - } - - public void send(java.nio.ByteBuffer buf) - { - if (session.isClosing()) - { - throw new TransportException("attempted to write to a closed socket"); - } - - synchronized (this) - { - lastWrite = session.write(ByteBuffer.wrap(buf)); - } - } - - public void flush() - { - // pass - } - - public synchronized void close() - { - // MINA will sometimes throw away in-progress writes when you - // ask it to close - synchronized (this) - { - if (lastWrite != null) - { - lastWrite.join(); - } - } - CloseFuture closed = session.close(); - closed.join(); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/network/nio/NioHandler.java b/java/common/src/main/java/org/apache/qpidity/transport/network/nio/NioHandler.java deleted file mode 100644 index a7339427c7..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/network/nio/NioHandler.java +++ /dev/null @@ -1,120 +0,0 @@ -package org.apache.qpidity.transport.network.nio; - -import java.io.EOFException; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.net.SocketException; -import java.nio.ByteBuffer; -import java.nio.channels.SocketChannel; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicInteger; - -import org.apache.qpidity.transport.Connection; -import org.apache.qpidity.transport.ConnectionDelegate; -import org.apache.qpidity.transport.Receiver; -import org.apache.qpidity.transport.network.Assembler; -import org.apache.qpidity.transport.network.Disassembler; -import org.apache.qpidity.transport.network.InputHandler; -import org.apache.qpidity.transport.network.OutputHandler; - -public class NioHandler implements Runnable -{ - private Receiver _receiver; - private SocketChannel _ch; - private ByteBuffer _readBuf; - private static Map _handlers = new ConcurrentHashMap(); - private AtomicInteger _count = new AtomicInteger(); - - private NioHandler(){} - - public static final Connection connect(String host, int port, - ConnectionDelegate delegate) - { - NioHandler handler = new NioHandler(); - return handler.connectInternal(host,port,delegate); - } - - private Connection connectInternal(String host, int port, - ConnectionDelegate delegate) - { - try - { - SocketAddress address = new InetSocketAddress(host,port); - _ch = SocketChannel.open(); - _ch.socket().setReuseAddress(true); - _ch.configureBlocking(true); - _ch.socket().setTcpNoDelay(true); - if (address != null) - { - _ch.socket().connect(address); - } - while (_ch.isConnectionPending()) - { - - } - - } - catch (SocketException e) - { - - e.printStackTrace(); - } - catch (IOException e) - { - e.printStackTrace(); - } - - NioSender sender = new NioSender(_ch); - Connection con = new Connection - (new Disassembler(new OutputHandler(sender), 64*1024 - 1), - delegate); - - con.setConnectionId(_count.incrementAndGet()); - _handlers.put(con.getConnectionId(),sender); - - _receiver = new InputHandler(new Assembler(con), InputHandler.State.FRAME_HDR); - - Thread t = new Thread(this); - t.start(); - - return con; - } - - public void run() - { - _readBuf = ByteBuffer.allocate(512); - long read = 0; - while(_ch.isConnected() && _ch.isOpen()) - { - try - { - read = _ch.read(_readBuf); - if (read > 0) - { - _readBuf.flip(); - ByteBuffer b = ByteBuffer.allocate(_readBuf.remaining()); - b.put(_readBuf); - b.flip(); - _readBuf.clear(); - _receiver.received(b); - } - } - catch(Exception e) - { - e.printStackTrace(); - } - } - - //throw new EOFException("The underlying socket/channel has closed"); - } - - public static void startBatchingFrames(int connectionId) - { - NioSender sender = _handlers.get(connectionId); - sender.setStartBatching(); - } - - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/network/nio/NioSender.java b/java/common/src/main/java/org/apache/qpidity/transport/network/nio/NioSender.java deleted file mode 100644 index 798f24b528..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/network/nio/NioSender.java +++ /dev/null @@ -1,100 +0,0 @@ -package org.apache.qpidity.transport.network.nio; - -import java.nio.ByteBuffer; -import java.nio.channels.SocketChannel; - -import org.apache.qpidity.transport.Sender; - -public class NioSender implements Sender -{ - private final Object lock = new Object(); - private SocketChannel _ch; - private boolean _batch = false; - private ByteBuffer _batcher; - - public NioSender(SocketChannel ch) - { - this._ch = ch; - } - - public void send(java.nio.ByteBuffer buf) - { - if (_batch) - { - //System.out.println(_batcher.position() + " , " + buf.remaining() + " , " + buf.position() + ","+_batcher.capacity()); - if (_batcher.position() + buf.remaining() >= _batcher.capacity()) - { - _batcher.flip(); - write(_batcher); - _batcher.clear(); - if (buf.remaining() > _batcher.capacity()) - { - write(buf); - } - else - { - _batcher.put(buf); - } - } - else - { - _batcher.put(buf); - } - } - else - { - write(buf); - } - } - - public void flush() - { - // pass - } - - private void write(java.nio.ByteBuffer buf) - { - synchronized (lock) - { - if( _ch.isConnected() && _ch.isOpen()) - { - try - { - _ch.write(buf); - } - catch(Exception e) - { - e.fillInStackTrace(); - } - } - else - { - throw new RuntimeException("Trying to write on a closed socket"); - } - - } - } - - public void setStartBatching() - { - _batch = true; - _batcher = ByteBuffer.allocate(1024); - } - - public void close() - { - // MINA will sometimes throw away in-progress writes when you - // ask it to close - synchronized (lock) - { - try - { - _ch.close(); - } - catch(Exception e) - { - e.printStackTrace(); - } - } - } -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/util/Functions.java b/java/common/src/main/java/org/apache/qpidity/transport/util/Functions.java deleted file mode 100644 index 0038cdf118..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/util/Functions.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.qpidity.transport.util; - -import java.nio.ByteBuffer; - -import static java.lang.Math.*; - - -/** - * Functions - * - * @author Rafael H. Schloming - */ - -public class Functions -{ - - public static final byte lsb(int i) - { - return (byte) (0xFF & i); - } - - public static final byte lsb(long l) - { - return (byte) (0xFF & l); - } - - public static final String str(ByteBuffer buf) - { - return str(buf, buf.remaining()); - } - - public static final String str(ByteBuffer buf, int limit) - { - StringBuilder str = new StringBuilder(); - str.append('"'); - - for (int i = 0; i < min(buf.remaining(), limit); i++) - { - byte c = buf.get(buf.position() + i); - - if (c > 31 && c < 127 && c != '\\') - { - str.append((char)c); - } - else - { - str.append(String.format("\\x%02x", c)); - } - } - - str.append('"'); - - if (limit < buf.remaining()) - { - str.append("..."); - } - - return str.toString(); - } - - public static final String str(byte[] bytes) - { - return str(ByteBuffer.wrap(bytes)); - } - - public static final String str(byte[] bytes, int limit) - { - return str(ByteBuffer.wrap(bytes), limit); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/util/Logger.java b/java/common/src/main/java/org/apache/qpidity/transport/util/Logger.java deleted file mode 100644 index 0159036a34..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/util/Logger.java +++ /dev/null @@ -1,125 +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.qpidity.transport.util; - -import org.slf4j.LoggerFactory; - -/** - * Logger - * - */ - -public final class Logger -{ - - public static final Logger get(Class klass) - { - return new Logger(LoggerFactory.getLogger(klass)); - } - - private final org.slf4j.Logger log; - - private Logger(org.slf4j.Logger log) - { - this.log = log; - } - - public void debug(String message, Object ... args) - { - if (log.isDebugEnabled()) - { - log.debug(String.format(message, args)); - } - } - - public void debug(Throwable t, String message, Object ... args) - { - if (log.isDebugEnabled()) - { - log.debug(String.format(message, args), t); - } - } - - public void error(String message, Object ... args) - { - if (log.isErrorEnabled()) - { - log.error(String.format(message, args)); - } - } - - public void error(Throwable t, String message, Object ... args) - { - if (log.isErrorEnabled()) - { - log.error(String.format(message, args), t); - } - } - - public void warn(String message, Object ... args) - { - if (log.isWarnEnabled()) - { - log.warn(String.format(message, args)); - } - } - - public void warn(Throwable t, String message, Object ... args) - { - if (log.isWarnEnabled()) - { - log.warn(String.format(message, args), t); - } - } - - public void info(String message, Object ... args) - { - if (log.isInfoEnabled()) - { - log.info(String.format(message, args)); - } - } - - public void info(Throwable t, String message, Object ... args) - { - if (log.isInfoEnabled()) - { - log.info(String.format(message, args), t); - } - } - - public void trace(String message, Object ... args) - { - if (log.isTraceEnabled()) - { - log.trace(String.format(message, args)); - } - } - - public void trace(Throwable t, String message, Object ... args) - { - if (log.isTraceEnabled()) - { - log.trace(String.format(message, args), t); - } - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/util/SliceIterator.java b/java/common/src/main/java/org/apache/qpidity/transport/util/SliceIterator.java deleted file mode 100644 index 32392a3561..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/transport/util/SliceIterator.java +++ /dev/null @@ -1,59 +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.qpidity.transport.util; - -import java.nio.ByteBuffer; - -import java.util.Iterator; - - -/** - * SliceIterator - * - * @author Rafael H. Schloming - */ - -public class SliceIterator implements Iterator -{ - - final private Iterator iterator; - - public SliceIterator(Iterator iterator) - { - this.iterator = iterator; - } - - public boolean hasNext() - { - return iterator.hasNext(); - } - - public ByteBuffer next() - { - return iterator.next().slice(); - } - - public void remove() - { - throw new UnsupportedOperationException(); - } - -} diff --git a/java/common/src/test/java/org/apache/qpid/transport/ConnectionTest.java b/java/common/src/test/java/org/apache/qpid/transport/ConnectionTest.java new file mode 100644 index 0000000000..a211b1d937 --- /dev/null +++ b/java/common/src/test/java/org/apache/qpid/transport/ConnectionTest.java @@ -0,0 +1,118 @@ +/* + * + * 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.transport; + +import org.apache.mina.util.AvailablePortFinder; + +import org.apache.qpid.util.concurrent.Condition; + +import org.apache.qpid.transport.network.io.IoTransport; +import org.apache.qpid.transport.network.mina.MinaHandler; +import org.apache.qpid.transport.util.Logger; + +import junit.framework.TestCase; + +import java.util.Random; + +/** + * ConnectionTest + */ + +public class ConnectionTest extends TestCase +{ + + private static final Logger log = Logger.get(ConnectionTest.class); + + private int port; + + protected void setUp() throws Exception + { + super.setUp(); + + port = AvailablePortFinder.getNextAvailable(12000); + + ConnectionDelegate server = new ConnectionDelegate() { + public void init(Channel ch, ProtocolHeader hdr) { + ch.getConnection().close(); + } + + public SessionDelegate getSessionDelegate() { + return new SessionDelegate() {}; + } + public void exception(Throwable t) { + log.error(t, "exception caught"); + } + public void closed() {} + }; + + MinaHandler.accept("localhost", port, server); + } + + private Connection connect(final Condition closed) + { + Connection conn = IoTransport.connect("localhost", port, new ConnectionDelegate() + { + public SessionDelegate getSessionDelegate() + { + return new SessionDelegate() {}; + } + public void exception(Throwable t) + { + t.printStackTrace(); + } + public void closed() + { + if (closed != null) + { + closed.set(); + } + } + }); + + conn.send(new ProtocolHeader(1, 0, 10)); + return conn; + } + + public void testClosedNotificationAndWriteToClosed() throws Exception + { + Condition closed = new Condition(); + Connection conn = connect(closed); + if (!closed.get(3000)) + { + fail("never got notified of connection close"); + } + + Channel ch = conn.getChannel(0); + Session ssn = new Session("test".getBytes()); + ssn.attach(ch); + + try + { + ssn.sessionAttach(ssn.getName()); + fail("writing to a closed socket succeeded"); + } + catch (TransportException e) + { + // expected + } + } + +} diff --git a/java/common/src/test/java/org/apache/qpid/transport/RangeSetTest.java b/java/common/src/test/java/org/apache/qpid/transport/RangeSetTest.java new file mode 100644 index 0000000000..ad45d00e46 --- /dev/null +++ b/java/common/src/test/java/org/apache/qpid/transport/RangeSetTest.java @@ -0,0 +1,238 @@ +/* + * + * 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.transport; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import junit.framework.TestCase; + +import static org.apache.qpid.util.Serial.*; + +/** + * RangeSetTest + * + */ + +public class RangeSetTest extends TestCase +{ + + private void check(RangeSet ranges) + { + List posts = new ArrayList(); + for (Range range : ranges) + { + posts.add(range.getLower()); + posts.add(range.getUpper()); + } + + List sorted = new ArrayList(posts); + Collections.sort(sorted, COMPARATOR); + + assertEquals(posts, sorted); + + int idx = 1; + while (idx + 1 < posts.size()) + { + assertTrue(!eq(posts.get(idx) + 1, posts.get(idx+1))); + idx += 2; + } + } + + public void test1() + { + RangeSet ranges = new RangeSet(); + ranges.add(5, 10); + check(ranges); + ranges.add(15, 20); + check(ranges); + ranges.add(23, 25); + check(ranges); + ranges.add(12, 14); + check(ranges); + ranges.add(0, 1); + check(ranges); + ranges.add(3, 11); + check(ranges); + } + + public void test2() + { + RangeSet rs = new RangeSet(); + check(rs); + + rs.add(1); + assertTrue(rs.includes(1)); + assertTrue(!rs.includes(2)); + assertTrue(!rs.includes(0)); + check(rs); + + rs.add(2); + assertTrue(!rs.includes(0)); + assertTrue(rs.includes(1)); + assertTrue(rs.includes(2)); + assertTrue(!rs.includes(3)); + check(rs); + + rs.add(0); + + assertTrue(!rs.includes(-1)); + assertTrue(rs.includes(0)); + assertTrue(rs.includes(1)); + assertTrue(rs.includes(2)); + assertTrue(!rs.includes(3)); + check(rs); + + rs.add(37); + + assertTrue(!rs.includes(-1)); + assertTrue(rs.includes(0)); + assertTrue(rs.includes(1)); + assertTrue(rs.includes(2)); + assertTrue(!rs.includes(3)); + assertTrue(!rs.includes(36)); + assertTrue(rs.includes(37)); + assertTrue(!rs.includes(38)); + check(rs); + + rs.add(-1); + check(rs); + + rs.add(-3); + check(rs); + + rs.add(1, 20); + assertTrue(!rs.includes(21)); + assertTrue(rs.includes(20)); + check(rs); + } + + public void testAddSelf() + { + RangeSet a = new RangeSet(); + a.add(0, 8); + check(a); + a.add(0, 8); + check(a); + assertEquals(a.size(), 1); + Range range = a.iterator().next(); + assertEquals(range.getLower(), 0); + assertEquals(range.getUpper(), 8); + } + + public void testIntersect1() + { + Range a = new Range(0, 10); + Range b = new Range(9, 20); + Range i1 = a.intersect(b); + Range i2 = b.intersect(a); + assertEquals(i1.getUpper(), 10); + assertEquals(i2.getUpper(), 10); + assertEquals(i1.getLower(), 9); + assertEquals(i2.getLower(), 9); + } + + public void testIntersect2() + { + Range a = new Range(0, 10); + Range b = new Range(11, 20); + assertNull(a.intersect(b)); + assertNull(b.intersect(a)); + } + + public void testIntersect3() + { + Range a = new Range(0, 10); + Range b = new Range(3, 5); + Range i1 = a.intersect(b); + Range i2 = b.intersect(a); + assertEquals(i1.getUpper(), 5); + assertEquals(i2.getUpper(), 5); + assertEquals(i1.getLower(), 3); + assertEquals(i2.getLower(), 3); + } + + public void testSubtract1() + { + Range a = new Range(0, 10); + assertTrue(a.subtract(a).isEmpty()); + } + + public void testSubtract2() + { + Range a = new Range(0, 10); + Range b = new Range(20, 30); + List ranges = a.subtract(b); + assertEquals(ranges.size(), 1); + Range d = ranges.get(0); + assertEquals(d.getLower(), a.getLower()); + assertEquals(d.getUpper(), a.getUpper()); + } + + public void testSubtract3() + { + Range a = new Range(20, 30); + Range b = new Range(0, 10); + List ranges = a.subtract(b); + assertEquals(ranges.size(), 1); + Range d = ranges.get(0); + assertEquals(d.getLower(), a.getLower()); + assertEquals(d.getUpper(), a.getUpper()); + } + + public void testSubtract4() + { + Range a = new Range(0, 10); + Range b = new Range(3, 5); + List ranges = a.subtract(b); + assertEquals(ranges.size(), 2); + Range low = ranges.get(0); + Range high = ranges.get(1); + assertEquals(low.getLower(), 0); + assertEquals(low.getUpper(), 2); + assertEquals(high.getLower(), 6); + assertEquals(high.getUpper(), 10); + } + + public void testSubtract5() + { + Range a = new Range(0, 10); + Range b = new Range(3, 20); + List ranges = a.subtract(b); + assertEquals(ranges.size(), 1); + Range d = ranges.get(0); + assertEquals(d.getLower(), 0); + assertEquals(d.getUpper(), 2); + } + + public void testSubtract6() + { + Range a = new Range(0, 10); + Range b = new Range(-10, 5); + List ranges = a.subtract(b); + assertEquals(ranges.size(), 1); + Range d = ranges.get(0); + assertEquals(d.getLower(), 6); + assertEquals(d.getUpper(), 10); + } + +} diff --git a/java/common/src/test/java/org/apache/qpidity/transport/ConnectionTest.java b/java/common/src/test/java/org/apache/qpidity/transport/ConnectionTest.java deleted file mode 100644 index c604aaf3e4..0000000000 --- a/java/common/src/test/java/org/apache/qpidity/transport/ConnectionTest.java +++ /dev/null @@ -1,118 +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.qpidity.transport; - -import org.apache.mina.util.AvailablePortFinder; - -import org.apache.qpid.util.concurrent.Condition; - -import org.apache.qpidity.transport.network.io.IoTransport; -import org.apache.qpidity.transport.network.mina.MinaHandler; -import org.apache.qpidity.transport.util.Logger; - -import junit.framework.TestCase; - -import java.util.Random; - -/** - * ConnectionTest - */ - -public class ConnectionTest extends TestCase -{ - - private static final Logger log = Logger.get(ConnectionTest.class); - - private int port; - - protected void setUp() throws Exception - { - super.setUp(); - - port = AvailablePortFinder.getNextAvailable(12000); - - ConnectionDelegate server = new ConnectionDelegate() { - public void init(Channel ch, ProtocolHeader hdr) { - ch.getConnection().close(); - } - - public SessionDelegate getSessionDelegate() { - return new SessionDelegate() {}; - } - public void exception(Throwable t) { - log.error(t, "exception caught"); - } - public void closed() {} - }; - - MinaHandler.accept("localhost", port, server); - } - - private Connection connect(final Condition closed) - { - Connection conn = IoTransport.connect("localhost", port, new ConnectionDelegate() - { - public SessionDelegate getSessionDelegate() - { - return new SessionDelegate() {}; - } - public void exception(Throwable t) - { - t.printStackTrace(); - } - public void closed() - { - if (closed != null) - { - closed.set(); - } - } - }); - - conn.send(new ProtocolHeader(1, 0, 10)); - return conn; - } - - public void testClosedNotificationAndWriteToClosed() throws Exception - { - Condition closed = new Condition(); - Connection conn = connect(closed); - if (!closed.get(3000)) - { - fail("never got notified of connection close"); - } - - Channel ch = conn.getChannel(0); - Session ssn = new Session("test".getBytes()); - ssn.attach(ch); - - try - { - ssn.sessionAttach(ssn.getName()); - fail("writing to a closed socket succeeded"); - } - catch (TransportException e) - { - // expected - } - } - -} diff --git a/java/common/src/test/java/org/apache/qpidity/transport/RangeSetTest.java b/java/common/src/test/java/org/apache/qpidity/transport/RangeSetTest.java deleted file mode 100644 index 474d47d8d7..0000000000 --- a/java/common/src/test/java/org/apache/qpidity/transport/RangeSetTest.java +++ /dev/null @@ -1,238 +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.qpidity.transport; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import junit.framework.TestCase; - -import static org.apache.qpid.util.Serial.*; - -/** - * RangeSetTest - * - */ - -public class RangeSetTest extends TestCase -{ - - private void check(RangeSet ranges) - { - List posts = new ArrayList(); - for (Range range : ranges) - { - posts.add(range.getLower()); - posts.add(range.getUpper()); - } - - List sorted = new ArrayList(posts); - Collections.sort(sorted, COMPARATOR); - - assertEquals(posts, sorted); - - int idx = 1; - while (idx + 1 < posts.size()) - { - assertTrue(!eq(posts.get(idx) + 1, posts.get(idx+1))); - idx += 2; - } - } - - public void test1() - { - RangeSet ranges = new RangeSet(); - ranges.add(5, 10); - check(ranges); - ranges.add(15, 20); - check(ranges); - ranges.add(23, 25); - check(ranges); - ranges.add(12, 14); - check(ranges); - ranges.add(0, 1); - check(ranges); - ranges.add(3, 11); - check(ranges); - } - - public void test2() - { - RangeSet rs = new RangeSet(); - check(rs); - - rs.add(1); - assertTrue(rs.includes(1)); - assertTrue(!rs.includes(2)); - assertTrue(!rs.includes(0)); - check(rs); - - rs.add(2); - assertTrue(!rs.includes(0)); - assertTrue(rs.includes(1)); - assertTrue(rs.includes(2)); - assertTrue(!rs.includes(3)); - check(rs); - - rs.add(0); - - assertTrue(!rs.includes(-1)); - assertTrue(rs.includes(0)); - assertTrue(rs.includes(1)); - assertTrue(rs.includes(2)); - assertTrue(!rs.includes(3)); - check(rs); - - rs.add(37); - - assertTrue(!rs.includes(-1)); - assertTrue(rs.includes(0)); - assertTrue(rs.includes(1)); - assertTrue(rs.includes(2)); - assertTrue(!rs.includes(3)); - assertTrue(!rs.includes(36)); - assertTrue(rs.includes(37)); - assertTrue(!rs.includes(38)); - check(rs); - - rs.add(-1); - check(rs); - - rs.add(-3); - check(rs); - - rs.add(1, 20); - assertTrue(!rs.includes(21)); - assertTrue(rs.includes(20)); - check(rs); - } - - public void testAddSelf() - { - RangeSet a = new RangeSet(); - a.add(0, 8); - check(a); - a.add(0, 8); - check(a); - assertEquals(a.size(), 1); - Range range = a.iterator().next(); - assertEquals(range.getLower(), 0); - assertEquals(range.getUpper(), 8); - } - - public void testIntersect1() - { - Range a = new Range(0, 10); - Range b = new Range(9, 20); - Range i1 = a.intersect(b); - Range i2 = b.intersect(a); - assertEquals(i1.getUpper(), 10); - assertEquals(i2.getUpper(), 10); - assertEquals(i1.getLower(), 9); - assertEquals(i2.getLower(), 9); - } - - public void testIntersect2() - { - Range a = new Range(0, 10); - Range b = new Range(11, 20); - assertNull(a.intersect(b)); - assertNull(b.intersect(a)); - } - - public void testIntersect3() - { - Range a = new Range(0, 10); - Range b = new Range(3, 5); - Range i1 = a.intersect(b); - Range i2 = b.intersect(a); - assertEquals(i1.getUpper(), 5); - assertEquals(i2.getUpper(), 5); - assertEquals(i1.getLower(), 3); - assertEquals(i2.getLower(), 3); - } - - public void testSubtract1() - { - Range a = new Range(0, 10); - assertTrue(a.subtract(a).isEmpty()); - } - - public void testSubtract2() - { - Range a = new Range(0, 10); - Range b = new Range(20, 30); - List ranges = a.subtract(b); - assertEquals(ranges.size(), 1); - Range d = ranges.get(0); - assertEquals(d.getLower(), a.getLower()); - assertEquals(d.getUpper(), a.getUpper()); - } - - public void testSubtract3() - { - Range a = new Range(20, 30); - Range b = new Range(0, 10); - List ranges = a.subtract(b); - assertEquals(ranges.size(), 1); - Range d = ranges.get(0); - assertEquals(d.getLower(), a.getLower()); - assertEquals(d.getUpper(), a.getUpper()); - } - - public void testSubtract4() - { - Range a = new Range(0, 10); - Range b = new Range(3, 5); - List ranges = a.subtract(b); - assertEquals(ranges.size(), 2); - Range low = ranges.get(0); - Range high = ranges.get(1); - assertEquals(low.getLower(), 0); - assertEquals(low.getUpper(), 2); - assertEquals(high.getLower(), 6); - assertEquals(high.getUpper(), 10); - } - - public void testSubtract5() - { - Range a = new Range(0, 10); - Range b = new Range(3, 20); - List ranges = a.subtract(b); - assertEquals(ranges.size(), 1); - Range d = ranges.get(0); - assertEquals(d.getLower(), 0); - assertEquals(d.getUpper(), 2); - } - - public void testSubtract6() - { - Range a = new Range(0, 10); - Range b = new Range(-10, 5); - List ranges = a.subtract(b); - assertEquals(ranges.size(), 1); - Range d = ranges.get(0); - assertEquals(d.getLower(), 6); - assertEquals(d.getUpper(), 10); - } - -} diff --git a/java/log4j-test.xml b/java/log4j-test.xml index a27d9fef2e..c242286b70 100644 --- a/java/log4j-test.xml +++ b/java/log4j-test.xml @@ -38,10 +38,6 @@ - - - - diff --git a/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionCloseTest.java b/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionCloseTest.java index 410939f583..b932b1d784 100644 --- a/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionCloseTest.java +++ b/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionCloseTest.java @@ -21,7 +21,7 @@ package org.apache.qpid.test.unit.client.connection; import org.apache.qpid.test.utils.QpidTestCase; -import org.apache.qpidity.transport.util.Logger; +import org.apache.qpid.transport.util.Logger; import java.util.HashMap; import java.util.Map; diff --git a/java/systests/src/main/java/org/apache/qpid/test/unit/xa/AbstractXATestCase.java b/java/systests/src/main/java/org/apache/qpid/test/unit/xa/AbstractXATestCase.java index 42811ed390..3906be2cc7 100644 --- a/java/systests/src/main/java/org/apache/qpid/test/unit/xa/AbstractXATestCase.java +++ b/java/systests/src/main/java/org/apache/qpid/test/unit/xa/AbstractXATestCase.java @@ -17,7 +17,7 @@ */ package org.apache.qpid.test.unit.xa; -import org.apache.qpidity.dtx.XidImpl; +import org.apache.qpid.dtx.XidImpl; import org.apache.qpid.test.utils.QpidTestCase; import javax.transaction.xa.Xid; diff --git a/java/testkit/etc/test.log4j b/java/testkit/etc/test.log4j index 7d7ebcc802..b574a7b5b7 100644 --- a/java/testkit/etc/test.log4j +++ b/java/testkit/etc/test.log4j @@ -21,9 +21,6 @@ log4j.rootLogger=${root.logging.level} log4j.logger.org.apache.qpid=ERROR, console log4j.additivity.org.apache.qpid=false -log4j.logger.org.apache.qpidity=TRACE, console -log4j.additivity.org.apache.qpidity=false - log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.Threshold=all log4j.appender.console.layout=org.apache.log4j.PatternLayout -- cgit v1.2.1