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/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 -------- 153 files changed, 9805 insertions(+), 9858 deletions(-) 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/common/src') 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); - } - -} -- cgit v1.2.1