Repository: qpid-jms Updated Branches: refs/heads/master 12cb11ef5 -> d661352c9
more unit tests for AmqpJmsObjectMessageFacade Project: http://git-wip-us.apache.org/repos/asf/qpid-jms/repo Commit: http://git-wip-us.apache.org/repos/asf/qpid-jms/commit/d661352c Tree: http://git-wip-us.apache.org/repos/asf/qpid-jms/tree/d661352c Diff: http://git-wip-us.apache.org/repos/asf/qpid-jms/diff/d661352c Branch: refs/heads/master Commit: d661352c90f391db43564851b83368c2622ca536 Parents: 12cb11e Author: Robert Gemmell <rob...@apache.org> Authored: Fri Oct 10 15:02:46 2014 +0100 Committer: Robert Gemmell <rob...@apache.org> Committed: Fri Oct 10 15:22:40 2014 +0100 ---------------------------------------------------------------------- .../message/AmqpJmsObjectMessageFacade.java | 2 +- .../amqp/message/AmqpTypedObjectDelegate.java | 6 +- .../ObjectMessageIntegrationTest.java | 2 + .../message/AmqpJmsMessageTypesTestCase.java | 4 +- .../message/AmqpJmsObjectMessageFacadeTest.java | 180 ++++++++++++++++++- 5 files changed, 182 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/d661352c/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsObjectMessageFacade.java ---------------------------------------------------------------------- diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsObjectMessageFacade.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsObjectMessageFacade.java index 4c18f7e..205453b 100644 --- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsObjectMessageFacade.java +++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsObjectMessageFacade.java @@ -84,7 +84,7 @@ public class AmqpJmsObjectMessageFacade extends AmqpJmsMessageFacade implements } public boolean isAmqpTypedEncoding() { - return this.delegate instanceof AmqpTypedObjectDelegate; + return delegate.isAmqpTypeEncoded(); } @Override http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/d661352c/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpTypedObjectDelegate.java ---------------------------------------------------------------------- diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpTypedObjectDelegate.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpTypedObjectDelegate.java index 36cdfd7..860e5d3 100644 --- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpTypedObjectDelegate.java +++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpTypedObjectDelegate.java @@ -93,17 +93,17 @@ public class AmqpTypedObjectDelegate implements AmqpObjectTypeDelegate { // TODO: Data and AmqpSequence? throw new IllegalArgumentException("Encoding this object type with the AMQP type system is not supported: " + value.getClass().getName()); } - - // TODO: ensure content type is not set (assuming we aren't using data sections)? } @Override public void onSend() { + message.setContentType(null); } private boolean isSupportedAmqpValueObjectType(Serializable serializable) { // TODO: augment supported types to encode as an AmqpValue? - return serializable instanceof Map<?,?> || + return serializable instanceof String || + serializable instanceof Map<?,?> || serializable instanceof List<?> || serializable.getClass().isArray(); } http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/d661352c/qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/ObjectMessageIntegrationTest.java ---------------------------------------------------------------------- diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/ObjectMessageIntegrationTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/ObjectMessageIntegrationTest.java index 4e0ee9d..65552fe 100644 --- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/ObjectMessageIntegrationTest.java +++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/ObjectMessageIntegrationTest.java @@ -19,6 +19,7 @@ package org.apache.qpid.jms.integration; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -227,6 +228,7 @@ public class ObjectMessageIntegrationTest extends QpidJmsTestCase MessageAnnotationsSectionMatcher msgAnnotationsMatcher = new MessageAnnotationsSectionMatcher(true); msgAnnotationsMatcher.withEntry(Symbol.valueOf(AmqpMessageSupport.JMS_MSG_TYPE), equalTo(AmqpMessageSupport.JMS_OBJECT_MESSAGE)); MessagePropertiesSectionMatcher propertiesMatcher = new MessagePropertiesSectionMatcher(true); + propertiesMatcher.withContentType(nullValue());//check there is no content-type TransferPayloadCompositeMatcher messageMatcher = new TransferPayloadCompositeMatcher(); messageMatcher.setHeadersMatcher(headersMatcher); messageMatcher.setMessageAnnotationsMatcher(msgAnnotationsMatcher); http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/d661352c/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsMessageTypesTestCase.java ---------------------------------------------------------------------- diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsMessageTypesTestCase.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsMessageTypesTestCase.java index 8ad585f..6324b75 100644 --- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsMessageTypesTestCase.java +++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsMessageTypesTestCase.java @@ -78,8 +78,8 @@ public class AmqpJmsMessageTypesTestCase extends QpidJmsTestCase { return new AmqpJmsStreamMessageFacade(amqpConsumer, message); } - protected AmqpJmsObjectMessageFacade createNewObjectMessageFacade(boolean javaSerialized) { - return new AmqpJmsObjectMessageFacade(createMockAmqpConnection(), javaSerialized); + protected AmqpJmsObjectMessageFacade createNewObjectMessageFacade(boolean amqpTyped) { + return new AmqpJmsObjectMessageFacade(createMockAmqpConnection(), amqpTyped); } protected AmqpJmsObjectMessageFacade createReceivedObjectMessageFacade(AmqpConsumer amqpConsumer, Message message) { http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/d661352c/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsObjectMessageFacadeTest.java ---------------------------------------------------------------------- diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsObjectMessageFacadeTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsObjectMessageFacadeTest.java index 4b3e422..5a2aa2b 100644 --- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsObjectMessageFacadeTest.java +++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsObjectMessageFacadeTest.java @@ -19,15 +19,28 @@ package org.apache.qpid.jms.provider.amqp.message; import static org.apache.qpid.jms.provider.amqp.message.AmqpMessageSupport.JMS_MSG_TYPE; import static org.apache.qpid.jms.provider.amqp.message.AmqpMessageSupport.JMS_OBJECT_MESSAGE; import static org.apache.qpid.jms.provider.amqp.message.AmqpMessageSupport.getSymbol; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.HashMap; import java.util.Map; +import org.apache.qpid.proton.amqp.Binary; import org.apache.qpid.proton.amqp.Symbol; +import org.apache.qpid.proton.amqp.messaging.AmqpValue; +import org.apache.qpid.proton.amqp.messaging.Data; import org.apache.qpid.proton.amqp.messaging.MessageAnnotations; +import org.apache.qpid.proton.amqp.messaging.Section; import org.apache.qpid.proton.message.Message; import org.junit.Test; @@ -40,7 +53,7 @@ public class AmqpJmsObjectMessageFacadeTest extends AmqpJmsMessageTypesTestCase @Test public void testNewMessageToSendContainsMessageTypeAnnotation() throws Exception { - AmqpJmsObjectMessageFacade amqpObjectMessageFacade = createNewObjectMessageFacade(true); + AmqpJmsObjectMessageFacade amqpObjectMessageFacade = createNewObjectMessageFacade(false); Message protonMessage = amqpObjectMessageFacade.getAmqpMessage(); MessageAnnotations annotations = protonMessage.getMessageAnnotations(); @@ -56,29 +69,184 @@ public class AmqpJmsObjectMessageFacadeTest extends AmqpJmsMessageTypesTestCase @Test public void testNewMessageToSendReturnsNullObject() throws Exception { - doNewMessageToSendReturnsNullObjectTestImpl(true); + doNewMessageToSendReturnsNullObjectTestImpl(false); } @Test public void testNewAmqpTypedMessageToSendReturnsNullObject() throws Exception { - doNewMessageToSendReturnsNullObjectTestImpl(false); + doNewMessageToSendReturnsNullObjectTestImpl(true); } - private void doNewMessageToSendReturnsNullObjectTestImpl(boolean javaSerialized) throws Exception { - AmqpJmsObjectMessageFacade amqpObjectMessageFacade = createNewObjectMessageFacade(javaSerialized); - amqpObjectMessageFacade.clearBody(); + private void doNewMessageToSendReturnsNullObjectTestImpl(boolean amqpTyped) throws Exception { + AmqpJmsObjectMessageFacade amqpObjectMessageFacade = createNewObjectMessageFacade(amqpTyped); assertNull(amqpObjectMessageFacade.getObject()); } // ---------- test for normal message operations -------------------------// + /** + * Test that setting an object on a new message results in the expected + * content in the body section of the underlying message. + */ + @Test + public void testSetObjectOnNewMessage() throws Exception { + String content = "myStringContent"; + + AmqpJmsObjectMessageFacade amqpObjectMessageFacade = createNewObjectMessageFacade(false); + amqpObjectMessageFacade.setObject(content); + + Message protonMessage = amqpObjectMessageFacade.getAmqpMessage(); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(content); + oos.flush(); + oos.close(); + byte[] bytes = baos.toByteArray(); + + // retrieve the bytes from the underlying message, check they match expectation + Section section = protonMessage.getBody(); + assertNotNull(section); + assertEquals(Data.class, section.getClass()); + assertArrayEquals("Underlying message data section did not contain the expected bytes", bytes, ((Data) section).getValue().getArray()); + } + + /** + * Test that setting an object on a new message results in the expected + * content in the body section of the underlying message. + */ + @Test + public void testSetObjectOnNewAmqpTypedMessage() throws Exception { + String content = "myStringContent"; + + AmqpJmsObjectMessageFacade amqpObjectMessageFacade = createNewObjectMessageFacade(true); + amqpObjectMessageFacade.setObject(content); + + Message protonMessage = amqpObjectMessageFacade.getAmqpMessage(); + + // retrieve the body from the underlying message, check it matches expectation + Section section = protonMessage.getBody(); + assertNotNull(section); + assertEquals(AmqpValue.class, section.getClass()); + assertEquals("Underlying message body did not contain the expected content", content, ((AmqpValue) section).getValue()); + } + + /** + * Test that setting a null object on a message results in the underlying + * body section being cleared, ensuring getObject returns null. + */ + @Test + public void testSetObjectWithNullClearsExistingBodySection() throws Exception { + Message protonMessage = Message.Factory.create(); + protonMessage.setContentType(AmqpMessageSupport.SERIALIZED_JAVA_OBJECT_CONTENT_TYPE); + protonMessage.setBody(new Data(new Binary(new byte[0]))); + + AmqpJmsObjectMessageFacade amqpObjectMessageFacade = createReceivedObjectMessageFacade(createMockAmqpConsumer(), protonMessage); + + assertNotNull("Expected existing body section to be found", protonMessage.getBody()); + amqpObjectMessageFacade.setObject(null); + assertNull("Expected existing body section to be cleared", protonMessage.getBody()); + assertNull("Expected null object", amqpObjectMessageFacade.getObject()); + } + + /** + * Test that setting a null object on a message results in the underlying + * body section being cleared, ensuring getObject returns null. + */ + @Test + public void testClearBodyWithExistingSerializedBodySection() throws Exception { + Message protonMessage = Message.Factory.create(); + protonMessage.setContentType(AmqpMessageSupport.SERIALIZED_JAVA_OBJECT_CONTENT_TYPE); + protonMessage.setBody(new Data(new Binary(new byte[0]))); + + AmqpJmsObjectMessageFacade amqpObjectMessageFacade = createReceivedObjectMessageFacade(createMockAmqpConsumer(), protonMessage); + + assertNotNull("Expected existing body section to be found", protonMessage.getBody()); + amqpObjectMessageFacade.clearBody(); + assertNull("Expected existing body section to be cleared", protonMessage.getBody()); + assertNull("Expected null object", amqpObjectMessageFacade.getObject()); + } + + /** + * Test that setting an object on a new message and later getting the value, returns an + * equal but different object that does not pick up intermediate changes to the set object. + */ + @Test + public void testSetThenGetObjectOnSerializedMessageReturnsSnapshot() throws Exception { + HashMap<String, String> origMap = new HashMap<String, String>(); + origMap.put("key1", "value1"); + + AmqpJmsObjectMessageFacade amqpObjectMessageFacade = createNewObjectMessageFacade(false); + amqpObjectMessageFacade.setObject(origMap); + + // verify we get a different-but-equal object back + Serializable serialized = amqpObjectMessageFacade.getObject(); + assertTrue("Unexpected object type returned", serialized instanceof Map<?, ?>); + Map<?, ?> returnedObject1 = (Map<?, ?>) serialized; + assertNotSame("Expected different objects, due to snapshot being taken", origMap, returnedObject1); + assertEquals("Expected equal objects, due to snapshot being taken", origMap, returnedObject1); + + // mutate the original object + origMap.put("key2", "value2"); + + // verify we get a different-but-equal object back when compared to the previously retrieved object + Serializable serialized2 = amqpObjectMessageFacade.getObject(); + assertTrue("Unexpected object type returned", serialized2 instanceof Map<?, ?>); + Map<?, ?> returnedObject2 = (Map<?, ?>) serialized2; + assertNotSame("Expected different objects, due to snapshot being taken", origMap, returnedObject2); + assertEquals("Expected equal objects, due to snapshot being taken", returnedObject1, returnedObject2); + + // verify the mutated map is a different and not equal object + assertNotSame("Expected different objects, due to snapshot being taken", returnedObject1, returnedObject2); + assertNotEquals("Expected objects to differ, due to snapshot being taken", origMap, returnedObject2); + } + // ---------- test handling of received messages -------------------------// @Test + public void testGetObjectUsingReceivedMessageWithNoBodySectionNoContentTypeReturnsNull() throws Exception { + doGetObjectUsingReceivedMessageWithNoBodySectionReturnsNullTestImpl(true); + } + + @Test public void testGetObjectUsingReceivedMessageWithNoBodySectionReturnsNull() throws Exception { + doGetObjectUsingReceivedMessageWithNoBodySectionReturnsNullTestImpl(false); + } + + private void doGetObjectUsingReceivedMessageWithNoBodySectionReturnsNullTestImpl(boolean amqpTyped) throws IOException, ClassNotFoundException { + Message message = Message.Factory.create(); + if (!amqpTyped) { + message.setContentType(AmqpMessageSupport.SERIALIZED_JAVA_OBJECT_CONTENT_TYPE); + } + AmqpJmsObjectMessageFacade amqpObjectMessageFacade = createReceivedObjectMessageFacade(createMockAmqpConsumer(), message); + + assertNull("Expected null object", amqpObjectMessageFacade.getObject()); + } + + @Test + public void testGetObjectUsingReceivedMessageWithDataSectionContainingNothingReturnsNull() throws Exception { Message message = Message.Factory.create(); + message.setContentType(AmqpMessageSupport.SERIALIZED_JAVA_OBJECT_CONTENT_TYPE); + message.setBody(new Data(null)); + AmqpJmsObjectMessageFacade amqpObjectMessageFacade = createReceivedObjectMessageFacade(createMockAmqpConsumer(), message); assertNull("Expected null object", amqpObjectMessageFacade.getObject()); } + + @Test + public void testGetObjectUsingReceivedMessageWithNonDataNonAmqvValueBinarySectionThrowsISE() throws Exception { + Message message = Message.Factory.create(); + message.setContentType(AmqpMessageSupport.SERIALIZED_JAVA_OBJECT_CONTENT_TYPE); + message.setBody(new AmqpValue("nonBinarySectionContent")); + + AmqpJmsObjectMessageFacade amqpObjectMessageFacade = createReceivedObjectMessageFacade(createMockAmqpConsumer(), message); + + try { + amqpObjectMessageFacade.getObject(); + fail("Expected exception to be thrown"); + } catch (IllegalStateException ise) { + // expected + } + } } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org