All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.amqp.core.MessageProperties Maven / Gradle / Ivy

There is a newer version: 3.1.6
Show newest version
/*
 * Copyright 2002-2022 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.amqp.core;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Message Properties for an AMQP message.
 *
 * @author Mark Fisher
 * @author Mark Pollack
 * @author Gary Russell
 * @author Dmitry Chernyshov
 * @author Artem Bilan
 * @author Csaba Soti
 */
public class MessageProperties implements Serializable {

	private static final int INT_MASK = 32;

	private static final long serialVersionUID = 1619000546531112290L;

	public static final String CONTENT_TYPE_BYTES = "application/octet-stream";

	public static final String CONTENT_TYPE_TEXT_PLAIN = "text/plain";

	public static final String CONTENT_TYPE_SERIALIZED_OBJECT = "application/x-java-serialized-object";

	public static final String CONTENT_TYPE_JSON = "application/json";

	public static final String CONTENT_TYPE_JSON_ALT = "text/x-json";

	public static final String CONTENT_TYPE_XML = "application/xml";

	public static final String SPRING_BATCH_FORMAT = "springBatchFormat";

	public static final String BATCH_FORMAT_LENGTH_HEADER4 = "lengthHeader4";

	public static final String SPRING_AUTO_DECOMPRESS = "springAutoDecompress";

	public static final String X_DELAY = "x-delay";

	public static final String DEFAULT_CONTENT_TYPE = CONTENT_TYPE_BYTES;

	public static final MessageDeliveryMode DEFAULT_DELIVERY_MODE = MessageDeliveryMode.PERSISTENT;

	public static final Integer DEFAULT_PRIORITY = 0;

	private final Map headers = new HashMap<>();

	private Date timestamp;

	private String messageId;

	private String userId;

	private String appId;

	private String clusterId;

	private String type;

	private String correlationId;

	private String replyTo;

	private String contentType = DEFAULT_CONTENT_TYPE;

	private String contentEncoding;

	private long contentLength;

	private boolean contentLengthSet;

	private MessageDeliveryMode deliveryMode = DEFAULT_DELIVERY_MODE;

	private String expiration;

	private Integer priority = DEFAULT_PRIORITY;

	private Boolean redelivered;

	private String receivedExchange;

	private String receivedRoutingKey;

	private String receivedUserId;

	private long deliveryTag;

	private boolean deliveryTagSet;

	private Integer messageCount;

	// Not included in hashCode()

	private String consumerTag;

	private String consumerQueue;

	private Integer receivedDelay;

	private MessageDeliveryMode receivedDeliveryMode;

	private boolean finalRetryForMessageWithNoId;

	private long publishSequenceNumber;

	private boolean lastInBatch;

	private boolean projectionUsed;

	private transient Type inferredArgumentType;

	private transient Method targetMethod;

	private transient Object targetBean;

	public void setHeader(String key, Object value) {
		this.headers.put(key, value);
	}

	/**
	 * Set headers.
	 * @param headers the headers.
	 * @since 2.4.7
	 */
	public void setHeaders(Map headers) {
		this.headers.putAll(headers);
	}

	/**
	 * Typed getter for a header.
	 * @param headerName the header name.
	 * @param  the type.
	 * @return the header value
	 * @since 2.2
	 */
	@SuppressWarnings("unchecked")
	public  T getHeader(String headerName) {
		return (T) this.headers.get(headerName);
	}

	public Map getHeaders() {
		return this.headers;
	}

	public void setTimestamp(Date timestamp) {
		this.timestamp = timestamp; //NOSONAR
	}

	// NOTE qpid java timestamp is long, presumably can convert to Date.
	public Date getTimestamp() {
		return this.timestamp; //NOSONAR
	}

	// NOTE Not forward compatible with qpid 1.0 .NET
	// qpid 0.8 .NET/Java: is a string
	// qpid 1.0 .NET: MessageId property on class MessageProperties and is UUID
	// There is an 'ID' stored IMessage class and is an int.
	public void setMessageId(String messageId) {
		this.messageId = messageId;
	}

