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
}
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";

View File

@ -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 -------------------------------------------------
/**

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