Skip to content

Commit 228f05a

Browse files
committed
QPIDJMS-295 Add support for content-encoding property
1 parent 9e5b9fd commit 228f05a

5 files changed

Lines changed: 240 additions & 0 deletions

File tree

qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsMessageFacade.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,37 @@ public void setProviderMessageIdObject(Object messageId) {
333333
properties.setMessageId(messageId);
334334
}
335335

336+
/**
337+
* Retrieves the content encoding property, which identifies the encoding of the message content.
338+
*
339+
* @return the content encoding as a String, or null if not set.
340+
*/
341+
public String getContentEncoding() {
342+
if (properties != null) {
343+
Symbol contentEncoding = properties.getContentEncoding();
344+
if (contentEncoding != null) {
345+
return contentEncoding.toString();
346+
}
347+
}
348+
349+
return null;
350+
}
351+
352+
/**
353+
* Sets the content encoding property, which identifies the encoding of the message content.
354+
*
355+
* @param contentEncoding
356+
* the content encoding as a String, or null to clear.
357+
*/
358+
public void setContentEncoding(String contentEncoding) {
359+
if (contentEncoding != null) {
360+
lazyCreateProperties();
361+
properties.setContentEncoding(Symbol.valueOf(contentEncoding));
362+
} else if (properties != null) {
363+
properties.setContentEncoding(null);
364+
}
365+
}
366+
336367
@Override
337368
public void setMessageId(String messageId) throws IdConversionException {
338369
Object value = AmqpMessageIdHelper.toIdObject(messageId);

qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsMessagePropertyIntercepter.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static org.apache.qpid.jms.provider.amqp.message.AmqpMessageSupport.JMS_AMQP_REPLY_TO_GROUP_ID;
2020
import static org.apache.qpid.jms.provider.amqp.message.AmqpMessageSupport.JMS_AMQP_TTL;
2121
import static org.apache.qpid.jms.provider.amqp.message.AmqpMessageSupport.JMS_AMQP_TYPED_ENCODING;
22+
import static org.apache.qpid.jms.provider.amqp.message.AmqpMessageSupport.JMS_AMQP_CONTENT_ENCODING;
2223

2324
import java.util.HashMap;
2425
import java.util.HashSet;
@@ -189,6 +190,32 @@ public void clearProperty(AmqpJmsMessageFacade message) throws JMSException {
189190
// TODO - Should we leave encoding intact or change to the default.
190191
}
191192
});
193+
PROPERTY_INTERCEPTERS.put(JMS_AMQP_CONTENT_ENCODING, new PropertyIntercepter() {
194+
@Override
195+
public Object getProperty(AmqpJmsMessageFacade message) throws JMSException {
196+
return message.getContentEncoding();
197+
}
198+
199+
@Override
200+
public void setProperty(AmqpJmsMessageFacade message, Object value) throws JMSException {
201+
String rc = (String) TypeConversionSupport.convert(value, String.class);
202+
if (rc == null) {
203+
throw new JMSException("Property " + JMS_AMQP_CONTENT_ENCODING + " cannot be set from a " + value.getClass().getName());
204+
}
205+
message.setContentEncoding(rc);
206+
}
207+
208+
@Override
209+
public boolean propertyExists(AmqpJmsMessageFacade message) {
210+
String contentEncoding = message.getContentEncoding();
211+
return contentEncoding != null && !contentEncoding.isEmpty();
212+
}
213+
214+
@Override
215+
public void clearProperty(AmqpJmsMessageFacade message) throws JMSException {
216+
message.setContentEncoding(null);
217+
}
218+
});
192219
}
193220

