diff --git a/artemis-rest/src/main/java/org/apache/activemq/artemis/rest/HttpHeaderProperty.java b/artemis-rest/src/main/java/org/apache/activemq/artemis/rest/HttpHeaderProperty.java index f8ae43c896..7a0b74dc74 100644 --- a/artemis-rest/src/main/java/org/apache/activemq/artemis/rest/HttpHeaderProperty.java +++ b/artemis-rest/src/main/java/org/apache/activemq/artemis/rest/HttpHeaderProperty.java @@ -19,9 +19,11 @@ package org.apache.activemq.artemis.rest; public class HttpHeaderProperty { public static final String CONTENT_TYPE = "http_content$type"; + public static final String MESSAGE_PROPERTY_DISCRIMINATOR = "message.property."; /** - * Converts an HTTP header name to a selector compatible property name. '-' character is converted to + * Either strips the prefix "message.property." and returns the rest of the name or (if not starting with aforementioned prefix) + * converts an HTTP header name to a selector compatible property name. '-' character is converted to * '$'. The return property name will also be all lower case with an "http_" prepended. For example * "Content-Type" would be converted to "http_content$type"; * @@ -29,8 +31,12 @@ public class HttpHeaderProperty { * @return */ public static String toPropertyName(String httpHeader) { - httpHeader = httpHeader.replace('-', '$'); - return "http_" + httpHeader.toLowerCase(); + if (httpHeader.startsWith( MESSAGE_PROPERTY_DISCRIMINATOR )) { + return httpHeader.replaceAll( MESSAGE_PROPERTY_DISCRIMINATOR, "" ); + } else { + httpHeader = httpHeader.replace( '-', '$' ); + return "http_" + httpHeader.toLowerCase(); + } } /** diff --git a/artemis-rest/src/main/java/org/apache/activemq/artemis/rest/util/HttpMessageHelper.java b/artemis-rest/src/main/java/org/apache/activemq/artemis/rest/util/HttpMessageHelper.java index b04ba374c6..4e5a2784d7 100644 --- a/artemis-rest/src/main/java/org/apache/activemq/artemis/rest/util/HttpMessageHelper.java +++ b/artemis-rest/src/main/java/org/apache/activemq/artemis/rest/util/HttpMessageHelper.java @@ -30,6 +30,8 @@ import org.apache.activemq.artemis.rest.HttpHeaderProperty; import org.apache.activemq.artemis.utils.ObjectInputStreamWithClassLoader; import org.jboss.resteasy.client.ClientRequest; +import static org.apache.activemq.artemis.rest.HttpHeaderProperty.MESSAGE_PROPERTY_DISCRIMINATOR; + public class HttpMessageHelper { public static final String POSTED_AS_HTTP_MESSAGE = "postedAsHttpMessage"; @@ -39,6 +41,10 @@ public class HttpMessageHelper { return lowerKey.toLowerCase().startsWith("content") || lowerKey.toLowerCase().equals("link"); } + public static boolean isMessageProperty( String key) { + return key.toLowerCase().startsWith( MESSAGE_PROPERTY_DISCRIMINATOR ); + } + public static void buildMessage(ClientMessage message, ClientRequest request, String contentType, @@ -95,7 +101,7 @@ public class HttpMessageHelper { MultivaluedMap hdrs = headers.getRequestHeaders(); for (Entry> entry : hdrs.entrySet()) { String key = entry.getKey(); - if (isTransferableHttpHeader(key)) { + if (isTransferableHttpHeader(key) || isMessageProperty( key )) { List vals = entry.getValue(); String value = concatenateHeaderValue(vals); message.putStringProperty(HttpHeaderProperty.toPropertyName(key), value); diff --git a/artemis-rest/src/test/java/org/apache/activemq/artemis/rest/test/MessagePropertiesTest.java b/artemis-rest/src/test/java/org/apache/activemq/artemis/rest/test/MessagePropertiesTest.java new file mode 100644 index 0000000000..21263d6091 --- /dev/null +++ b/artemis-rest/src/test/java/org/apache/activemq/artemis/rest/test/MessagePropertiesTest.java @@ -0,0 +1,102 @@ +/* + * 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.rest.test; + +import org.apache.activemq.artemis.api.core.SimpleString; +import org.apache.activemq.artemis.api.core.client.ClientMessage; +import org.apache.activemq.artemis.api.core.client.ClientSession; +import org.apache.activemq.artemis.api.core.client.MessageHandler; +import org.apache.activemq.artemis.rest.HttpHeaderProperty; +import org.apache.activemq.artemis.rest.queue.QueueDeployment; +import org.jboss.resteasy.client.ClientRequest; +import org.jboss.resteasy.client.ClientResponse; +import org.jboss.resteasy.spi.Link; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import static org.apache.activemq.artemis.rest.util.HttpMessageHelper.POSTED_AS_HTTP_MESSAGE; +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.CoreMatchers.not; +import static org.jboss.resteasy.test.TestPortProvider.generateURL; + +public class MessagePropertiesTest extends MessageTestBase { + + + public static class Listener implements MessageHandler { + + public static CountDownLatch latch = new CountDownLatch(1); + public static Set< SimpleString > propertyNames; + + + @Override + public void onMessage(ClientMessage clientMessage) { + try { + propertyNames = clientMessage.getPropertyNames(); + } catch (Exception e) { + e.printStackTrace(); + } + latch.countDown(); + } + } + + @Test + public void testJmsProperties() throws Exception { + QueueDeployment deployment = new QueueDeployment(); + deployment.setDuplicatesAllowed(true); + deployment.setDurableSend(false); + final String queueName = "testQueue"; + deployment.setName(queueName); + manager.getQueueManager().deploy(deployment); + ClientSession session = manager.getQueueManager().getSessionFactory().createSession(); + try { + session.createConsumer(queueName).setMessageHandler(new Listener()); + session.start(); + + ClientRequest request = new ClientRequest(generateURL(Util.getUrlPath(queueName))); + + ClientResponse response = request.head(); + response.releaseConnection(); + Assert.assertEquals(200, response.getStatus()); + Link sender = getLinkByTitle(manager.getQueueManager().getLinkStrategy(), response, "create"); + System.out.println("create: " + sender); + + { + response = sender.request().body("text/plain", "val") + .header( "dummyHeader", "DummyValue" ) + .header( HttpHeaderProperty.MESSAGE_PROPERTY_DISCRIMINATOR + "property1", "val" ) + .post(); + response.releaseConnection(); + Assert.assertEquals(201, response.getStatus()); + + Listener.latch.await( 2, TimeUnit.SECONDS); + Assert.assertEquals(4, Listener.propertyNames.size()); + Assert.assertThat( Listener.propertyNames, hasItem( new SimpleString( "http_content$type" ) ) ); + Assert.assertThat( Listener.propertyNames, hasItem( new SimpleString( "http_content$length" ) ) ); + Assert.assertThat( Listener.propertyNames, hasItem( new SimpleString( POSTED_AS_HTTP_MESSAGE ) ) ); + Assert.assertThat( Listener.propertyNames, hasItem( new SimpleString( "property1" ) ) ); + Assert.assertThat( Listener.propertyNames, not(hasItem( new SimpleString( "dummyHeader" )) ) ); + } + } finally { + session.close(); + } + } + +}