Skip to content

Commit

Permalink
Merging message body fix, hostname verification fix and bug fixes fro…
Browse files Browse the repository at this point in the history
…m master branch (Azure#315)

* Test improvements (Azure#309)

* Adding a large message test.
Adding duplicate tests for partitioned entities.
Minor tweaks to make message handler tests more reliable.

* Invalid merge.

* Removed merge conflict files

* Some test fixes.

* Adding ARM deployment template for CI (Azure#218)

build/azuredeploy.json

* Test reliability fixes.
And RequestResponseLimitTest is modified to drastically reduce its runtime.

* More test reliability fixes.

* More tweaks.

# Conflicts:
#	azure-servicebus/src/test/java/com/microsoft/azure/servicebus/ClientValidationTests.java
#	azure-servicebus/src/test/java/com/microsoft/azure/servicebus/primitives/ConnectionStringBuilderTests.java

* Adding retry to RequestResponse link when idle connection is closed. (Azure#305)

* Adding retry to RequestResponse link when idle connection is closed. Otherwise CBS token sending will fail if a SEND request comes in right at the time of connnection closing.

* Minor tweaks to fix 15 minute timeout bug.

* Another fix to handle connection while the links are being opened.

* Another fix to retry sending SAS token if it times out. There are cases when client sending SAS token and server closing the connection happen at the same time and response never arrives.

* More fixes to request-response link to retry on connection close.

* A test fix.

# Conflicts:
#	azure-servicebus/src/main/java/com/microsoft/azure/servicebus/amqp/AmqpErrorCode.java
#	azure-servicebus/src/main/java/com/microsoft/azure/servicebus/primitives/CoreMessageReceiver.java
#	azure-servicebus/src/main/java/com/microsoft/azure/servicebus/primitives/CoreMessageSender.java
#	azure-servicebus/src/main/java/com/microsoft/azure/servicebus/primitives/RequestResponseLink.java

* Adding support for multiple message body types. (Azure#296)

* Adding support for multiple message body types.
Deprecated getBody and setBody methods.

* Changes to MessageBody class API to support AMQP spec of multiple data sections or sequence sections in a message.

* Adding a minor null check.

* Change to handle Messages constructed with string body as binary messages to preserve backward compatibility.

* Adding message body tests.

# Conflicts:
#	azure-servicebus/src/main/java/com/microsoft/azure/servicebus/Message.java
#	azure-servicebus/src/test/java/com/microsoft/azure/servicebus/SendReceiveTests.java
#	azure-servicebus/src/test/java/com/microsoft/azure/servicebus/SessionTests.java

* Merging the fix for man-in-the-middle vulnerability from master branch.
  • Loading branch information
yvgopal authored Dec 20, 2018
1 parent 0da3bec commit 2edad13
Show file tree
Hide file tree
Showing 39 changed files with 1,320 additions and 361 deletions.
11 changes: 5 additions & 6 deletions azure-servicebus/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20</version>
<configuration>
<forkCount>0</forkCount> <!-- Speeds up test execution using multiple JVMs. Set it to 0 if you want to run test sequentially in the build vm itself -->
<reuseForks>true</reuseForks>
</configuration>
</plugin>
</plugins>
</build>
Expand All @@ -51,17 +55,12 @@
<artifactId>proton-j</artifactId>
<version>${proton-j-version}</version>
</dependency>
<dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>qpid-proton-j-extensions</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.53</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>adal4j</artifactId>
<version>1.3.0</version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public interface IMessage {
* Gets the content type of this message.
*
* Optionally describes the payload of the message, with a descriptor following the format of
* RFC2045, Section 5, for example "application/json".
* RFC2045, Section 5, for example "application/json". Note that content type is not same as message body type.
*
* @return content type of this message
*/
Expand Down Expand Up @@ -213,17 +213,38 @@ public interface IMessage {
*
* @return body of this message
* @see <a href="https://docs.microsoft.com/azure/service-bus-messaging/service-bus-messages-payloads">Messages, payloads, and serialization</a>
* @deprecated Message body need not just a byte array. Replaced by {@link #getMessageBody()}
*/
@Deprecated
public byte[] getBody();

/**
* Sets the body of this message as a byte array.
*
* @param body body of this message
* @see #getBody()
* @deprecated Message body need not just a byte array. Replaced by {@link #setMessageBody(MessageBody)}
*/
@Deprecated
public void setBody(byte[] body);

/**
* Gets the body of this message. Client applications should extract message content based on body type.
*
* @return body of this message
* @see <a href="https://docs.microsoft.com/azure/service-bus-messaging/service-bus-messages-payloads">Messages, payloads, and serialization</a>
*/
public MessageBody getMessageBody();

/**
* Sets the body of this message.
*
* @param body body of this message
* @see #getMessageBody()
*/
public void setMessageBody(MessageBody body);


/**
* Gets the map of user application properties of this message. Client
* applications can set user properties (headers) on the message using this map.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ interface IMessageAndSessionPump {
* IMessageHandler methods are executed on the passed executor service.
*
* @param handler The {@link IMessageHandler} instance
* @param executorService ExecutorService which is used to execute {@link IMessageHandler} methods. If there are
* @param executorService ExecutorService which is used to execute {@link IMessageHandler} methods.
* @throws InterruptedException if the current thread was interrupted while waiting
* @throws ServiceBusException if register failed
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,20 @@
import java.util.Map;
import java.util.UUID;


/**
*
*
*/
final public class Message implements Serializable, IMessage {
private static final long serialVersionUID = 7849508139219590863L;

private static final Charset DEFAULT_CHAR_SET = Charset.forName("UTF-8");

private static final String DEFAULT_CONTENT_TYPE = null;

private static final byte[] DEFAULT_CONTENT = new byte[0];
private static final MessageBody DEFAULT_CONTENT = Utils.fromBinay(new byte[0]);

private long deliveryCount;

private String messageId;

private Duration timeToLive;

private byte[] content;
private MessageBody messageBody;

private String contentType;

Expand Down Expand Up @@ -67,40 +60,103 @@ final public class Message implements Serializable, IMessage {

private byte[] deliveryTag;

/**
* Creates an empty message with an empty byte array as body.
*/
public Message()
{
this(DEFAULT_CONTENT);
}

/**
* Creates a message from a string. For backward compatibility reasons, the string is converted to a byte array and message body type is set to binary.
* @param content content of the message.
*/
public Message(String content)
{
this(content.getBytes(DEFAULT_CHAR_SET));
}

/**
* Creates a message from a byte array. Message body type is set to binary.
* @param content content of the message
*/
public Message(byte[] content)
{
this(content, DEFAULT_CONTENT_TYPE);
this(Utils.fromBinay(content));
}

/**
* Creates a message from message body.
* @param body message body
*/
public Message(MessageBody body)
{
this(body, DEFAULT_CONTENT_TYPE);
}

/**
* Creates a message from a string. For backward compatibility reasons, the string is converted to a byte array and message body type is set to binary.
* @param content content of the message
* @param contentType content type of the message
*/
public Message(String content, String contentType)
{
this(content.getBytes(DEFAULT_CHAR_SET), contentType);
}

/**
* Creates a message from a byte array. Message body type is set to binary.
* @param content content of the message
* @param contentType content type of the message
*/
public Message(byte[] content, String contentType)
{
this(UUID.randomUUID().toString(), content, contentType);
this(Utils.fromBinay(content), contentType);
}

/**
* Creates a message from message body.
* @param body message body
* @param contentType content type of the message
*/
public Message(MessageBody body, String contentType)
{
this(UUID.randomUUID().toString(), body, contentType);
}

/**
* Creates a message from a string. For backward compatibility reasons, the string is converted to a byte array and message body type is set to binary.
* @param messageId id of the message
* @param content content of the message
* @param contentType content type of the message
*/
public Message(String messageId, String content, String contentType)
{
this(messageId, content.getBytes(DEFAULT_CHAR_SET), contentType);
}


/**
* Creates a message from a byte array. Message body type is set to binary.
* @param messageId id of the message
* @param content content of the message
* @param contentType content type of the message
*/
public Message(String messageId, byte[] content, String contentType)
{
this(messageId, Utils.fromBinay(content), contentType);
}

/**
* Creates a message from message body.
* @param messageId id of the message
* @param body message body
* @param contentType content type of the message
*/
public Message(String messageId, MessageBody body, String contentType)
{
this.messageId = messageId;
this.content = content;
this.messageBody = body;
this.contentType = contentType;
this.properties = new HashMap<>();
}
Expand Down Expand Up @@ -186,16 +242,6 @@ public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}

@Override
public byte[] getBody() {
return this.content;
}

@Override
public void setBody(byte[] content) {
this.content = content;
}

@Override
public Map<String, Object> getProperties() {
return this.properties;
Expand Down Expand Up @@ -325,4 +371,30 @@ void setDeliveryTag(byte[] deliveryTag)
{
this.deliveryTag = deliveryTag;
}

@Override
@Deprecated
public byte[] getBody()
{
return Utils.getDataFromMessageBody(this.messageBody);
}

@Override
@Deprecated
public void setBody(byte[] body)
{
this.messageBody = Utils.fromBinay(body);
}

@Override
public MessageBody getMessageBody()
{
return this.messageBody;
}

@Override
public void setMessageBody(MessageBody body)
{
this.messageBody = body;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package com.microsoft.azure.servicebus;

import java.util.List;

/**
* This class encapsulates the body of a message. Body types map to AMQP message body types.
* It has getters and setters for multiple body types.
* Client should test for body type before calling corresponding get method.
* Get methods not corresponding to the type of the body return null.
*/
public class MessageBody {
private MessageBodyType bodyType;
private Object valueData;
private List<List<Object>> sequenceData;
private List<byte[]> binaryData;

private MessageBody() {}

/**
* Creates message body of AMQPValue type.
* @param value AMQPValue content of the message. It must be of a type supported by AMQP.
* @return MessageBody instance wrapping around the value data.
*/
public static MessageBody fromValueData(Object value)
{
if(value == null)
{
throw new IllegalArgumentException("Value data is null.");
}

MessageBody body = new MessageBody();
body.bodyType = MessageBodyType.VALUE;
body.valueData = value;
body.sequenceData = null;
body.binaryData = null;
return body;
}

/**
* Creates a message body from a list of AMQPSequence sections.Each AMQPSequence section is in turn a list of objects.
* Please note that this version of the SDK supports only one AMQPSequence section in a message. It means only a list of exactly one sequence in it is accepted as message body.
* @param sequenceData a list of AMQPSequence sections. Each AMQPSequence section is in turn a list of objects. Every object in each list must of a type supported by AMQP.
* @return MessageBody instance wrapping around the sequence data.
*/
public static MessageBody fromSequenceData(List<List<Object>> sequenceData)
{
if(sequenceData == null || sequenceData.size() == 0 || sequenceData.size() > 1)
{
throw new IllegalArgumentException("Sequence data is null or has more than one collection in it.");
}

MessageBody body = new MessageBody();
body.bodyType = MessageBodyType.SEQUENCE;
body.valueData = null;
body.sequenceData = sequenceData;
body.binaryData = null;
return body;
}

/**
* Creates a message body from a list of Data sections.Each Data section is a byte array.
* Please note that this version of the SDK supports only one Data section in a message. It means only a list of exactly one byte array in it is accepted as message body.
* @param binaryData a list of byte arrays.
* @return MessageBody instance wrapping around the binary data.
*/
public static MessageBody fromBinaryData(List<byte[]> binaryData)
{
if(binaryData == null || binaryData.size() == 0 || binaryData.size() > 1)
{
throw new IllegalArgumentException("Binary data is null or has more than one byte array in it.");
}

MessageBody body = new MessageBody();
body.bodyType = MessageBodyType.BINARY;
body.valueData = null;
body.sequenceData = null;
body.binaryData = binaryData;
return body;
}

/**
* Returns the content of message body.
* @return value of message body only if the MessageBody is of Value type. Returns null otherwise.
*/
public Object getValueData() {
return valueData;
}

/**
* Returns the content of message body.
* @return a list of AMQPSequence sections only if the MessageBody is of Sequence type. Returns null otherwise. Each AMQPSequence section is in turn a list of objects.
*/
public List<List<Object>> getSequenceData() {
return sequenceData;
}

/**
* Returns the content of message body.
* @return message body as list of byte arrays only if the MessageBody is of Binary type. Returns null otherwise.
*/
public List<byte[]> getBinaryData() {
return binaryData;
}

/**
* Return the type of content in this message body.
* @return type of message content
*/
public MessageBodyType getBodyType() {
return bodyType;
}
}
Loading

0 comments on commit 2edad13

Please sign in to comment.