194221
/**

qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpMessageSupport.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ public final class AmqpMessageSupport {
8383
public static final String JMS_AMQP_REPLY_TO_GROUP_ID = "JMS_AMQP_REPLY_TO_GROUP_ID";
8484
public static final String JMS_AMQP_TYPED_ENCODING = "JMS_AMQP_TYPED_ENCODING";
8585

86+
/**
87+
* Used to set or access the content-encoding property, identifying the message's encoding.
88+
* Must be a String when set.
89+
*/
90+
public static final String JMS_AMQP_CONTENT_ENCODING = "JMS_AMQP_CONTENT_ENCODING";
91+
8692
/**
8793
* Content type used to mark Data sections as containing a serialized java object.
8894
*/

qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/MessageIntegrationTest.java

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2410,4 +2410,106 @@ private void doReceivedMessageDeliveryTimeTestImpl(boolean setDeliveryTimeAnnota
24102410
assertEquals(expectedDeliveryTime, receivedMessage.getJMSDeliveryTime(), "Unexpected delivery time");
24112411
}
24122412
}
2413+
2414+
/**
2415+
* Tests that when a message with the content-encoding field set is received,
2416+
* the JMS message correctly reflects this value through the JMS_AMQP_CONTENT_ENCODING property.
2417+
*
2418+
* @throws Exception if an error occurs during the test.
2419+
*/
2420+
@Test
2421+
@Timeout(20)
2422+
public void testReceivedMessageWithContentEncodingPropertySet() throws Exception {
2423+
try (TestAmqpPeer testPeer = new TestAmqpPeer()) {
2424+
Connection connection = testFixture.establishConnecton(testPeer);
2425+
connection.start();
2426+
2427+
testPeer.expectBegin();
2428+
2429+
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
2430+
Queue queue = session.createQueue("myQueue");
2431+
2432+
DescribedType amqpValueNullContent = new AmqpValueDescribedType(null);
2433+
PropertiesDescribedType props = new PropertiesDescribedType();
2434+
2435+
String expectedContentEncoding = "gzip";
2436+
props.setContentEncoding(Symbol.valueOf(expectedContentEncoding));
2437+
2438+
testPeer.expectReceiverAttach();
2439+
testPeer.expectLinkFlowRespondWithTransfer(null, null, props, null, amqpValueNullContent);
2440+
testPeer.expectDispositionThatIsAcceptedAndSettled();
2441+
2442+
MessageConsumer messageConsumer = session.createConsumer(queue);
2443+
Message receivedMessage = messageConsumer.receive(3000);
2444+
testPeer.waitForAllHandlersToComplete(3000);
2445+
2446+
assertNotNull(receivedMessage, "did not receive the message");
2447+
2448+
boolean foundContentEncoding = false;
2449+
2450+
Enumeration<?> names = receivedMessage.getPropertyNames();
2451+
2452+
while (names.hasMoreElements()) {
2453+
Object element = names.nextElement();
2454+
if (AmqpMessageSupport.JMS_AMQP_CONTENT_ENCODING.equals(element)) {
2455+
foundContentEncoding = true;
2456+
}
2457+
}
2458+
2459+
assertTrue(foundContentEncoding, "JMS_AMQP_CONTENT_ENCODING not in property names");
2460+
assertTrue(receivedMessage.propertyExists(AmqpMessageSupport.JMS_AMQP_CONTENT_ENCODING), "JMS_AMQP_CONTENT_ENCODING does not exist");
2461+
assertEquals(expectedContentEncoding, receivedMessage.getStringProperty(AmqpMessageSupport.JMS_AMQP_CONTENT_ENCODING), "did not get the expected JMS_AMQP_CONTENT_ENCODING");
2462+
2463+
testPeer.expectClose();
2464+
connection.close();
2465+
2466+
testPeer.waitForAllHandlersToComplete(1000);
2467+
}
2468+
}
2469+
2470+
/**
2471+
* Test that a message with the "content-encoding" property set to "gzip" is correctly sent
2472+
* and that the property is encoded as an AMQP Symbol.
2473+
*
2474+
* @throws Exception if an error occurs during the test.
2475+
*/
2476+
@Test
2477+
@Timeout(20)
2478+
public void testSendMessageWithContentEncodingPropertySet() throws Exception {
2479+
try (TestAmqpPeer testPeer = new TestAmqpPeer()) {
2480+
Connection connection = testFixture.establishConnecton(testPeer);
2481+
testPeer.expectBegin();
2482+
testPeer.expectSenderAttach();
2483+
2484+
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
2485+
String queueName = "myQueue";
2486+
Queue queue = session.createQueue(queueName);
2487+
MessageProducer producer = session.createProducer(queue);
2488+
2489+
MessageHeaderSectionMatcher headersMatcher = new MessageHeaderSectionMatcher(true).withDurable(equalTo(true));
2490+
2491+
MessageAnnotationsSectionMatcher msgAnnotationsMatcher = new MessageAnnotationsSectionMatcher(true);
2492+
2493+
MessagePropertiesSectionMatcher propsMatcher = new MessagePropertiesSectionMatcher(true);
2494+
propsMatcher.withContentEncoding(equalTo(Symbol.valueOf("gzip")));
2495+
2496+
TransferPayloadCompositeMatcher messageMatcher = new TransferPayloadCompositeMatcher();
2497+
messageMatcher.setHeadersMatcher(headersMatcher);
2498+
messageMatcher.setMessageAnnotationsMatcher(msgAnnotationsMatcher);
2499+
messageMatcher.setPropertiesMatcher(propsMatcher);
2500+
messageMatcher.setMessageContentMatcher(new EncodedAmqpValueMatcher(null));
2501+
2502+
testPeer.expectTransfer(messageMatcher);
2503+
2504+
Message message = session.createTextMessage();
2505+
message.setStringProperty(AmqpMessageSupport.JMS_AMQP_CONTENT_ENCODING, "gzip");
2506+
2507+
producer.send(message);
2508+
2509+
testPeer.expectClose();
2510+
connection.close();
2511+
2512+
testPeer.waitForAllHandlersToComplete(1000);
2513+
}
2514+
}
24132515
}

qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsMessagePropertyIntercepterTest.java

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static org.apache.qpid.jms.provider.amqp.message.AmqpMessageSupport.JMS_AMQP_REPLY_TO_GROUP_ID;
2020
import static org.apache.qpid.jms.provider.amqp.message.AmqpMessageSupport.JMS_AMQP_TTL;
2121
import static org.apache.qpid.jms.provider.amqp.message.AmqpMessageSupport.JMS_AMQP_TYPED_ENCODING;
22+
import static org.apache.qpid.jms.provider.amqp.message.AmqpMessageSupport.JMS_AMQP_CONTENT_ENCODING;
2223
import static org.junit.jupiter.api.Assertions.assertEquals;
2324
import static org.junit.jupiter.api.Assertions.assertFalse;
2425
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -304,6 +305,79 @@ public void testSetJmsAmqpTypedEncodingConversionChecks() throws JMSException {
304305
}
305306
}
306307

308+
//-------- JMS_AMQP_CONTENT_ENCODING -------------------------------------//
309+
310+
@Test
311+
public void testJmsAmqpContentEncodingInGetAllPropertyNames() throws JMSException {
312+
assertTrue(AmqpJmsMessagePropertyIntercepter.getAllPropertyNames().contains(JMS_AMQP_CONTENT_ENCODING));
313+
}
314+
315+
@Test
316+
public void testSetJmsAmqpContentEncoding() throws JMSException {
317+
String testValue = "gzip";
318+
AmqpJmsObjectMessageFacade message = createAmqpObjectMessageFacade();
319+
AmqpJmsMessagePropertyIntercepter.setProperty(message, JMS_AMQP_CONTENT_ENCODING, testValue);
320+
Mockito.verify(message).setContentEncoding(testValue);
321+
}
322+
323+
@Test
324+
public void testGetJmsAmqpContentEncodingWhenNotSet() throws JMSException {
325+
AmqpJmsMessageFacade message = createAmqpMessageFacade();
326+
assertNull(AmqpJmsMessagePropertyIntercepter.getProperty(message, JMS_AMQP_CONTENT_ENCODING));
327+
}
328+
329+
@Test
330+
public void testGetJmsAmqpContentEncodingWhenSet() throws JMSException {
331+
String testValue = "gzip";
332+
AmqpJmsMessageFacade message = createAmqpMessageFacade();
333+
Mockito.when(message.getContentEncoding()).thenReturn(testValue);
334+
assertNotNull(AmqpJmsMessagePropertyIntercepter.getProperty(message, JMS_AMQP_CONTENT_ENCODING));
335+
assertEquals(testValue, AmqpJmsMessagePropertyIntercepter.getProperty(message, JMS_AMQP_CONTENT_ENCODING));
336+
}
337+
338+
@Test
339+
public void testJmsAmqpContentEncodingNotInPropertyNamesWhenNotSet() throws JMSException {
340+
AmqpJmsMessageFacade message = createAmqpMessageFacade();
341+
assertNull(AmqpJmsMessagePropertyIntercepter.getProperty(message, JMS_AMQP_CONTENT_ENCODING));
342+
assertFalse(AmqpJmsMessagePropertyIntercepter.getPropertyNames(message).contains(JMS_AMQP_CONTENT_ENCODING));
343+
}
344+
345+
@Test
346+
public void testJmsAmqpContentEncodingInPropertyNamesWhenSet() throws JMSException {
347+
String testValue = "gzip";
348+
AmqpJmsMessageFacade message = createAmqpMessageFacade();
349+
Mockito.when(message.getApplicationPropertyNames(anySet())).then(new PassPropertyNames());
350+
Mockito.when(message.getContentEncoding()).thenReturn(testValue);
351+
assertTrue(AmqpJmsMessagePropertyIntercepter.getPropertyNames(message).contains(JMS_AMQP_CONTENT_ENCODING));
352+
}
353+
354+
@Test
355+
public void testJmsAmqpContentEncodingPropertyExistsWhenSet() throws JMSException {
356+
String testValue = "gzip";
357+
AmqpJmsMessageFacade message = createAmqpMessageFacade();
358+
Mockito.when(message.getContentEncoding()).thenReturn(testValue);
359+
assertTrue(AmqpJmsMessagePropertyIntercepter.propertyExists(message, JMS_AMQP_CONTENT_ENCODING));
360+
}
361+
362+
@Test
363+
public void testJmsAmqpContentEncodingPropertyExistsWhenNotSet() throws JMSException {
364+
AmqpJmsMessageFacade message = createAmqpMessageFacade();
365+
Mockito.when(message.getContentEncoding()).thenReturn(null);
366+
assertFalse(AmqpJmsMessagePropertyIntercepter.propertyExists(message, JMS_AMQP_CONTENT_ENCODING));
367+
Mockito.when(message.getContentEncoding()).thenReturn("");
368+
assertFalse(AmqpJmsMessagePropertyIntercepter.propertyExists(message, JMS_AMQP_CONTENT_ENCODING));
369+
}
370+
371+
@Test
372+
public void testSetJmsAmqpContentEncodingConversionChecks() throws JMSException {
373+
AmqpJmsMessageFacade message = createAmqpMessageFacade();
374+
try {
375+
AmqpJmsMessagePropertyIntercepter.setProperty(message, JMS_AMQP_CONTENT_ENCODING, new byte[1]);
376+
fail("Should have thrown an exception for this call");
377+
} catch (JMSException ignored) {
378+
}
379+
}
380+
307381
//--------- Utilities ----------------------------------------------------//
308382

309383
private AmqpJmsMessageFacade createAmqpMessageFacade() {

0 commit comments

Comments
 (0)