Allow custom delimiter when sending TextMessages via MBean

This enables possibility to send messages containing commas in the body
with tools such as jconsole.
Example simple text as body: body=Hello, world!
Example json as body: body={"a":"b","c":"d"}
This commit is contained in:
Alexej Timonin 2021-09-04 22:31:22 +02:00
parent 36f5592348
commit 7c63227003
3 changed files with 78 additions and 8 deletions

View File

@ -336,7 +336,22 @@ public class DestinationView implements DestinationViewMBean {
@Override @Override
public String sendTextMessageWithProperties(String properties) throws Exception { public String sendTextMessageWithProperties(String properties) throws Exception {
String[] kvs = properties.split(","); Map<String, String> props = parseProps(properties, ",");
return sendTextMessage(props, props.remove("body"), props.remove("username"), props.remove("password"));
}
@Override
public String sendTextMessageWithProperties(String properties, String delimiter) throws Exception {
if (delimiter == null || delimiter.isEmpty()) {
return sendTextMessageWithProperties(properties);
} else {
Map<String, String> props = parseProps(properties, delimiter);
return sendTextMessage(props, props.remove("body"), props.remove("username"), props.remove("password"));
}
}
private Map<String, String> parseProps(String properties, String delimiter) {
String[] kvs = properties.split(delimiter);
Map<String, String> props = new HashMap<String, String>(); Map<String, String> props = new HashMap<String, String>();
for (String kv : kvs) { for (String kv : kvs) {
String[] it = kv.split("="); String[] it = kv.split("=");
@ -344,7 +359,7 @@ public class DestinationView implements DestinationViewMBean {
props.put(it[0],it[1]); props.put(it[0],it[1]);
} }
} }
return sendTextMessage(props, props.remove("body"), props.remove("username"), props.remove("password")); return props;
} }
@Override @Override

View File

@ -168,13 +168,30 @@ public interface DestinationViewMBean {
/** /**
* Sends a TextMessage to the destination. * Sends a TextMessage to the destination.
* *
* @param properties the message properties to set as a comma sep name=value list. Can only * @param properties the message properties to set as name=value list separated
* contain Strings maped to primitive types or JMS properties. eg: body=hi,JMSReplyTo=Queue2 * by a comma. Can only contain Strings mapped to primitive
* types or JMS properties. eg: body=hi,JMSReplyTo=Queue2
* @return the message id of the message sent. * @return the message id of the message sent.
* @throws Exception * @throws Exception
*/ */
@MBeanInfo("Sends a TextMessage to the destination.") @MBeanInfo("Sends a TextMessage to the destination using comma separeted properties list. Example properties: body=value,header=value")
public String sendTextMessageWithProperties(String properties) throws Exception; public String sendTextMessageWithProperties(@MBeanInfo("properties") String properties) throws Exception;
/**
* Sends a TextMessage to the destination.
*
* @param properties the message properties to set as name=value list separated
* by a custom delimiter. Can only contain Strings mapped to
* primitive types or JMS properties. eg:
* body=hi,JMSReplyTo=Queue2
* @param delimiter The delimiter that separates each property. Defaults to
* comma if none is provided.
* @return the message id of the message sent.
* @throws Exception
*/
@MBeanInfo("Sends a TextMessage to the destination using properties separeted by arbetrary delimiter. Example properties: body=value;header=value")
public String sendTextMessageWithProperties(@MBeanInfo("properties") String properties,
@MBeanInfo("delimiter") String delimiter) throws Exception;
/** /**
* Sends a TextMesage to the destination. * Sends a TextMesage to the destination.

View File

@ -46,8 +46,6 @@ import javax.management.ObjectName;
import javax.management.openmbean.CompositeData; import javax.management.openmbean.CompositeData;
import javax.management.openmbean.TabularData; import javax.management.openmbean.TabularData;
import junit.textui.TestRunner;
import org.apache.activemq.ActiveMQConnection; import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.ActiveMQPrefetchPolicy; import org.apache.activemq.ActiveMQPrefetchPolicy;
@ -69,6 +67,9 @@ import org.apache.activemq.util.Wait;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import junit.textui.TestRunner;
/** /**
* A test case of the various MBeans in ActiveMQ. If you want to look at the * A test case of the various MBeans in ActiveMQ. If you want to look at the
* various MBeans after the test has been run then run this test case as a * various MBeans after the test has been run then run this test case as a
@ -117,6 +118,7 @@ public class MBeanTest extends EmbeddedBrokerTestSupport {
// messages on a queue // messages on a queue
assertSendViaMBean(); assertSendViaMBean();
assertSendCsnvViaMBean(); assertSendCsnvViaMBean();
assertSendTextMessageWithCustomDelimitedPropsViaMBean();
assertQueueBrowseWorks(); assertQueueBrowseWorks();
assertCreateAndDestroyDurableSubscriptions(); assertCreateAndDestroyDurableSubscriptions();
assertConsumerCounts(); assertConsumerCounts();
@ -728,6 +730,42 @@ public class MBeanTest extends EmbeddedBrokerTestSupport {
browseAndVerifyTypes(proxy, true); browseAndVerifyTypes(proxy, true);
} }
protected void assertSendTextMessageWithCustomDelimitedPropsViaMBean() throws Exception {
String queueName = getDestinationString() + ".SendMBBean";
ObjectName brokerName = assertRegisteredObjectName(domain + ":type=Broker,brokerName=localhost");
echo("Create QueueView MBean...");
BrokerViewMBean broker = MBeanServerInvocationHandler.newProxyInstance(mbeanServer, brokerName, BrokerViewMBean.class, true);
broker.addQueue(queueName);
ObjectName queueViewMBeanName = assertRegisteredObjectName(domain + ":type=Broker,brokerName=localhost,destinationType=Queue,destinationName=" + queueName);
echo("Create QueueView MBean...");
QueueViewMBean proxy = MBeanServerInvocationHandler.newProxyInstance(mbeanServer, queueViewMBeanName, QueueViewMBean.class, true);
proxy.purge();
int count = 5;
String delimiter = ";";
for (int i = 0; i < count; i++) {
String props = String.join(delimiter,
"body=message:" + i,
"JMSCorrelationID=MyCorrId",
"JMSDeliveryMode=1",
"JMSXGroupID=MyGroupID",
"JMSXGroupSeq=1234",
"JMSPriority=" + (i + 1),
"JMSType=MyType",
"MyHeader=" + i,
"MyStringHeader=StringHeader" + i);
proxy.sendTextMessageWithProperties(props, delimiter);
}
browseAndVerifyTypes(proxy, true);
}
protected void assertComplexData(int messageIndex, CompositeData cdata, String name, Object expected) { protected void assertComplexData(int messageIndex, CompositeData cdata, String name, Object expected) {
Object value = cdata.get(name); Object value = cdata.get(name);
assertEquals("Message " + messageIndex + " CData field: " + name, expected, value); assertEquals("Message " + messageIndex + " CData field: " + name, expected, value);