diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataConstants.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataConstants.java index b4ebe49a2c..be7e84e61a 100644 --- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataConstants.java +++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataConstants.java @@ -26,56 +26,56 @@ public final class XmlDataConstants { // Utility } - static final String XML_VERSION = "1.0"; - static final String DOCUMENT_PARENT = "activemq-journal"; - static final String BINDINGS_PARENT = "bindings"; + public static final String XML_VERSION = "1.0"; + public static final String DOCUMENT_PARENT = "activemq-journal"; + public static final String BINDINGS_PARENT = "bindings"; - static final String QUEUE_BINDINGS_CHILD = "queue-binding"; - static final String QUEUE_BINDING_ADDRESS = "address"; - static final String QUEUE_BINDING_FILTER_STRING = "filter-string"; - static final String QUEUE_BINDING_NAME = "name"; - static final String QUEUE_BINDING_ID = "id"; - static final String QUEUE_BINDING_ROUTING_TYPE = "routing-type"; + public static final String QUEUE_BINDINGS_CHILD = "queue-binding"; + public static final String QUEUE_BINDING_ADDRESS = "address"; + public static final String QUEUE_BINDING_FILTER_STRING = "filter-string"; + public static final String QUEUE_BINDING_NAME = "name"; + public static final String QUEUE_BINDING_ID = "id"; + public static final String QUEUE_BINDING_ROUTING_TYPE = "routing-type"; - static final String ADDRESS_BINDINGS_CHILD = "address-binding"; - static final String ADDRESS_BINDING_NAME = "name"; - static final String ADDRESS_BINDING_ID = "id"; - static final String ADDRESS_BINDING_ROUTING_TYPE = "routing-types"; + public static final String ADDRESS_BINDINGS_CHILD = "address-binding"; + public static final String ADDRESS_BINDING_NAME = "name"; + public static final String ADDRESS_BINDING_ID = "id"; + public static final String ADDRESS_BINDING_ROUTING_TYPE = "routing-types"; - static final String MESSAGES_PARENT = "messages"; - static final String MESSAGES_CHILD = "message"; - static final String MESSAGE_ID = "id"; - static final String MESSAGE_PRIORITY = "priority"; - static final String MESSAGE_EXPIRATION = "expiration"; - static final String MESSAGE_TIMESTAMP = "timestamp"; - static final String DEFAULT_TYPE_PRETTY = "default"; - static final String BYTES_TYPE_PRETTY = "bytes"; - static final String MAP_TYPE_PRETTY = "map"; - static final String OBJECT_TYPE_PRETTY = "object"; - static final String STREAM_TYPE_PRETTY = "stream"; - static final String TEXT_TYPE_PRETTY = "text"; - static final String MESSAGE_TYPE = "type"; - static final String MESSAGE_IS_LARGE = "isLarge"; - static final String MESSAGE_USER_ID = "user-id"; - static final String MESSAGE_BODY = "body"; - static final String PROPERTIES_PARENT = "properties"; - static final String PROPERTIES_CHILD = "property"; - static final String PROPERTY_NAME = "name"; - static final String PROPERTY_VALUE = "value"; - static final String PROPERTY_TYPE = "type"; - static final String QUEUES_PARENT = "queues"; - static final String QUEUES_CHILD = "queue"; - static final String QUEUE_NAME = "name"; - static final String PROPERTY_TYPE_BOOLEAN = "boolean"; - static final String PROPERTY_TYPE_BYTE = "byte"; - static final String PROPERTY_TYPE_BYTES = "bytes"; - static final String PROPERTY_TYPE_SHORT = "short"; - static final String PROPERTY_TYPE_INTEGER = "integer"; - static final String PROPERTY_TYPE_LONG = "long"; - static final String PROPERTY_TYPE_FLOAT = "float"; - static final String PROPERTY_TYPE_DOUBLE = "double"; - static final String PROPERTY_TYPE_STRING = "string"; - static final String PROPERTY_TYPE_SIMPLE_STRING = "simple-string"; + public static final String MESSAGES_PARENT = "messages"; + public static final String MESSAGES_CHILD = "message"; + public static final String MESSAGE_ID = "id"; + public static final String MESSAGE_PRIORITY = "priority"; + public static final String MESSAGE_EXPIRATION = "expiration"; + public static final String MESSAGE_TIMESTAMP = "timestamp"; + public static final String DEFAULT_TYPE_PRETTY = "default"; + public static final String BYTES_TYPE_PRETTY = "bytes"; + public static final String MAP_TYPE_PRETTY = "map"; + public static final String OBJECT_TYPE_PRETTY = "object"; + public static final String STREAM_TYPE_PRETTY = "stream"; + public static final String TEXT_TYPE_PRETTY = "text"; + public static final String MESSAGE_TYPE = "type"; + public static final String MESSAGE_IS_LARGE = "isLarge"; + public static final String MESSAGE_USER_ID = "user-id"; + public static final String MESSAGE_BODY = "body"; + public static final String PROPERTIES_PARENT = "properties"; + public static final String PROPERTIES_CHILD = "property"; + public static final String PROPERTY_NAME = "name"; + public static final String PROPERTY_VALUE = "value"; + public static final String PROPERTY_TYPE = "type"; + public static final String QUEUES_PARENT = "queues"; + public static final String QUEUES_CHILD = "queue"; + public static final String QUEUE_NAME = "name"; + public static final String PROPERTY_TYPE_BOOLEAN = "boolean"; + public static final String PROPERTY_TYPE_BYTE = "byte"; + public static final String PROPERTY_TYPE_BYTES = "bytes"; + public static final String PROPERTY_TYPE_SHORT = "short"; + public static final String PROPERTY_TYPE_INTEGER = "integer"; + public static final String PROPERTY_TYPE_LONG = "long"; + public static final String PROPERTY_TYPE_FLOAT = "float"; + public static final String PROPERTY_TYPE_DOUBLE = "double"; + public static final String PROPERTY_TYPE_STRING = "string"; + public static final String PROPERTY_TYPE_SIMPLE_STRING = "simple-string"; static final String JMS_CONNECTION_FACTORY_NAME = "name"; static final String JMS_CONNECTION_FACTORY_CLIENT_ID = "client-id"; diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporter.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporter.java index fefe88e01c..4f9918158c 100644 --- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporter.java +++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporter.java @@ -16,9 +16,6 @@ */ package org.apache.activemq.artemis.cli.commands.tools; -import javax.xml.stream.XMLOutputFactory; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamWriter; import java.io.File; import java.io.OutputStream; import java.lang.reflect.InvocationHandler; @@ -36,7 +33,10 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; -import io.airlift.airline.Command; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; + import org.apache.activemq.artemis.api.core.ActiveMQBuffer; import org.apache.activemq.artemis.api.core.ActiveMQBuffers; import org.apache.activemq.artemis.api.core.ActiveMQException; @@ -80,10 +80,11 @@ import org.apache.activemq.artemis.core.settings.HierarchicalRepository; import org.apache.activemq.artemis.core.settings.impl.AddressSettings; import org.apache.activemq.artemis.core.settings.impl.HierarchicalObjectRepository; import org.apache.activemq.artemis.utils.ActiveMQThreadFactory; -import org.apache.activemq.artemis.utils.Base64; import org.apache.activemq.artemis.utils.ExecutorFactory; import org.apache.activemq.artemis.utils.OrderedExecutorFactory; +import io.airlift.airline.Command; + @Command(name = "exp", description = "Export all message-data using an XML that could be interpreted by any system.") public final class XmlDataExporter extends OptionalLocking { @@ -471,11 +472,7 @@ public final class XmlDataExporter extends OptionalLocking { if (message.isLargeMessage()) { printLargeMessageBody((LargeServerMessage) message); } else { - int size = message.getEndOfBodyPosition() - message.getBodyBuffer().readerIndex(); - byte[] buffer = new byte[size]; - message.getBodyBuffer().readBytes(buffer); - - xmlWriter.writeCData(encode(buffer)); + xmlWriter.writeCData(XmlDataExporterUtil.encodeMessageBody(message)); } xmlWriter.writeEndElement(); // end MESSAGE_BODY } @@ -499,7 +496,7 @@ public final class XmlDataExporter extends OptionalLocking { } ActiveMQBuffer buffer = ActiveMQBuffers.fixedBuffer(bufferSize.intValue()); encoder.encode(buffer, bufferSize.intValue()); - xmlWriter.writeCData(encode(buffer.toByteBuffer().array())); + xmlWriter.writeCData(XmlDataExporterUtil.encode(buffer.toByteBuffer().array())); totalBytesWritten += bufferSize; } encoder.close(); @@ -531,35 +528,12 @@ public final class XmlDataExporter extends OptionalLocking { Object value = message.getObjectProperty(key); xmlWriter.writeEmptyElement(XmlDataConstants.PROPERTIES_CHILD); xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_NAME, key.toString()); - if (value instanceof byte[]) { - xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_VALUE, encode((byte[]) value)); - } else { - xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_VALUE, value == null ? XmlDataConstants.NULL : value.toString()); - } + xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_VALUE, XmlDataExporterUtil.convertProperty(value)); - // if the value is null then we can't really know what it is so just set the type to the most generic thing - if (value == null) { - xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_BYTES); - } else if (value instanceof Boolean) { - xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_BOOLEAN); - } else if (value instanceof Byte) { - xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_BYTE); - } else if (value instanceof Short) { - xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_SHORT); - } else if (value instanceof Integer) { - xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_INTEGER); - } else if (value instanceof Long) { - xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_LONG); - } else if (value instanceof Float) { - xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_FLOAT); - } else if (value instanceof Double) { - xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_DOUBLE); - } else if (value instanceof String) { - xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_STRING); - } else if (value instanceof SimpleString) { - xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_SIMPLE_STRING); - } else if (value instanceof byte[]) { - xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_BYTES); + // Write the property type as an attribute + String propertyType = XmlDataExporterUtil.getPropertyType(value); + if (propertyType != null) { + xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, propertyType); } } xmlWriter.writeEndElement(); // end PROPERTIES_PARENT @@ -570,19 +544,7 @@ public final class XmlDataExporter extends OptionalLocking { xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_PRIORITY, Byte.toString(message.getPriority())); xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_EXPIRATION, Long.toString(message.getExpiration())); xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_TIMESTAMP, Long.toString(message.getTimestamp())); - byte rawType = message.getType(); - String prettyType = XmlDataConstants.DEFAULT_TYPE_PRETTY; - if (rawType == Message.BYTES_TYPE) { - prettyType = XmlDataConstants.BYTES_TYPE_PRETTY; - } else if (rawType == Message.MAP_TYPE) { - prettyType = XmlDataConstants.MAP_TYPE_PRETTY; - } else if (rawType == Message.OBJECT_TYPE) { - prettyType = XmlDataConstants.OBJECT_TYPE_PRETTY; - } else if (rawType == Message.STREAM_TYPE) { - prettyType = XmlDataConstants.STREAM_TYPE_PRETTY; - } else if (rawType == Message.TEXT_TYPE) { - prettyType = XmlDataConstants.TEXT_TYPE_PRETTY; - } + String prettyType = XmlDataExporterUtil.getMessagePrettyType(message.getType()); xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_TYPE, prettyType); if (message.getUserID() != null) { xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_USER_ID, message.getUserID().toString()); @@ -597,10 +559,6 @@ public final class XmlDataExporter extends OptionalLocking { return queues; } - private static String encode(final byte[] data) { - return Base64.encodeBytes(data, 0, data.length, Base64.DONT_BREAK_LINES | Base64.URL_SAFE); - } - // Inner classes ------------------------------------------------- /** diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporterUtil.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporterUtil.java new file mode 100644 index 0000000000..8ee7678fe8 --- /dev/null +++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/tools/XmlDataExporterUtil.java @@ -0,0 +1,108 @@ +/* + * 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.cli.commands.tools; + +import com.google.common.base.Preconditions; + +import org.apache.activemq.artemis.api.core.Message; +import org.apache.activemq.artemis.api.core.SimpleString; +import org.apache.activemq.artemis.core.server.ServerMessage; +import org.apache.activemq.artemis.utils.Base64; + +/** + * Common utility methods to help with XML message conversion + */ +public class XmlDataExporterUtil { + + public static String convertProperty(final Object value) { + if (value instanceof byte[]) { + return encode((byte[]) value); + } else { + return value == null ? XmlDataConstants.NULL : value.toString(); + } + } + + public static String getPropertyType(final Object value) { + String stringValue = null; + + // if the value is null then we can't really know what it is so just set + // the type to the most generic thing + if (value == null) { + stringValue = XmlDataConstants.PROPERTY_TYPE_BYTES; + } else if (value instanceof Boolean) { + stringValue = XmlDataConstants.PROPERTY_TYPE_BOOLEAN; + } else if (value instanceof Byte) { + stringValue = XmlDataConstants.PROPERTY_TYPE_BYTE; + } else if (value instanceof Short) { + stringValue = XmlDataConstants.PROPERTY_TYPE_SHORT; + } else if (value instanceof Integer) { + stringValue = XmlDataConstants.PROPERTY_TYPE_INTEGER; + } else if (value instanceof Long) { + stringValue = XmlDataConstants.PROPERTY_TYPE_LONG; + } else if (value instanceof Float) { + stringValue = XmlDataConstants.PROPERTY_TYPE_FLOAT; + } else if (value instanceof Double) { + stringValue = XmlDataConstants.PROPERTY_TYPE_DOUBLE; + } else if (value instanceof String) { + stringValue = XmlDataConstants.PROPERTY_TYPE_STRING; + } else if (value instanceof SimpleString) { + stringValue = XmlDataConstants.PROPERTY_TYPE_SIMPLE_STRING; + } else if (value instanceof byte[]) { + stringValue = XmlDataConstants.PROPERTY_TYPE_BYTES; + } + + return stringValue; + } + + public static String getMessagePrettyType(byte rawType) { + String prettyType = XmlDataConstants.DEFAULT_TYPE_PRETTY; + + if (rawType == Message.BYTES_TYPE) { + prettyType = XmlDataConstants.BYTES_TYPE_PRETTY; + } else if (rawType == Message.MAP_TYPE) { + prettyType = XmlDataConstants.MAP_TYPE_PRETTY; + } else if (rawType == Message.OBJECT_TYPE) { + prettyType = XmlDataConstants.OBJECT_TYPE_PRETTY; + } else if (rawType == Message.STREAM_TYPE) { + prettyType = XmlDataConstants.STREAM_TYPE_PRETTY; + } else if (rawType == Message.TEXT_TYPE) { + prettyType = XmlDataConstants.TEXT_TYPE_PRETTY; + } + + return prettyType; + } + + /** + * Base64 encode a ServerMessage body into the proper XML format + * + * @param message + * @return + */ + public static String encodeMessageBody(final ServerMessage message) { + Preconditions.checkNotNull(message, "ServerMessage can not be null"); + + int size = message.getEndOfBodyPosition() - message.getBodyBuffer().readerIndex(); + byte[] buffer = new byte[size]; + message.getBodyBuffer().readBytes(buffer); + + return XmlDataExporterUtil.encode(buffer); + } + + protected static String encode(final byte[] data) { + return Base64.encodeBytes(data, 0, data.length, Base64.DONT_BREAK_LINES | Base64.URL_SAFE); + } +}