ARTEMIS-964 Moving shared XML logic

https://issues.apache.org/jira/browse/ARTEMIS-964

Moving XML conversion logic to a common XmlDataExporterUtil class so it
can be used elsewhere.
This commit is contained in:
Christopher L. Shannon (cshannon) 2017-02-14 11:09:44 -05:00
parent c0c4859215
commit 0fdf44fb62
3 changed files with 169 additions and 103 deletions

View File

@ -26,56 +26,56 @@ public final class XmlDataConstants {
// Utility // Utility
} }
static final String XML_VERSION = "1.0"; public static final String XML_VERSION = "1.0";
static final String DOCUMENT_PARENT = "activemq-journal"; public static final String DOCUMENT_PARENT = "activemq-journal";
static final String BINDINGS_PARENT = "bindings"; public static final String BINDINGS_PARENT = "bindings";
static final String QUEUE_BINDINGS_CHILD = "queue-binding"; public static final String QUEUE_BINDINGS_CHILD = "queue-binding";
static final String QUEUE_BINDING_ADDRESS = "address"; public static final String QUEUE_BINDING_ADDRESS = "address";
static final String QUEUE_BINDING_FILTER_STRING = "filter-string"; public static final String QUEUE_BINDING_FILTER_STRING = "filter-string";
static final String QUEUE_BINDING_NAME = "name"; public static final String QUEUE_BINDING_NAME = "name";
static final String QUEUE_BINDING_ID = "id"; public static final String QUEUE_BINDING_ID = "id";
static final String QUEUE_BINDING_ROUTING_TYPE = "routing-type"; public static final String QUEUE_BINDING_ROUTING_TYPE = "routing-type";
static final String ADDRESS_BINDINGS_CHILD = "address-binding"; public static final String ADDRESS_BINDINGS_CHILD = "address-binding";
static final String ADDRESS_BINDING_NAME = "name"; public static final String ADDRESS_BINDING_NAME = "name";
static final String ADDRESS_BINDING_ID = "id"; public static final String ADDRESS_BINDING_ID = "id";
static final String ADDRESS_BINDING_ROUTING_TYPE = "routing-types"; public static final String ADDRESS_BINDING_ROUTING_TYPE = "routing-types";
static final String MESSAGES_PARENT = "messages"; public static final String MESSAGES_PARENT = "messages";
static final String MESSAGES_CHILD = "message"; public static final String MESSAGES_CHILD = "message";
static final String MESSAGE_ID = "id"; public static final String MESSAGE_ID = "id";
static final String MESSAGE_PRIORITY = "priority"; public static final String MESSAGE_PRIORITY = "priority";
static final String MESSAGE_EXPIRATION = "expiration"; public static final String MESSAGE_EXPIRATION = "expiration";
static final String MESSAGE_TIMESTAMP = "timestamp"; public static final String MESSAGE_TIMESTAMP = "timestamp";
static final String DEFAULT_TYPE_PRETTY = "default"; public static final String DEFAULT_TYPE_PRETTY = "default";
static final String BYTES_TYPE_PRETTY = "bytes"; public static final String BYTES_TYPE_PRETTY = "bytes";
static final String MAP_TYPE_PRETTY = "map"; public static final String MAP_TYPE_PRETTY = "map";
static final String OBJECT_TYPE_PRETTY = "object"; public static final String OBJECT_TYPE_PRETTY = "object";
static final String STREAM_TYPE_PRETTY = "stream"; public static final String STREAM_TYPE_PRETTY = "stream";
static final String TEXT_TYPE_PRETTY = "text"; public static final String TEXT_TYPE_PRETTY = "text";
static final String MESSAGE_TYPE = "type"; public static final String MESSAGE_TYPE = "type";
static final String MESSAGE_IS_LARGE = "isLarge"; public static final String MESSAGE_IS_LARGE = "isLarge";
static final String MESSAGE_USER_ID = "user-id"; public static final String MESSAGE_USER_ID = "user-id";
static final String MESSAGE_BODY = "body"; public static final String MESSAGE_BODY = "body";
static final String PROPERTIES_PARENT = "properties"; public static final String PROPERTIES_PARENT = "properties";
static final String PROPERTIES_CHILD = "property"; public static final String PROPERTIES_CHILD = "property";
static final String PROPERTY_NAME = "name"; public static final String PROPERTY_NAME = "name";
static final String PROPERTY_VALUE = "value"; public static final String PROPERTY_VALUE = "value";
static final String PROPERTY_TYPE = "type"; public static final String PROPERTY_TYPE = "type";
static final String QUEUES_PARENT = "queues"; public static final String QUEUES_PARENT = "queues";
static final String QUEUES_CHILD = "queue"; public static final String QUEUES_CHILD = "queue";
static final String QUEUE_NAME = "name"; public static final String QUEUE_NAME = "name";
static final String PROPERTY_TYPE_BOOLEAN = "boolean"; public static final String PROPERTY_TYPE_BOOLEAN = "boolean";
static final String PROPERTY_TYPE_BYTE = "byte"; public static final String PROPERTY_TYPE_BYTE = "byte";
static final String PROPERTY_TYPE_BYTES = "bytes"; public static final String PROPERTY_TYPE_BYTES = "bytes";
static final String PROPERTY_TYPE_SHORT = "short"; public static final String PROPERTY_TYPE_SHORT = "short";
static final String PROPERTY_TYPE_INTEGER = "integer"; public static final String PROPERTY_TYPE_INTEGER = "integer";
static final String PROPERTY_TYPE_LONG = "long"; public static final String PROPERTY_TYPE_LONG = "long";
static final String PROPERTY_TYPE_FLOAT = "float"; public static final String PROPERTY_TYPE_FLOAT = "float";
static final String PROPERTY_TYPE_DOUBLE = "double"; public static final String PROPERTY_TYPE_DOUBLE = "double";
static final String PROPERTY_TYPE_STRING = "string"; public static final String PROPERTY_TYPE_STRING = "string";
static final String PROPERTY_TYPE_SIMPLE_STRING = "simple-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_NAME = "name";
static final String JMS_CONNECTION_FACTORY_CLIENT_ID = "client-id"; static final String JMS_CONNECTION_FACTORY_CLIENT_ID = "client-id";

