Author: davsclaus
Date: Fri May 13 13:10:22 2011
New Revision: 1102705
URL: http://svn.apache.org/viewvc?rev=1102705&view=rev
Log:
CAMEL-3972: Added operation to browsable endpoint in JMX to show message in
generic XML format.
Added:
camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedBrowseableEndpointAsXmlTest.java
- copied, changed from r1102648,
camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedBrowseableEndpointTest.java
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedBrowsableEndpoint.java
camel/trunk/camel-core/src/main/java/org/apache/camel/util/MessageHelper.java
camel/trunk/camel-core/src/main/java/org/apache/camel/util/StringHelper.java
camel/trunk/camel-core/src/main/java/org/apache/camel/view/XmlGraphGenerator.java
camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedBrowseableEndpointTest.java
camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsQueueEndpoint.java
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedBrowsableEndpoint.java
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedBrowsableEndpoint.java?rev=1102705&r1=1102704&r2=1102705&view=diff
==============================================================================
---
camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedBrowsableEndpoint.java
(original)
+++
camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedBrowsableEndpoint.java
Fri May 13 13:10:22 2011
@@ -17,7 +17,9 @@
package org.apache.camel.management.mbean;
import org.apache.camel.Exchange;
+import org.apache.camel.Message;
import org.apache.camel.spi.BrowsableEndpoint;
+import org.apache.camel.util.MessageHelper;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedResource;
@@ -56,4 +58,41 @@ public class ManagedBrowsableEndpoint ex
return exchange.toString();
}
+ @ManagedOperation(description = "Get message body from queue by index")
+ public String browseMessageBody(Integer index) {
+ if (index >= endpoint.getExchanges().size()) {
+ return null;
+ }
+ Exchange exchange = endpoint.getExchanges().get(index);
+ if (exchange == null) {
+ return null;
+ }
+
+ Object body;
+ if (exchange.hasOut()) {
+ body = exchange.getOut().getBody();
+ } else {
+ body = exchange.getIn().getBody();
+ }
+
+ // must use java type with JMX such as java.lang.String
+ return body != null ? body.toString() : null;
+ }
+
+ @ManagedOperation(description = "Get message as XML from queue by index")
+ public String browseMessageAsXml(Integer index) {
+ if (index >= endpoint.getExchanges().size()) {
+ return null;
+ }
+ Exchange exchange = endpoint.getExchanges().get(index);
+ if (exchange == null) {
+ return null;
+ }
+
+ Message msg = exchange.hasOut() ? exchange.getOut() : exchange.getIn();
+ String xml = MessageHelper.dumpAsXml(msg);
+
+ return xml;
+ }
+
}
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/util/MessageHelper.java
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/util/MessageHelper.java?rev=1102705&r1=1102704&r2=1102705&view=diff
==============================================================================
---
camel/trunk/camel-core/src/main/java/org/apache/camel/util/MessageHelper.java
(original)
+++
camel/trunk/camel-core/src/main/java/org/apache/camel/util/MessageHelper.java
Fri May 13 13:10:22 2011
@@ -20,6 +20,8 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
+import java.util.Map;
+import java.util.TreeMap;
import javax.xml.transform.stream.StreamSource;
import org.apache.camel.Exchange;
@@ -235,4 +237,72 @@ public final class MessageHelper {
return prepend + body;
}
+ /**
+ * Dumps the message as a generic XML structure.
+ *
+ * @param message the message
+ * @return the XML
+ */
+ public static String dumpAsXml(Message message) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("<message>\n");
+
+ // headers
+ if (message.hasHeaders()) {
+ sb.append("<headers>\n");
+ // sort the headers so they are listed A..Z
+ Map<String, Object> headers = new TreeMap<String,
Object>(message.getHeaders());
+ for (Map.Entry<String, Object> entry : headers.entrySet()) {
+ Object value = entry.getValue();
+ String type = ObjectHelper.classCanonicalName(value);
+ sb.append("<header key=\"" + entry.getKey() + "\"");
+ if (type != null) {
+ sb.append(" type=\"" + type + "\"");
+ }
+ sb.append(">");
+
+ // dump header value as XML, use Camel type converter to
convert to String
+ if (value != null) {
+ String xml =
message.getExchange().getContext().getTypeConverter().convertTo(String.class,
value);
+ if (xml != null) {
+ // is the header value already XML
+ if (xml.startsWith("<") && xml.endsWith(">")) {
+ sb.append(xml);
+ } else {
+ // no its not xml so xml encode it
+ sb.append(StringHelper.xmlEncode(xml));
+ }
+ }
+ }
+
+ sb.append("</header>\n");
+ }
+ sb.append("</headers>\n");
+ }
+
+ sb.append("<body");
+ String type = ObjectHelper.classCanonicalName(message.getBody());
+ if (type != null) {
+ sb.append(" type=\"" + type + "\"");
+ }
+ sb.append(">");
+
+ // dump body value as XML, use Camel type converter to convert to
String
+ String xml = message.getBody(String.class);
+ if (xml != null) {
+ // is the body already XML
+ if (xml.startsWith("<") && xml.endsWith(">")) {
+ sb.append(xml);
+ } else {
+ // no its not xml so xml encode it
+ sb.append(StringHelper.xmlEncode(xml));
+ }
+ }
+
+ sb.append("</body>\n");
+
+ sb.append("</message>");
+ return sb.toString();
+ }
+
}
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/util/StringHelper.java
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/util/StringHelper.java?rev=1102705&r1=1102704&r2=1102705&view=diff
==============================================================================
---
camel/trunk/camel-core/src/main/java/org/apache/camel/util/StringHelper.java
(original)
+++
camel/trunk/camel-core/src/main/java/org/apache/camel/util/StringHelper.java
Fri May 13 13:10:22 2011
@@ -75,5 +75,19 @@ public final class StringHelper {
s = s.replaceAll("\"", "");
return s;
}
-
+
+ /**
+ * Encodes the text into safe XML by replacing < > and & with XML tokens
+ *
+ * @param text the text
+ * @return the encoded text
+ */
+ public static String xmlEncode(String text) {
+ if (text == null) {
+ return "";
+ }
+ // must replace amp first, so we dont replace < to amp later
+ return text.replaceAll("&", "&").replaceAll("\"",
""").replaceAll("<", "<").replaceAll(">", ">");
+ }
+
}
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/view/XmlGraphGenerator.java
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/view/XmlGraphGenerator.java?rev=1102705&r1=1102704&r2=1102705&view=diff
==============================================================================
---
camel/trunk/camel-core/src/main/java/org/apache/camel/view/XmlGraphGenerator.java
(original)
+++
camel/trunk/camel-core/src/main/java/org/apache/camel/view/XmlGraphGenerator.java
Fri May 13 13:10:22 2011
@@ -26,6 +26,7 @@ import org.apache.camel.model.MulticastD
import org.apache.camel.model.ProcessorDefinition;
import org.apache.camel.model.RouteDefinition;
import static org.apache.camel.util.ObjectHelper.isEmpty;
+import static org.apache.camel.util.StringHelper.xmlEncode;
/**
* @version
@@ -60,7 +61,7 @@ public class XmlGraphGenerator extends G
}
protected void printRoutes(PrintWriter writer, String group,
List<RouteDefinition> routes) {
- group = encode(group);
+ group = xmlEncode(group);
if (group != null) {
int idx = group.lastIndexOf('.');
String name = group;
@@ -78,7 +79,7 @@ public class XmlGraphGenerator extends G
if (first) {
first = false;
if (group != null) {
- writer.println("<Edge fromID='" + group + "' toID='" +
encode(nodeData.id) + "'/>");
+ writer.println("<Edge fromID='" + group + "' toID='" +
xmlEncode(nodeData.id) + "'/>");
}
}
printRoute(writer, route, nodeData);
@@ -115,13 +116,13 @@ public class XmlGraphGenerator extends G
if (fromData != null) {
writer.print("<Edge fromID=\"");
- writer.print(encode(fromData.id));
+ writer.print(xmlEncode(fromData.id));
writer.print("\" toID=\"");
- writer.print(encode(toData.id));
+ writer.print(xmlEncode(toData.id));
String association = toData.edgeLabel;
if (isEmpty(association)) {
writer.print("\" association=\"");
- writer.print(encode(association));
+ writer.print(xmlEncode(association));
}
writer.println("\"/>");
}
@@ -145,13 +146,13 @@ public class XmlGraphGenerator extends G
writer.println();
writer.print("<Node id=\"");
- writer.print(encode(data.id));
+ writer.print(xmlEncode(data.id));
writer.print("\" name=\"");
String name = data.label;
if (isEmpty(name)) {
name = data.tooltop;
}
- writer.print(encode(name));
+ writer.print(xmlEncode(name));
writer.print("\" nodeType=\"");
String nodeType = data.image;
if (isEmpty(nodeType)) {
@@ -160,22 +161,15 @@ public class XmlGraphGenerator extends G
nodeType = "node";
}
}
- writer.print(encode(nodeType));
+ writer.print(xmlEncode(nodeType));
writer.print("\" description=\"");
- writer.print(encode(data.tooltop));
+ writer.print(xmlEncode(data.tooltop));
if (addUrl) {
writer.print("\" url=\"");
- writer.print(encode(data.url));
+ writer.print(xmlEncode(data.url));
}
writer.println("\"/>");
}
}
- protected String encode(String text) {
- if (text == null) {
- return "";
- }
- return text.replaceAll("\"", """).replaceAll("<", "<").
- replaceAll(">", ">").replaceAll("&", "&");
- }
}
Copied:
camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedBrowseableEndpointAsXmlTest.java
(from r1102648,
camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedBrowseableEndpointTest.java)
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedBrowseableEndpointAsXmlTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedBrowseableEndpointAsXmlTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedBrowseableEndpointTest.java&r1=1102648&r2=1102705&rev=1102705&view=diff
==============================================================================
---
camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedBrowseableEndpointTest.java
(original)
+++
camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedBrowseableEndpointAsXmlTest.java
Fri May 13 13:10:22 2011
@@ -16,6 +16,8 @@
*/
package org.apache.camel.management;
+import java.util.HashMap;
+import java.util.Map;
import javax.management.MBeanServer;
import javax.management.ObjectName;
@@ -24,32 +26,70 @@ import org.apache.camel.builder.RouteBui
/**
* @version
*/
-public class ManagedBrowseableEndpointTest extends ManagementTestSupport {
+public class ManagedBrowseableEndpointAsXmlTest extends ManagementTestSupport {
- public void testBrowseableEndpoint() throws Exception {
- getMockEndpoint("mock:result").expectedMessageCount(2);
+ public void testBrowseableEndpointAsXml() throws Exception {
+ getMockEndpoint("mock:result").expectedMessageCount(7);
- template.sendBody("direct:start", "Hello World");
- template.sendBody("direct:start", "Bye World");
+ template.sendBody("direct:start", "<foo>Camel > Donkey</foo>");
+ template.sendBody("direct:start", "Camel > Donkey");
+ template.sendBodyAndHeader("direct:start", "<foo>Camel >
Donkey</foo>", "name", "Me & You");
+ template.sendBodyAndHeader("direct:start", "<foo>Camel >
Donkey</foo>", "title", "<title>Me & You</title>");
+ template.sendBodyAndHeader("direct:start", "Camel > Donkey", "name",
"Me & You");
+ template.sendBodyAndHeader("direct:start", 123, "user", true);
+ Map<String, Object> headers = new HashMap<String, Object>();
+ headers.put("user", false);
+ headers.put("uid", 123);
+ headers.put("title", "Camel rocks");
+ template.sendBodyAndHeaders("direct:start",
"<animal><name>Donkey</name><age>17</age></animal>", headers);
assertMockEndpointsSatisfied();
MBeanServer mbeanServer = getMBeanServer();
ObjectName name =
ObjectName.getInstance("org.apache.camel:context=localhost/camel-1,type=endpoints,name=\"mock://result\"");
- String uri = (String) mbeanServer.getAttribute(name, "EndpointUri");
- assertEquals("mock://result", uri);
- Long size = (Long) mbeanServer.invoke(name, "queueSize", null, null);
- assertEquals(2, size.longValue());
+ String out = (String) mbeanServer.invoke(name, "browseMessageAsXml",
new Object[]{0}, new String[]{"java.lang.Integer"});
+ assertNotNull(out);
+ log.info(out);
+ assertEquals("<message>\n<body type=\"java.lang.String\"><foo>Camel
> Donkey</foo></body>\n</message>", out);
+
+ out = (String) mbeanServer.invoke(name, "browseMessageAsXml", new
Object[]{1}, new String[]{"java.lang.Integer"});
+ assertNotNull(out);
+ log.info(out);
+ assertEquals("<message>\n<body type=\"java.lang.String\">Camel >
Donkey</body>\n</message>", out);
+
+ out = (String) mbeanServer.invoke(name, "browseMessageAsXml", new
Object[]{2}, new String[]{"java.lang.Integer"});
+ assertNotNull(out);
+ log.info(out);
+ assertEquals("<message>\n<headers>\n<header key=\"name\"
type=\"java.lang.String\">Me & You</header>\n</headers>\n"
+ + "<body type=\"java.lang.String\"><foo>Camel >
Donkey</foo></body>\n</message>", out);
- String out = (String) mbeanServer.invoke(name, "browseExchange", new
Object[]{0}, new String[]{"java.lang.Integer"});
+ out = (String) mbeanServer.invoke(name, "browseMessageAsXml", new
Object[]{3}, new String[]{"java.lang.Integer"});
assertNotNull(out);
- assertTrue(out.contains("Hello World"));
+ log.info(out);
+ assertEquals("<message>\n<headers>\n<header key=\"title\"
type=\"java.lang.String\"><title>Me & You</title></header>\n</headers>\n"
+ + "<body type=\"java.lang.String\"><foo>Camel >
Donkey</foo></body>\n</message>", out);
- out = (String) mbeanServer.invoke(name, "browseExchange", new
Object[]{1}, new String[]{"java.lang.Integer"});
+ out = (String) mbeanServer.invoke(name, "browseMessageAsXml", new
Object[]{4}, new String[]{"java.lang.Integer"});
assertNotNull(out);
- assertTrue(out.contains("Bye World"));
+ log.info(out);
+ assertEquals("<message>\n<headers>\n<header key=\"name\"
type=\"java.lang.String\">Me & You</header>\n</headers>\n"
+ + "<body type=\"java.lang.String\">Camel >
Donkey</body>\n</message>", out);
+
+ out = (String) mbeanServer.invoke(name, "browseMessageAsXml", new
Object[]{5}, new String[]{"java.lang.Integer"});
+ assertNotNull(out);
+ log.info(out);
+ assertEquals("<message>\n<headers>\n<header key=\"user\"
type=\"java.lang.Boolean\">true</header>\n</headers>\n"
+ + "<body type=\"java.lang.Integer\">123</body>\n</message>",
out);
+
+ out = (String) mbeanServer.invoke(name, "browseMessageAsXml", new
Object[]{6}, new String[]{"java.lang.Integer"});
+ assertNotNull(out);
+ log.info(out);
+ assertEquals("<message>\n<headers>\n<header key=\"title\"
type=\"java.lang.String\">Camel rocks</header>\n"
+ + "<header key=\"uid\"
type=\"java.lang.Integer\">123</header>\n"
+ + "<header key=\"user\"
type=\"java.lang.Boolean\">false</header>\n</headers>\n"
+ + "<body
type=\"java.lang.String\"><animal><name>Donkey</name><age>17</age></animal></body>\n</message>",
out);
}
@Override
@@ -57,7 +97,9 @@ public class ManagedBrowseableEndpointTe
return new RouteBuilder() {
@Override
public void configure() throws Exception {
- from("direct:start").to("log:foo").to("mock:result");
+ context.setUseBreadcrumb(false);
+
+ from("direct:start").to("mock:result");
}
};
}
Modified:
camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedBrowseableEndpointTest.java
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedBrowseableEndpointTest.java?rev=1102705&r1=1102704&r2=1102705&view=diff
==============================================================================
---
camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedBrowseableEndpointTest.java
(original)
+++
camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedBrowseableEndpointTest.java
Fri May 13 13:10:22 2011
@@ -50,6 +50,10 @@ public class ManagedBrowseableEndpointTe
out = (String) mbeanServer.invoke(name, "browseExchange", new
Object[]{1}, new String[]{"java.lang.Integer"});
assertNotNull(out);
assertTrue(out.contains("Bye World"));
+
+ out = (String) mbeanServer.invoke(name, "browseMessageBody", new
Object[]{1}, new String[]{"java.lang.Integer"});
+ assertNotNull(out);
+ assertEquals("Bye World", out);
}
@Override
Modified:
camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsQueueEndpoint.java
URL:
http://svn.apache.org/viewvc/camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsQueueEndpoint.java?rev=1102705&r1=1102704&r2=1102705&view=diff
==============================================================================
---
camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsQueueEndpoint.java
(original)
+++
camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsQueueEndpoint.java
Fri May 13 13:10:22 2011
@@ -22,7 +22,9 @@ import javax.jms.JMSException;
import javax.jms.Queue;
import org.apache.camel.Exchange;
+import org.apache.camel.Message;
import org.apache.camel.spi.BrowsableEndpoint;
+import org.apache.camel.util.MessageHelper;
import org.springframework.jms.core.JmsOperations;
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedOperation;
@@ -102,7 +104,11 @@ public class JmsQueueEndpoint extends Jm
@ManagedOperation(description = "Get Exchange from queue by index")
public String browseExchange(Integer index) {
- Exchange exchange = getExchanges().get(index);
+ List<Exchange> exchanges = getExchanges();
+ if (index >= exchanges.size()) {
+ return null;
+ }
+ Exchange exchange = exchanges.get(index);
if (exchange == null) {
return null;
}
@@ -110,6 +116,45 @@ public class JmsQueueEndpoint extends Jm
return exchange.toString();
}
+ @ManagedOperation(description = "Get message body from queue by index")
+ public String browseMessageBody(Integer index) {
+ List<Exchange> exchanges = getExchanges();
+ if (index >= exchanges.size()) {
+ return null;
+ }
+ Exchange exchange = exchanges.get(index);
+ if (exchange == null) {
+ return null;
+ }
+
+ Object body;
+ if (exchange.hasOut()) {
+ body = exchange.getOut().getBody();
+ } else {
+ body = exchange.getIn().getBody();
+ }
+
+ // must use java type with JMX such as java.lang.String
+ return body != null ? body.toString() : null;
+ }
+
+ @ManagedOperation(description = "Get message as XML from queue by index")
+ public String browseMessageAsXml(Integer index) {
+ List<Exchange> exchanges = getExchanges();
+ if (index >= exchanges.size()) {
+ return null;
+ }
+ Exchange exchange = exchanges.get(index);
+ if (exchange == null) {
+ return null;
+ }
+
+ Message msg = exchange.hasOut() ? exchange.getOut() : exchange.getIn();
+ String xml = MessageHelper.dumpAsXml(msg);
+
+ return xml;
+ }
+
protected QueueBrowseStrategy createQueueBrowseStrategy() {
return new DefaultQueueBrowseStrategy();
}