/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.activemq.artemis.core.client.impl; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.ByteBuffer; import org.apache.activemq.artemis.api.core.ActiveMQBuffer; import org.apache.activemq.artemis.api.core.ActiveMQBuffers; import org.apache.activemq.artemis.api.core.ActiveMQException; import org.apache.activemq.artemis.api.core.ActiveMQPropertyConversionException; import org.apache.activemq.artemis.api.core.Message; import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.core.client.ActiveMQClientMessageBundle; import org.apache.activemq.artemis.core.message.LargeBodyEncoder; import org.apache.activemq.artemis.core.message.impl.CoreMessage; import org.apache.activemq.artemis.reader.MessageUtil; import org.apache.activemq.artemis.utils.UUID; import org.apache.activemq.artemis.utils.collections.TypedProperties; /** * A ClientMessageImpl */ public class ClientMessageImpl extends CoreMessage implements ClientMessageInternal { // added this constant here so that the client package have no dependency on JMS public static final SimpleString REPLYTO_HEADER_NAME = MessageUtil.REPLYTO_HEADER_NAME; private int deliveryCount; private ClientConsumerInternal consumer; private int flowControlSize = -1; /** * Used on LargeMessages only */ private InputStream bodyInputStream; /* * Constructor for when reading from remoting */ public ClientMessageImpl() { } protected ClientMessageImpl(ClientMessageImpl other) { super(other); } @Override public ClientMessageImpl setDurable(boolean durable) { super.setDurable(durable); return this; } @Override public ClientMessageImpl setExpiration(long expiration) { super.setExpiration(expiration); return this; } @Override public ClientMessageImpl setPriority(byte priority) { super.setPriority(priority); return this; } @Override public ClientMessageImpl setUserID(UUID userID) { return this; } /* * Construct messages before sending */ public ClientMessageImpl(final byte type, final boolean durable, final long expiration, final long timestamp, final byte priority, final int initialMessageBufferSize) { this.setType(type).setExpiration(expiration).setTimestamp(timestamp).setDurable(durable). setPriority(priority).initBuffer(initialMessageBufferSize); } @Override public TypedProperties getProperties() { return this.checkProperties(); } @Override public void onReceipt(final ClientConsumerInternal consumer) { this.consumer = consumer; } @Override public ClientMessageImpl setDeliveryCount(final int deliveryCount) { this.deliveryCount = deliveryCount; return this; } @Override public int getDeliveryCount() { return deliveryCount; } @Override public ClientMessageImpl acknowledge() throws ActiveMQException { if (consumer != null) { consumer.acknowledge(this); } return this; } @Override public ClientMessageImpl individualAcknowledge() throws ActiveMQException { if (consumer != null) { consumer.individualAcknowledge(this); } return this; } @Override public void checkCompletion() throws ActiveMQException { } @Override public int getFlowControlSize() { if (flowControlSize < 0) { throw new IllegalStateException("Flow Control hasn't been set"); } return flowControlSize; } @Override public void setFlowControlSize(final int flowControlSize) { this.flowControlSize = flowControlSize; } /** * @return the largeMessage */ @Override public boolean isLargeMessage() { return false; } @Override public boolean isCompressed() { return properties.getBooleanProperty(Message.HDR_LARGE_COMPRESSED); } @Override public int getBodySize() { return getBodyBuffer().writerIndex() - getBodyBuffer().readerIndex(); } @Override public String toString() { return getClass().getSimpleName() + "[messageID=" + messageID + ", durable=" + durable + ", address=" + getAddress() + ",userID=" + (getUserID() != null ? getUserID() : "null") + ",properties=" + getProperties().toString() + "]"; } @Override public void saveToOutputStream(final OutputStream out) throws ActiveMQException { try { byte[] readBuffer = new byte[getBodySize()]; getBodyBuffer().readBytes(readBuffer); out.write(readBuffer); out.flush(); } catch (IOException e) { throw ActiveMQClientMessageBundle.BUNDLE.errorSavingBody(e); } } @Override public ClientMessageImpl setOutputStream(final OutputStream out) throws ActiveMQException { saveToOutputStream(out); return this; } @Override public boolean waitOutputStreamCompletion(final long timeMilliseconds) throws ActiveMQException { return true; } @Override public void discardBody() { } /** * @return the bodyInputStream */ @Override public InputStream getBodyInputStream() { return bodyInputStream; } /** * @param bodyInputStream the bodyInputStream to set */ @Override public ClientMessageImpl setBodyInputStream(final InputStream bodyInputStream) { this.bodyInputStream = bodyInputStream; return this; } @Override public LargeBodyEncoder getBodyEncoder() throws ActiveMQException { return new DecodingContext(); } @Override public ClientMessageImpl putBooleanProperty(final SimpleString key, final boolean value) { return (ClientMessageImpl) super.putBooleanProperty(key, value); } @Override public ClientMessageImpl putByteProperty(final SimpleString key, final byte value) { return (ClientMessageImpl) super.putByteProperty(key, value); } @Override public ClientMessageImpl putBytesProperty(final SimpleString key, final byte[] value) { return (ClientMessageImpl) super.putBytesProperty(key, value); } @Override public ClientMessageImpl putCharProperty(SimpleString key, char value) { return (ClientMessageImpl) super.putCharProperty(key, value); } @Override public ClientMessageImpl putCharProperty(String key, char value) { return (ClientMessageImpl) super.putCharProperty(key, value); } @Override public ClientMessageImpl putShortProperty(final SimpleString key, final short value) { return (ClientMessageImpl) super.putShortProperty(key, value); } @Override public ClientMessageImpl putIntProperty(final SimpleString key, final int value) { return (ClientMessageImpl) super.putIntProperty(key, value); } @Override public ClientMessageImpl putLongProperty(final SimpleString key, final long value) { return (ClientMessageImpl) super.putLongProperty(key, value); } @Override public ClientMessageImpl putFloatProperty(final SimpleString key, final float value) { return (ClientMessageImpl) super.putFloatProperty(key, value); } @Override public ClientMessageImpl putDoubleProperty(final SimpleString key, final double value) { return (ClientMessageImpl) super.putDoubleProperty(key, value); } @Override public ClientMessageImpl putStringProperty(final SimpleString key, final SimpleString value) { return (ClientMessageImpl) super.putStringProperty(key, value); } @Override public ClientMessageImpl putObjectProperty(final SimpleString key, final Object value) throws ActiveMQPropertyConversionException { return (ClientMessageImpl) super.putObjectProperty(key, value); } @Override public ClientMessageImpl putObjectProperty(final String key, final Object value) throws ActiveMQPropertyConversionException { return (ClientMessageImpl) super.putObjectProperty(key, value); } @Override public ClientMessageImpl putBooleanProperty(final String key, final boolean value) { return (ClientMessageImpl) super.putBooleanProperty(key, value); } @Override public ClientMessageImpl putByteProperty(final String key, final byte value) { return (ClientMessageImpl) super.putByteProperty(key, value); } @Override public ClientMessageImpl putBytesProperty(final String key, final byte[] value) { return (ClientMessageImpl) super.putBytesProperty(key, value); } @Override public ClientMessageImpl putShortProperty(final String key, final short value) { return (ClientMessageImpl) super.putShortProperty(key, value); } @Override public ClientMessageImpl putIntProperty(final String key, final int value) { return (ClientMessageImpl) super.putIntProperty(key, value); } @Override public ClientMessageImpl putLongProperty(final String key, final long value) { return (ClientMessageImpl) super.putLongProperty(key, value); } @Override public ClientMessageImpl putFloatProperty(final String key, final float value) { return (ClientMessageImpl) super.putFloatProperty(key, value); } @Override public ClientMessageImpl putDoubleProperty(final String key, final double value) { return (ClientMessageImpl) super.putDoubleProperty(key, value); } @Override public ClientMessageImpl putStringProperty(final String key, final String value) { return (ClientMessageImpl) super.putStringProperty(key, value); } @Override public ClientMessageImpl writeBodyBufferBytes(byte[] bytes) { getBodyBuffer().writeBytes(bytes); return this; } @Override public ClientMessageImpl writeBodyBufferString(String string) { getBodyBuffer().writeString(string); return this; } private final class DecodingContext implements LargeBodyEncoder { private DecodingContext() { } @Override public void open() { getBodyBuffer().readerIndex(0); } @Override public void close() { } @Override public long getLargeBodySize() { if (isLargeMessage()) { return getBodyBuffer().writerIndex(); } else { return getBodyBuffer().writerIndex() - BODY_OFFSET; } } @Override public int encode(final ByteBuffer bufferRead) throws ActiveMQException { ActiveMQBuffer buffer1 = ActiveMQBuffers.wrappedBuffer(bufferRead); return encode(buffer1, bufferRead.capacity()); } @Override public int encode(final ActiveMQBuffer bufferOut, final int size) { byte[] bytes = new byte[size]; buffer.readBytes(bytes); bufferOut.writeBytes(bytes, 0, size); return size; } } @Override public Message copy() { return new ClientMessageImpl(this); } }