View File

@ -16,9 +16,6 @@
*/ */
package org.apache.activemq.artemis.cli.commands.tools; 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.File;
import java.io.OutputStream; import java.io.OutputStream;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationHandler;
@ -36,7 +33,10 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; 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.ActiveMQBuffer;
import org.apache.activemq.artemis.api.core.ActiveMQBuffers; import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
import org.apache.activemq.artemis.api.core.ActiveMQException; 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.AddressSettings;
import org.apache.activemq.artemis.core.settings.impl.HierarchicalObjectRepository; import org.apache.activemq.artemis.core.settings.impl.HierarchicalObjectRepository;
import org.apache.activemq.artemis.utils.ActiveMQThreadFactory; 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.ExecutorFactory;
import org.apache.activemq.artemis.utils.OrderedExecutorFactory; 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.") @Command(name = "exp", description = "Export all message-data using an XML that could be interpreted by any system.")
public final class XmlDataExporter extends OptionalLocking { public final class XmlDataExporter extends OptionalLocking {
@ -471,11 +472,7 @@ public final class XmlDataExporter extends OptionalLocking {
if (message.isLargeMessage()) { if (message.isLargeMessage()) {
printLargeMessageBody((LargeServerMessage) message); printLargeMessageBody((LargeServerMessage) message);
} else { } else {
int size = message.getEndOfBodyPosition() - message.getBodyBuffer().readerIndex(); xmlWriter.writeCData(XmlDataExporterUtil.encodeMessageBody(message));
byte[] buffer = new byte[size];
message.getBodyBuffer().readBytes(buffer);
xmlWriter.writeCData(encode(buffer));
} }
xmlWriter.writeEndElement(); // end MESSAGE_BODY xmlWriter.writeEndElement(); // end MESSAGE_BODY
} }
@ -499,7 +496,7 @@ public final class XmlDataExporter extends OptionalLocking {
} }
ActiveMQBuffer buffer = ActiveMQBuffers.fixedBuffer(bufferSize.intValue()); ActiveMQBuffer buffer = ActiveMQBuffers.fixedBuffer(bufferSize.intValue());
encoder.encode(buffer, bufferSize.intValue()); encoder.encode(buffer, bufferSize.intValue());
xmlWriter.writeCData(encode(buffer.toByteBuffer().array())); xmlWriter.writeCData(XmlDataExporterUtil.encode(buffer.toByteBuffer().array()));
totalBytesWritten += bufferSize; totalBytesWritten += bufferSize;
} }
encoder.close(); encoder.close();
@ -531,35 +528,12 @@ public final class XmlDataExporter extends OptionalLocking {
Object value = message.getObjectProperty(key); Object value = message.getObjectProperty(key);
xmlWriter.writeEmptyElement(XmlDataConstants.PROPERTIES_CHILD); xmlWriter.writeEmptyElement(XmlDataConstants.PROPERTIES_CHILD);
xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_NAME, key.toString()); xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_NAME, key.toString());
if (value instanceof byte[]) { xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_VALUE, XmlDataExporterUtil.convertProperty(value));
xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_VALUE, encode((byte[]) value));
} else {
xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_VALUE, value == null ? XmlDataConstants.NULL : value.toString());
}
// if the value is null then we can't really know what it is so just set the type to the most generic thing // Write the property type as an attribute
if (value == null) { String propertyType = XmlDataExporterUtil.getPropertyType(value);
xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_BYTES); if (propertyType != null) {
} else if (value instanceof Boolean) { xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, propertyType);
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);
} }
} }
xmlWriter.writeEndElement(); // end PROPERTIES_PARENT 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_PRIORITY, Byte.toString(message.getPriority()));
xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_EXPIRATION, Long.toString(message.getExpiration())); xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_EXPIRATION, Long.toString(message.getExpiration()));
xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_TIMESTAMP, Long.toString(message.getTimestamp())); xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_TIMESTAMP, Long.toString(message.getTimestamp()));
byte rawType = message.getType(); String prettyType = XmlDataExporterUtil.getMessagePrettyType(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;
}
xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_TYPE, prettyType); xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_TYPE, prettyType);
if (message.getUserID() != null) { if (message.getUserID() != null) {
xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_USER_ID, message.getUserID().toString()); xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_USER_ID, message.getUserID().toString());
@ -597,10 +559,6 @@ public final class XmlDataExporter extends OptionalLocking {
return queues; 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 ------------------------------------------------- // Inner classes -------------------------------------------------
/** /**

View File

@ -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);
}
}