	public String getMessageId() {
		return this.messageId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	// NOTE Note forward compatible with qpid 1.0 .NET
	// qpid 0.8 .NET/java: is a string
	// qpid 1.0 .NET: getUserId is byte[]
	public String getUserId() {
		return this.userId;
	}

	/**
	 * Return the user id from an incoming message.
	 * @return the user id.
	 * @since 1.6
	 */
	public String getReceivedUserId() {
		return this.receivedUserId;
	}

	public void setReceivedUserId(String receivedUserId) {
		this.receivedUserId = receivedUserId;
	}

	public void setAppId(String appId) {
		this.appId = appId;
	}

	public String getAppId() {
		return this.appId;
	}

	// NOTE not forward compatible with qpid 1.0 .NET
	// qpid 0.8 .NET/Java: is a string
	// qpid 1.0 .NET: is not present
	public void setClusterId(String clusterId) {
		this.clusterId = clusterId;
	}

	public String getClusterId() {
		return this.clusterId;
	}

	public void setType(String type) {
		this.type = type;
	}

	// NOTE structureType is int in Qpid
	public String getType() {
		return this.type;
	}

	/**
	 * Set the correlation id.
	 * @param correlationId the id.
	 */
	public void setCorrelationId(String correlationId) {
		this.correlationId = correlationId;
	}

	/**
	 * Get the correlation id.
	 * @return the id.
	 */
	public String getCorrelationId() {
		return this.correlationId;
	}

	public void setReplyTo(String replyTo) {
		this.replyTo = replyTo;
	}

	public String getReplyTo() {
		return this.replyTo;
	}

	public void setReplyToAddress(Address replyTo) {
		this.replyTo = (replyTo != null) ? replyTo.toString() : null;
	}

	public Address getReplyToAddress() {
		return (this.replyTo != null) ? new Address(this.replyTo) : null;
	}

	public void setContentType(String contentType) {
		this.contentType = contentType;
	}

	public String getContentType() {
		return this.contentType;
	}

	public void setContentEncoding(String contentEncoding) {
		this.contentEncoding = contentEncoding;
	}

	public String getContentEncoding() {
		return this.contentEncoding;
	}

	public void setContentLength(long contentLength) {
		this.contentLength = contentLength;
		this.contentLengthSet = true;
	}

	public long getContentLength() {
		return this.contentLength;
	}

	protected final boolean isContentLengthSet() {
		return this.contentLengthSet;
	}

	public void setDeliveryMode(MessageDeliveryMode deliveryMode) {
		this.deliveryMode = deliveryMode;
	}

	public MessageDeliveryMode getDeliveryMode() {
		return this.deliveryMode;
	}

	public MessageDeliveryMode getReceivedDeliveryMode() {
		return this.receivedDeliveryMode;
	}

	public void setReceivedDeliveryMode(MessageDeliveryMode receivedDeliveryMode) {
		this.receivedDeliveryMode = receivedDeliveryMode;
	}

	/**
	 * Set the message expiration. This is a String property per the AMQP 0.9.1 spec. For
	 * RabbitMQ, this is a String representation of the message time to live in
	 * milliseconds.
	 * @param expiration the expiration.
	 */
	public void setExpiration(String expiration) {
		this.expiration = expiration;
	}

	/**
	 * Get the message expiration. This is a String property per the AMQP 0.9.1 spec. For
	 * RabbitMQ, this is a String representation of the message time to live in
	 * milliseconds.
	 * @return the expiration.
	 */
	public String getExpiration() {
		return this.expiration;
	}

	public void setPriority(Integer priority) {
		this.priority = priority;
	}

	public Integer getPriority() {
		return this.priority;
	}

	public void setReceivedExchange(String receivedExchange) {
		this.receivedExchange = receivedExchange;
	}

	public String getReceivedExchange() {
		return this.receivedExchange;
	}

	public void setReceivedRoutingKey(String receivedRoutingKey) {
		this.receivedRoutingKey = receivedRoutingKey;
	}

	public String getReceivedRoutingKey() {
		return this.receivedRoutingKey;
	}

	/**
	 * When a delayed message exchange is used the x-delay header on a
	 * received message contains the delay.
	 * @return the received delay.
	 * @since 1.6
	 * @see #getDelay()
	 */
	public Integer getReceivedDelay() {
		return this.receivedDelay;
	}

	/**
	 * When a delayed message exchange is used the x-delay header on a
	 * received message contains the delay.
	 * @param receivedDelay the received delay.
	 * @since 1.6
	 */
	public void setReceivedDelay(Integer receivedDelay) {
		this.receivedDelay = receivedDelay;
	}

	public void setRedelivered(Boolean redelivered) {
		this.redelivered = redelivered;
	}

	public Boolean isRedelivered() {
		return this.redelivered;
	}

	/*
	 * Additional accessor because is* is not standard for type Boolean
	 */
	public Boolean getRedelivered() {
		return this.redelivered;
	}

	public void setDeliveryTag(long deliveryTag) {
		this.deliveryTag = deliveryTag;
		this.deliveryTagSet = true;
	}

	public long getDeliveryTag() {
		return this.deliveryTag;
	}

	protected final boolean isDeliveryTagSet() {
		return this.deliveryTagSet;
	}

	/**
	 * Set the message count.
	 * @param messageCount the count
	 * @see #getMessageCount()
	 */
	public void setMessageCount(Integer messageCount) {
		this.messageCount = messageCount;
	}

	/**
	 * Return the server's most recent estimate of the number of messages remaining on the queue.
	 * Only applies to messages retrieved via {@code basicGet}.
	 * @return the count.
	 */
	public Integer getMessageCount() {
		return this.messageCount;
	}

	public String getConsumerTag() {
		return this.consumerTag;
	}

	public void setConsumerTag(String consumerTag) {
		this.consumerTag = consumerTag;
	}

	public String getConsumerQueue() {
		return this.consumerQueue;
	}

	public void setConsumerQueue(String consumerQueue) {
		this.consumerQueue = consumerQueue;
	}

	/**
	 * The x-delay header (outbound).
	 * @return the delay.
	 * @since 1.6
	 * @see #getReceivedDelay()
	 */
	public Integer getDelay() {
		Object delay = this.headers.get(X_DELAY);
		if (delay instanceof Integer) {
			return (Integer) delay;
		}
		else {
			return null;
		}
	}

	/**
	 * Set the x-delay header.
	 * @param delay the delay.
	 * @since 1.6
	 */
	public void setDelay(Integer delay) {
		if (delay == null || delay < 0) {
			this.headers.remove(X_DELAY);
		}
		else {
			this.headers.put(X_DELAY, delay);
		}
	}

	public boolean isFinalRetryForMessageWithNoId() {
		return this.finalRetryForMessageWithNoId;
	}

	public void setFinalRetryForMessageWithNoId(boolean finalRetryForMessageWithNoId) {
		this.finalRetryForMessageWithNoId = finalRetryForMessageWithNoId;
	}

	/**
	 * Return the publish sequence number if publisher confirms are enabled; set by the template.
	 * @return the sequence number.
	 * @since 2.1
	 */
	public long getPublishSequenceNumber() {
		return this.publishSequenceNumber;
	}

	/**
	 * Set the publish sequence number, if publisher confirms are enabled; set by the template.
	 * @param publishSequenceNumber the sequence number.
	 * @since 2.1
	 */
	public void setPublishSequenceNumber(long publishSequenceNumber) {
		this.publishSequenceNumber = publishSequenceNumber;
	}

	/**
	 * The inferred target argument type when using a method-level
	 * {@code @RabbitListener}.
	 * @return the type.
	 * @since 1.6
	 */
	public Type getInferredArgumentType() {
		return this.inferredArgumentType;
	}

	/**
	 * Set the inferred target argument type when using a method-level
	 * {@code @RabbitListener}.
	 * @param inferredArgumentType the type.
	 * @since 1.6
	 */
	public void setInferredArgumentType(Type inferredArgumentType) {
		this.inferredArgumentType = inferredArgumentType;
	}

	/**
	 * The target method when using a {@code @RabbitListener}.
	 * @return the method.
	 * @since 1.6
	 */
	public Method getTargetMethod() {
		return this.targetMethod;
	}

	/**
	 * Set the target method when using a {@code @RabbitListener}.
	 * @param targetMethod the target method.
	 * @since 1.6
	 */
	public void setTargetMethod(Method targetMethod) {
		this.targetMethod = targetMethod;
	}

	/**
	 * The target bean when using {@code @RabbitListener}.
	 * @return the bean.
	 * @since 1.6
	 */
	public Object getTargetBean() {
		return this.targetBean;
	}

	/**
	 * Set the target bean when using {@code @RabbitListener}.
	 * @param targetBean the bean.
	 * @since 1.6
	 */
	public void setTargetBean(Object targetBean) {
		this.targetBean = targetBean;
	}

	/**
	 * When true; the message having these properties is the last message from a batch.
	 * @return true for the last message.
	 * @since 2.2
	 */
	public boolean isLastInBatch() {
		return this.lastInBatch;
	}

	/**
	 * Set to true to indicate these properties are for the last message in a batch.
	 * @param lastInBatch true for the last.
	 * @since 2.2
	 */
	public void setLastInBatch(boolean lastInBatch) {
		this.lastInBatch = lastInBatch;
	}

	/**
	 * Get an internal flag used to communicate that conversion used projection; always
	 * false at the application level.
	 * @return true if projection was used.
	 * @since 2.2.20
	 */
	public boolean isProjectionUsed() {
		return this.projectionUsed;
	}

	/**
	 * Set an internal flag used to communicate that conversion used projection; always false
	 * at the application level.
	 * @param projectionUsed true for projection.
	 * @since 2.2.20
	 */
	public void setProjectionUsed(boolean projectionUsed) {
		this.projectionUsed = projectionUsed;
	}

	/**
	 * Return the x-death header.
	 * @return the header.
	 */
	@SuppressWarnings("unchecked")
	public List> getXDeathHeader() {
		try {
			return (List>) this.headers.get("x-death");
		}
		catch (@SuppressWarnings("unused") Exception e) {
			return null;
		}
	}

	@Override // NOSONAR complexity
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((this.appId == null) ? 0 : this.appId.hashCode());
		result = prime * result + ((this.clusterId == null) ? 0 : this.clusterId.hashCode());
		result = prime * result + ((this.contentEncoding == null) ? 0 : this.contentEncoding.hashCode());
		result = prime * result + (int) (this.contentLength ^ (this.contentLength >>> INT_MASK));
		result = prime * result + ((this.contentType == null) ? 0 : this.contentType.hashCode());
		result = prime * result + ((this.correlationId == null) ? 0 : this.correlationId.hashCode());
		result = prime * result + ((this.deliveryMode == null) ? 0 : this.deliveryMode.hashCode());
		result = prime * result + (int) (this.deliveryTag ^ (this.deliveryTag >>> INT_MASK));
		result = prime * result + ((this.expiration == null) ? 0 : this.expiration.hashCode());
		result = prime * result + this.headers.hashCode();
		result = prime * result + ((this.messageCount == null) ? 0 : this.messageCount.hashCode());
		result = prime * result + ((this.messageId == null) ? 0 : this.messageId.hashCode());
		result = prime * result + ((this.priority == null) ? 0 : this.priority.hashCode());
		result = prime * result + ((this.receivedExchange == null) ? 0 : this.receivedExchange.hashCode());
		result = prime * result + ((this.receivedRoutingKey == null) ? 0 : this.receivedRoutingKey.hashCode());
		result = prime * result + ((this.redelivered == null) ? 0 : this.redelivered.hashCode());
		result = prime * result + ((this.replyTo == null) ? 0 : this.replyTo.hashCode());
		result = prime * result + ((this.timestamp == null) ? 0 : this.timestamp.hashCode());
		result = prime * result + ((this.type == null) ? 0 : this.type.hashCode());
		result = prime * result + ((this.userId == null) ? 0 : this.userId.hashCode());
		return result;
	}

