Beispiel #1
0
  /**
   * Load enough bytes from channel to buffer. After the loading process, the caller can make sure
   * the amount in buffer is of size 'amount' if we haven't reached the end of channel.
   *
   * @param amount The amount of bytes in buffer after returning, no larger than bufferSize
   * @param reload Whether to reload or append
   */
  private void fillBuffer(long amount, boolean reload) {
    try {
      if (amount > bufferSize) {
        amount = bufferSize;
      }
      // Read all remaining bytes if the requested amount reach the end
      // of channel.
      if (channelSize - channel.position() < amount) {
        amount = channelSize - channel.position();
      }

      if (in == null) {
        switch (bufferType) {
          case HEAP:
            in = ByteBuffer.allocate(bufferSize, false);
            break;
          case DIRECT:
            in = ByteBuffer.allocate(bufferSize, true);
            break;
          case AUTO:
            in = ByteBuffer.allocate(bufferSize);
            break;
          default:
            in = ByteBuffer.allocate(bufferSize);
        }
        channel.read(in.buf());
        in.flip();
        useLoadBuf = true;
      }

      if (!useLoadBuf) {
        return;
      }

      if (reload || in.remaining() < amount) {
        if (!reload) {
          in.compact();
        } else {
          in.clear();
        }
        channel.read(in.buf());
        in.flip();
      }

    } catch (Exception e) {
      log.error("Error fillBuffer", e);
    }
  }
  private void sendMessages(int messageCount, boolean persistent) throws AMQException {
    for (int i = 0; i < messageCount; i++) {
      IncomingMessage currentMessage = message(false, persistent);
      ArrayList<AMQQueue> qs = new ArrayList<AMQQueue>();
      qs.add(getQueue());
      currentMessage.enqueue(qs);

      // route header
      MessageMetaData mmd = currentMessage.headersReceived();
      currentMessage.setStoredMessage(getMessageStore().addMessage(mmd));

      // Add the body so we have somthing to test later
      currentMessage.addContentBodyFrame(
          getSession()
              .getMethodRegistry()
              .getProtocolVersionMethodConverter()
              .convertToContentChunk(
                  new ContentBody(ByteBuffer.allocate((int) MESSAGE_SIZE), MESSAGE_SIZE)));

      AMQMessage m = new AMQMessage(currentMessage.getStoredMessage());
      for (BaseQueue q : currentMessage.getDestinationQueues()) {
        q.enqueue(m);
      }
    }
  }
  /** Tests that two simple receives work. */
  public void testMultipleSimpleReceives() {
    int len = 1000;
    byte[] expected = getByteSequence(len);
    ByteBuffer buf = ByteBuffer.allocate(len + 4, false);
    buf.putInt(len);
    buf.put(expected);
    buf = buf.asReadOnlyBuffer();
    buf.flip();

    assertEquals(0, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    harness.recv(buf);

    assertEquals(0, sentMessages.size());
    assertEquals(1, receivedMessages.size());

    byte[] actual = receivedMessages.get(0);

    assertTrue("Incorrect recv!", Arrays.equals(actual, expected));

    harness.recv(buf.rewind());

    assertEquals(0, sentMessages.size());
    assertEquals(2, receivedMessages.size());

    actual = receivedMessages.get(1);

    assertTrue("Incorrect recv!", Arrays.equals(actual, expected));
  }
  /** Tests handling of exceptions during dispatch. */
  public void testReceiveHandlingException() {
    int len = 1000;
    byte[] expected = getByteSequence(len);
    ByteBuffer buf = ByteBuffer.allocate(len + 4, false);
    buf.putInt(len);
    buf.put(expected);
    buf = buf.asReadOnlyBuffer();
    buf.flip();

    assertEquals(0, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    RuntimeException expectedEx = new RuntimeException("Dummy exception for testing filter recv");

    harness.setExceptionOnNextCompleteMessage(expectedEx);

    // This recv will fail to process the message
    harness.recv(buf);
    assertEquals(0, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    // Send a second message, expecting the first to have been dropped.
    buf.rewind();
    harness.recv(buf);

    assertEquals(0, sentMessages.size());
    assertEquals(1, receivedMessages.size());
  }
  /**
   * Tests that complete messages are delivered even when the message arrives one byte at a time
   * from the network. Then tests that a second message can still be received all-at-once.
   */
  public void testPartialOneByteReceives() {
    int len = 32;
    byte[] expected = getByteSequence(len);
    ByteBuffer buf = ByteBuffer.allocate(len + 4, false);
    buf.putInt(len);
    buf.put(expected);
    buf = buf.asReadOnlyBuffer();
    buf.flip();

    for (; buf.hasRemaining(); buf.skip(1)) {
      assertEquals(0, sentMessages.size());
      assertEquals(0, receivedMessages.size());
      ByteBuffer singleByte = buf.slice().limit(1);
      harness.recv(singleByte);
    }

    assertEquals(0, sentMessages.size());
    assertEquals(1, receivedMessages.size());

    byte[] actual = receivedMessages.get(0);

    assertTrue("Incorrect recv!", Arrays.equals(actual, expected));

    harness.recv(buf.rewind());

    assertEquals(0, sentMessages.size());
    assertEquals(2, receivedMessages.size());

    actual = receivedMessages.get(1);

    assertTrue("Incorrect recv!", Arrays.equals(actual, expected));
  }
  /** Tests handling of exceptions during dispatch. */
  public void testReceiveHandlingExceptionPartial() {
    int len1 = 400;
    int len2 = 600;
    int len = len1 + len2;
    byte[] expected = getByteSequence(len);
    ByteBuffer buf = ByteBuffer.allocate(len + 4, false);
    buf.putInt(len);
    buf.put(expected);
    buf = buf.asReadOnlyBuffer();
    buf.flip();

    assertEquals(0, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    ByteBuffer part1 = buf.slice().limit(len1 + 4);

    ByteBuffer part2 = ByteBuffer.allocate(len2 + len2 + 4, false);
    buf.rewind();
    buf.skip(len1 + 4);
    part2.put(buf);
    buf.rewind();
    buf.skip(len1 + 4);
    part2.putInt(len2);
    part2.put(buf);
    part2.flip();

    assertEquals(0, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    harness.recv(part1);

    assertEquals(0, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    RuntimeException expectedEx = new RuntimeException("Dummy exception for testing filter recv");

    harness.setExceptionOnNextCompleteMessage(expectedEx);

    // This recv should process the second message.
    harness.recv(part2);

    assertEquals(0, sentMessages.size());
    assertEquals(1, receivedMessages.size());

    byte[] actual = receivedMessages.get(0);
    assertEquals(len2, actual.length);
  }
  @Override
  public ByteBuffer encodedContent() {
    ByteBuffer ret = ByteBuffer.allocate(32);
    ret.setAutoExpand(true);

    User.writeTo(user, ret);

    ret.flip();

    return ret;
  }
Beispiel #8
0
  /**
   * 转换为字节数组,包括长度
   *
   * @return
   */
  public byte[] getByties() {
    int size = countSize();

    ByteBuffer buffer = ByteBuffer.allocate(size);

    writeBuffer(buffer);

    buffer.flip();

    byte[] ret = new byte[size];

    buffer.get(ret);

    return ret;
  }
Beispiel #9
0
  /** {@inheritDoc} */
  public synchronized ITag readTag() {
    long oldPos = getCurrentPosition();
    ITag tag = readTagHeader();

    if (tagPosition == 0 && tag.getDataType() != TYPE_METADATA && generateMetadata) {
      // Generate initial metadata automatically
      setCurrentPosition(oldPos);
      KeyFrameMeta meta = analyzeKeyFrames();
      tagPosition++;
      if (meta != null) {
        return createFileMeta();
      }
    }

    ByteBuffer body = ByteBuffer.allocate(tag.getBodySize(), false);

    // XXX Paul: this assists in 'properly' handling damaged FLV files
    long newPosition = getCurrentPosition() + tag.getBodySize();
    if (newPosition <= getTotalBytes()) {
      int limit;
      while (getCurrentPosition() < newPosition) {
        fillBuffer(newPosition - getCurrentPosition());
        if (getCurrentPosition() + in.remaining() > newPosition) {
          limit = in.limit();
          in.limit((int) (newPosition - getCurrentPosition()) + in.position());
          body.put(in);
          in.limit(limit);
        } else {
          body.put(in);
        }
      }

      body.flip();
      tag.setBody(body);
      tagPosition++;
    }

    return tag;
  }
Beispiel #10
0
  /**
   * Create tag for metadata event.
   *
   * @return Metadata event tag
   */
  private ITag createFileMeta() {
    // Create tag for onMetaData event
    ByteBuffer buf = ByteBuffer.allocate(1024);
    buf.setAutoExpand(true);
    Output out = new Output(buf);

    // Duration property
    out.writeString("onMetaData");
    Map<Object, Object> props = new HashMap<Object, Object>();
    props.put("duration", duration / 1000.0);
    if (firstVideoTag != -1) {
      long old = getCurrentPosition();
      setCurrentPosition(firstVideoTag);
      readTagHeader();
      fillBuffer(1);
      byte frametype = in.get();
      // Video codec id
      props.put("videocodecid", frametype & MASK_VIDEO_CODEC);
      setCurrentPosition(old);
    }
    if (firstAudioTag != -1) {
      long old = getCurrentPosition();
      setCurrentPosition(firstAudioTag);
      readTagHeader();
      fillBuffer(1);
      byte frametype = in.get();
      // Audio codec id
      props.put("audiocodecid", (frametype & MASK_SOUND_FORMAT) >> 4);
      setCurrentPosition(old);
    }
    props.put("canSeekToEnd", true);
    out.writeMap(props, new Serializer());
    buf.flip();

    ITag result = new Tag(IoConstants.TYPE_METADATA, 0, buf.limit(), null, 0);
    result.setBody(buf);
    return result;
  }
  /** Tests that the send filter correctly prepends the message length. */
  public void testSend() {
    int len = 1000;
    byte[] sendData = getByteSequence(len);
    ByteBuffer buf = ByteBuffer.allocate(len + 4, false);
    buf.putInt(len);
    buf.put(sendData);
    buf = buf.asReadOnlyBuffer();
    buf.flip();

    byte[] expected = new byte[buf.remaining()];
    buf.get(expected);

    assertEquals(0, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    harness.send(sendData);

    assertEquals(1, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    byte[] actual = sentMessages.get(0);

    assertTrue("Incorrect send!", Arrays.equals(actual, expected));
  }
/**
 * This suite of tests is intended to test the functionality of the {code CompleteMessageFilter}.
 */
public class MessageFilterTest extends TestCase implements FilterTestHarness.Callback {
  final ByteBuffer sizeBuf = ByteBuffer.allocate(4, false);
  final List<byte[]> receivedMessages = new ArrayList<byte[]>();
  final List<byte[]> sentMessages = new ArrayList<byte[]>();

  FilterTestHarness harness = null;

  /**
   * Sets up a {@link FilterTestHarness} for this test, and clears the list of received and sent
   * messages.
   */
  @Override
  public void setUp() {
    System.err.println("Testcase: " + this.getName());
    sizeBuf.sweep();
    receivedMessages.clear();
    sentMessages.clear();
    harness = new FilterTestHarness(this);
  }

  /** Performs cleanup after each test case. */
  @Override
  public void tearDown() {
    sizeBuf.clear();
    receivedMessages.clear();
    sentMessages.clear();
    harness = null;
  }

  /** {@inheritDoc} */
  public void filteredMessageReceived(ByteBuffer buf) {
    addToList(receivedMessages, buf);
  }

  /** {@inheritDoc} */
  public void sendUnfiltered(ByteBuffer buf) {
    addToList(sentMessages, buf);
  }

  private void addToList(List<byte[]> list, ByteBuffer buf) {
    byte[] bytes = new byte[buf.remaining()];
    buf.get(bytes);
    list.add(bytes);
  }

  private byte[] getByteSequence(int size) {
    byte[] seq = new byte[size];
    for (int i = 0; i < size; ++i) {
      seq[i] = (byte) (i & 0xFF);
    }
    return seq;
  }

  /** Tests that a simple receive works. */
  public void testSimpleReceive() {
    int len = 1000;
    byte[] expected = getByteSequence(len);
    ByteBuffer buf = ByteBuffer.allocate(len + 4, false);
    buf.putInt(len);
    buf.put(expected);
    buf = buf.asReadOnlyBuffer();
    buf.flip();

    assertEquals(0, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    harness.recv(buf);

    assertEquals(0, sentMessages.size());
    assertEquals(1, receivedMessages.size());

    byte[] actual = receivedMessages.get(0);

    assertTrue("Incorrect recv!", Arrays.equals(actual, expected));
  }

  /** Tests that two simple receives work. */
  public void testMultipleSimpleReceives() {
    int len = 1000;
    byte[] expected = getByteSequence(len);
    ByteBuffer buf = ByteBuffer.allocate(len + 4, false);
    buf.putInt(len);
    buf.put(expected);
    buf = buf.asReadOnlyBuffer();
    buf.flip();

    assertEquals(0, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    harness.recv(buf);

    assertEquals(0, sentMessages.size());
    assertEquals(1, receivedMessages.size());

    byte[] actual = receivedMessages.get(0);

    assertTrue("Incorrect recv!", Arrays.equals(actual, expected));

    harness.recv(buf.rewind());

    assertEquals(0, sentMessages.size());
    assertEquals(2, receivedMessages.size());

    actual = receivedMessages.get(1);

    assertTrue("Incorrect recv!", Arrays.equals(actual, expected));
  }

  /** Tests that a big message gets reassembled by the filter. */
  public void testBigReceive() {
    // Send a 62KB message in 1KB chunks
    int len = 62 * 1024;
    byte[] expected = new byte[len];
    sizeBuf.putInt(len).flip();
    harness.recv(sizeBuf.asReadOnlyBuffer());

    ByteBuffer buf = ByteBuffer.wrap(getByteSequence(1024)).asReadOnlyBuffer();

    // Do the recvs
    for (int i = 0; i < 62; ++i) {
      assertEquals(0, sentMessages.size());
      assertEquals(0, receivedMessages.size());

      buf.rewind();
      buf.get(expected, i * 1024, 1024);
      buf.rewind();
      harness.recv(buf);
    }

    assertEquals(0, sentMessages.size());
    assertEquals(1, receivedMessages.size());

    byte[] actual = receivedMessages.get(0);

    assertTrue("Incorrect recv!", Arrays.equals(actual, expected));
  }

  /** Tests that zero-byte receives have no effect on complete message delivery. */
  public void testPartialReceiveNoBytes() {
    int len = 1000;

    sizeBuf.putInt(len).flip();
    harness.recv(sizeBuf.asReadOnlyBuffer());

    ByteBuffer emptyBuf = sizeBuf.slice().limit(0).asReadOnlyBuffer();
    harness.recv(emptyBuf);

    assertEquals(0, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    byte[] expected = getByteSequence(len);
    ByteBuffer buf = ByteBuffer.wrap(expected).asReadOnlyBuffer();

    harness.recv(buf);

    assertEquals(0, sentMessages.size());
    assertEquals(1, receivedMessages.size());

    byte[] actual = receivedMessages.get(0);

    assertTrue("Incorrect recv!", Arrays.equals(actual, expected));

    harness.recv(emptyBuf);

    assertEquals(0, sentMessages.size());
    assertEquals(1, receivedMessages.size());

    harness.recv(sizeBuf.rewind().asReadOnlyBuffer());
    harness.recv(buf.rewind());

    assertEquals(0, sentMessages.size());
    assertEquals(2, receivedMessages.size());

    actual = receivedMessages.get(1);

    assertTrue("Incorrect recv!", Arrays.equals(actual, expected));
  }

  /**
   * Tests that complete messages are delivered even when the message arrives one byte at a time
   * from the network. Then tests that a second message can still be received all-at-once.
   */
  public void testPartialOneByteReceives() {
    int len = 32;
    byte[] expected = getByteSequence(len);
    ByteBuffer buf = ByteBuffer.allocate(len + 4, false);
    buf.putInt(len);
    buf.put(expected);
    buf = buf.asReadOnlyBuffer();
    buf.flip();

    for (; buf.hasRemaining(); buf.skip(1)) {
      assertEquals(0, sentMessages.size());
      assertEquals(0, receivedMessages.size());
      ByteBuffer singleByte = buf.slice().limit(1);
      harness.recv(singleByte);
    }

    assertEquals(0, sentMessages.size());
    assertEquals(1, receivedMessages.size());

    byte[] actual = receivedMessages.get(0);

    assertTrue("Incorrect recv!", Arrays.equals(actual, expected));

    harness.recv(buf.rewind());

    assertEquals(0, sentMessages.size());
    assertEquals(2, receivedMessages.size());

    actual = receivedMessages.get(1);

    assertTrue("Incorrect recv!", Arrays.equals(actual, expected));
  }

  /** Tests handling of a valid message with payload length zero. */
  public void testReceiveValidZeroLength() {
    sizeBuf.putInt(0).flip();

    harness.recv(sizeBuf.asReadOnlyBuffer());

    assertEquals(0, sentMessages.size());
    assertEquals(1, receivedMessages.size());

    assertEquals(0, receivedMessages.get(0).length);
  }

  /** Tests handling of exceptions during dispatch. */
  public void testReceiveHandlingException() {
    int len = 1000;
    byte[] expected = getByteSequence(len);
    ByteBuffer buf = ByteBuffer.allocate(len + 4, false);
    buf.putInt(len);
    buf.put(expected);
    buf = buf.asReadOnlyBuffer();
    buf.flip();

    assertEquals(0, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    RuntimeException expectedEx = new RuntimeException("Dummy exception for testing filter recv");

    harness.setExceptionOnNextCompleteMessage(expectedEx);

    // This recv will fail to process the message
    harness.recv(buf);
    assertEquals(0, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    // Send a second message, expecting the first to have been dropped.
    buf.rewind();
    harness.recv(buf);

    assertEquals(0, sentMessages.size());
    assertEquals(1, receivedMessages.size());
  }

  /** Tests handling of exceptions during dispatch. */
  public void testReceiveHandlingExceptionPartial() {
    int len1 = 400;
    int len2 = 600;
    int len = len1 + len2;
    byte[] expected = getByteSequence(len);
    ByteBuffer buf = ByteBuffer.allocate(len + 4, false);
    buf.putInt(len);
    buf.put(expected);
    buf = buf.asReadOnlyBuffer();
    buf.flip();

    assertEquals(0, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    ByteBuffer part1 = buf.slice().limit(len1 + 4);

    ByteBuffer part2 = ByteBuffer.allocate(len2 + len2 + 4, false);
    buf.rewind();
    buf.skip(len1 + 4);
    part2.put(buf);
    buf.rewind();
    buf.skip(len1 + 4);
    part2.putInt(len2);
    part2.put(buf);
    part2.flip();

    assertEquals(0, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    harness.recv(part1);

    assertEquals(0, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    RuntimeException expectedEx = new RuntimeException("Dummy exception for testing filter recv");

    harness.setExceptionOnNextCompleteMessage(expectedEx);

    // This recv should process the second message.
    harness.recv(part2);

    assertEquals(0, sentMessages.size());
    assertEquals(1, receivedMessages.size());

    byte[] actual = receivedMessages.get(0);
    assertEquals(len2, actual.length);
  }

  /** Tests that the send filter correctly prepends the message length. */
  public void testSend() {
    int len = 1000;
    byte[] sendData = getByteSequence(len);
    ByteBuffer buf = ByteBuffer.allocate(len + 4, false);
    buf.putInt(len);
    buf.put(sendData);
    buf = buf.asReadOnlyBuffer();
    buf.flip();

    byte[] expected = new byte[buf.remaining()];
    buf.get(expected);

    assertEquals(0, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    harness.send(sendData);

    assertEquals(1, sentMessages.size());
    assertEquals(0, receivedMessages.size());

    byte[] actual = sentMessages.get(0);

    assertTrue("Incorrect send!", Arrays.equals(actual, expected));
  }
}
 /**
  * Create packet with given header
  *
  * @param header Packet header
  */
 public Packet(Header header) {
   this.header = header;
   data = ByteBuffer.allocate(header.getSize() + (header.getTimer() == 0xffffff ? 4 : 0));
 }