	@Override // NOSONAR complexity
	public boolean equals(Object obj) { // NOSONAR line count
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		MessageProperties other = (MessageProperties) obj;
		if (this.appId == null) {
			if (other.appId != null) {
				return false;
			}
		}
		else if (!this.appId.equals(other.appId)) {
			return false;
		}
		if (this.clusterId == null) {
			if (other.clusterId != null) {
				return false;
			}
		}
		else if (!this.clusterId.equals(other.clusterId)) {
			return false;
		}
		if (this.contentEncoding == null) {
			if (other.contentEncoding != null) {
				return false;
			}
		}
		else if (!this.contentEncoding.equals(other.contentEncoding)) {
			return false;
		}
		if (this.contentLength != other.contentLength) {
			return false;
		}
		if (this.contentType == null) {
			if (other.contentType != null) {
				return false;
			}
		}
		else if (!this.contentType.equals(other.contentType)) {
			return false;
		}

		if (this.correlationId == null) {
			if (other.correlationId != null) {
				return false;
			}
		}
		else if (!this.correlationId.equals(other.correlationId)) {
			return false;
		}

		if (this.deliveryMode != other.deliveryMode) {
			return false;
		}
		if (this.deliveryTag != other.deliveryTag) {
			return false;
		}
		if (this.expiration == null) {
			if (other.expiration != null) {
				return false;
			}
		}
		else if (!this.expiration.equals(other.expiration)) {
			return false;
		}
		if (!this.headers.equals(other.headers)) {
			return false;
		}
		if (this.messageCount == null) {
			if (other.messageCount != null) {
				return false;
			}
		}
		else if (!this.messageCount.equals(other.messageCount)) {
			return false;
		}
		if (this.messageId == null) {
			if (other.messageId != null) {
				return false;
			}
		}
		else if (!this.messageId.equals(other.messageId)) {
			return false;
		}
		if (this.priority == null) {
			if (other.priority != null) {
				return false;
			}
		}
		else if (!this.priority.equals(other.priority)) {
			return false;
		}
		if (this.receivedExchange == null) {
			if (other.receivedExchange != null) {
				return false;
			}
		}
		else if (!this.receivedExchange.equals(other.receivedExchange)) {
			return false;
		}
		if (this.receivedRoutingKey == null) {
			if (other.receivedRoutingKey != null) {
				return false;
			}
		}
		else if (!this.receivedRoutingKey.equals(other.receivedRoutingKey)) {
			return false;
		}
		if (this.redelivered == null) {
			if (other.redelivered != null) {
				return false;
			}
		}
		else if (!this.redelivered.equals(other.redelivered)) {
			return false;
		}
		if (this.replyTo == null) {
			if (other.replyTo != null) {
				return false;
			}
		}
		else if (!this.replyTo.equals(other.replyTo)) {
			return false;
		}
		if (this.timestamp == null) {
			if (other.timestamp != null) {
				return false;
			}
		}
		else if (!this.timestamp.equals(other.timestamp)) {
			return false;
		}
		if (this.type == null) {
			if (other.type != null) {
				return false;
			}
		}
		else if (!this.type.equals(other.type)) {
			return false;
		}
		if (this.userId == null) {
			if (other.userId != null) {
				return false;
			}
		}
		else if (!this.userId.equals(other.userId)) {
			return false;
		}
		return true;
	}

	@Override // NOSONAR complexity
	public String toString() {
		return "MessageProperties [headers=" + this.headers
				+ (this.timestamp == null ? "" : ", timestamp=" + this.timestamp)
				+ (this.messageId == null ? "" : ", messageId=" + this.messageId)
				+ (this.userId == null ? "" : ", userId=" + this.userId)
				+ (this.receivedUserId == null ? "" : ", receivedUserId=" + this.receivedUserId)
				+ (this.appId == null ? "" : ", appId=" + this.appId)
				+ (this.clusterId == null ? "" : ", clusterId=" + this.clusterId)
				+ (this.type == null ? "" : ", type=" + this.type)
				+ (this.correlationId == null ? "" : ", correlationId=" + this.correlationId)
				+ (this.replyTo == null ? "" : ", replyTo=" + this.replyTo)
				+ (this.contentType == null ? "" : ", contentType=" + this.contentType)
				+ (this.contentEncoding == null ? "" : ", contentEncoding=" + this.contentEncoding)
				+ ", contentLength=" + this.contentLength
				+ (this.deliveryMode == null ? "" : ", deliveryMode=" + this.deliveryMode)
				+ (this.receivedDeliveryMode == null ? "" : ", receivedDeliveryMode=" + this.receivedDeliveryMode)
				+ (this.expiration == null ? "" : ", expiration=" + this.expiration)
				+ (this.priority == null ? "" : ", priority=" + this.priority)
				+ (this.redelivered == null ? "" : ", redelivered=" + this.redelivered)
				+ (this.receivedExchange == null ? "" : ", receivedExchange=" + this.receivedExchange)
				+ (this.receivedRoutingKey == null ? "" : ", receivedRoutingKey=" + this.receivedRoutingKey)
				+ (this.receivedDelay == null ? "" : ", receivedDelay=" + this.receivedDelay)
				+ ", deliveryTag=" + this.deliveryTag
				+ (this.messageCount == null ? "" : ", messageCount=" + this.messageCount)
				+ (this.consumerTag == null ? "" : ", consumerTag=" + this.consumerTag)
				+ (this.consumerQueue == null ? "" : ", consumerQueue=" + this.consumerQueue)
				+ "]";
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy