You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by an...@apache.org on 2016/07/20 09:35:37 UTC
[5/9] activemq-artemis git commit: ARTEMIS-637 Port 5.x AMQP test
client
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/df41a60e/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/IdGenerator.java
----------------------------------------------------------------------
diff --git a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/IdGenerator.java b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/IdGenerator.java
new file mode 100644
index 0000000..c662b59
--- /dev/null
+++ b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/IdGenerator.java
@@ -0,0 +1,274 @@
+/*
+ * 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.transport.amqp.client.util;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.UnknownHostException;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Generator for Globally unique Strings.
+ */
+public class IdGenerator {
+
+ private static final Logger LOG = LoggerFactory.getLogger(IdGenerator.class);
+ private static final String UNIQUE_STUB;
+ private static int instanceCount;
+ private static String hostName;
+ private String seed;
+ private final AtomicLong sequence = new AtomicLong(1);
+ private int length;
+ public static final String PROPERTY_IDGENERATOR_PORT = "activemq.idgenerator.port";
+
+ static {
+ String stub = "";
+ boolean canAccessSystemProps = true;
+ try {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPropertiesAccess();
+ }
+ }
+ catch (SecurityException se) {
+ canAccessSystemProps = false;
+ }
+
+ if (canAccessSystemProps) {
+ int idGeneratorPort = 0;
+ ServerSocket ss = null;
+ try {
+ idGeneratorPort = Integer.parseInt(System.getProperty(PROPERTY_IDGENERATOR_PORT, "0"));
+ LOG.trace("Using port {}", idGeneratorPort);
+ hostName = getLocalHostName();
+ ss = new ServerSocket(idGeneratorPort);
+ stub = "-" + ss.getLocalPort() + "-" + System.currentTimeMillis() + "-";
+ Thread.sleep(100);
+ }
+ catch (Exception e) {
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("could not generate unique stub by using DNS and binding to local port", e);
+ }
+ else {
+ LOG.warn("could not generate unique stub by using DNS and binding to local port: {} {}", e.getClass().getCanonicalName(), e.getMessage());
+ }
+
+ // Restore interrupted state so higher level code can deal with it.
+ if (e instanceof InterruptedException) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ finally {
+ if (ss != null) {
+ try {
+ ss.close();
+ }
+ catch (IOException ioe) {
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Closing the server socket failed", ioe);
+ }
+ else {
+ LOG.warn("Closing the server socket failed" + " due " + ioe.getMessage());
+ }
+ }
+ }
+ }
+ }
+
+ if (hostName == null) {
+ hostName = "localhost";
+ }
+ hostName = sanitizeHostName(hostName);
+
+ if (stub.length() == 0) {
+ stub = "-1-" + System.currentTimeMillis() + "-";
+ }
+ UNIQUE_STUB = stub;
+ }
+
+ /**
+ * Construct an IdGenerator
+ *
+ * @param prefix The prefix value that is applied to all generated IDs.
+ */
+ public IdGenerator(String prefix) {
+ synchronized (UNIQUE_STUB) {
+ this.seed = prefix + UNIQUE_STUB + (instanceCount++) + ":";
+ this.length = this.seed.length() + ("" + Long.MAX_VALUE).length();
+ }
+ }
+
+ public IdGenerator() {
+ this("ID:" + hostName);
+ }
+
+ /**
+ * As we have to find the host name as a side-affect of generating a unique stub, we allow
+ * it's easy retrieval here
+ *
+ * @return the local host name
+ */
+ public static String getHostName() {
+ return hostName;
+ }
+
+ /**
+ * Generate a unique id
+ *
+ * @return a unique id
+ */
+ public synchronized String generateId() {
+ StringBuilder sb = new StringBuilder(length);
+ sb.append(seed);
+ sb.append(sequence.getAndIncrement());
+ return sb.toString();
+ }
+
+ public static String sanitizeHostName(String hostName) {
+ boolean changed = false;
+
+ StringBuilder sb = new StringBuilder();
+ for (char ch : hostName.toCharArray()) {
+ // only include ASCII chars
+ if (ch < 127) {
+ sb.append(ch);
+ }
+ else {
+ changed = true;
+ }
+ }
+
+ if (changed) {
+ String newHost = sb.toString();
+ LOG.info("Sanitized hostname from: {} to: {}", hostName, newHost);
+ return newHost;
+ }
+ else {
+ return hostName;
+ }
+ }
+
+ /**
+ * Generate a unique ID - that is friendly for a URL or file system
+ *
+ * @return a unique id
+ */
+ public String generateSanitizedId() {
+ String result = generateId();
+ result = result.replace(':', '-');
+ result = result.replace('_', '-');
+ result = result.replace('.', '-');
+ return result;
+ }
+
+ /**
+ * From a generated id - return the seed (i.e. minus the count)
+ *
+ * @param id the generated identifier
+ * @return the seed
+ */
+ public static String getSeedFromId(String id) {
+ String result = id;
+ if (id != null) {
+ int index = id.lastIndexOf(':');
+ if (index > 0 && (index + 1) < id.length()) {
+ result = id.substring(0, index);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * From a generated id - return the generator count
+ *
+ * @param id The ID that will be parsed for a sequence number.
+ * @return the sequence value parsed from the given ID.
+ */
+ public static long getSequenceFromId(String id) {
+ long result = -1;
+ if (id != null) {
+ int index = id.lastIndexOf(':');
+
+ if (index > 0 && (index + 1) < id.length()) {
+ String numStr = id.substring(index + 1, id.length());
+ result = Long.parseLong(numStr);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Does a proper compare on the Id's
+ *
+ * @param id1 the lhs of the comparison.
+ * @param id2 the rhs of the comparison.
+ * @return 0 if equal else a positive if {@literal id1 > id2} ...
+ */
+ public static int compare(String id1, String id2) {
+ int result = -1;
+ String seed1 = IdGenerator.getSeedFromId(id1);
+ String seed2 = IdGenerator.getSeedFromId(id2);
+ if (seed1 != null && seed2 != null) {
+ result = seed1.compareTo(seed2);
+ if (result == 0) {
+ long count1 = IdGenerator.getSequenceFromId(id1);
+ long count2 = IdGenerator.getSequenceFromId(id2);
+ result = (int) (count1 - count2);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * When using the {@link java.net.InetAddress#getHostName()} method in an
+ * environment where neither a proper DNS lookup nor an <tt>/etc/hosts</tt>
+ * entry exists for a given host, the following exception will be thrown:
+ * <code>
+ * java.net.UnknownHostException: <hostname>: <hostname>
+ * at java.net.InetAddress.getLocalHost(InetAddress.java:1425)
+ * ...
+ * </code>
+ * Instead of just throwing an UnknownHostException and giving up, this
+ * method grabs a suitable hostname from the exception and prevents the
+ * exception from being thrown. If a suitable hostname cannot be acquired
+ * from the exception, only then is the <tt>UnknownHostException</tt> thrown.
+ *
+ * @return The hostname
+ * @throws UnknownHostException if the given host cannot be looked up.
+ * @see java.net.InetAddress#getLocalHost()
+ * @see java.net.InetAddress#getHostName()
+ */
+ protected static String getLocalHostName() throws UnknownHostException {
+ try {
+ return (InetAddress.getLocalHost()).getHostName();
+ }
+ catch (UnknownHostException uhe) {
+ String host = uhe.getMessage(); // host = "hostname: hostname"
+ if (host != null) {
+ int colon = host.indexOf(':');
+ if (colon > 0) {
+ return host.substring(0, colon);
+ }
+ }
+ throw uhe;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/df41a60e/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/NoOpAsyncResult.java
----------------------------------------------------------------------
diff --git a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/NoOpAsyncResult.java b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/NoOpAsyncResult.java
new file mode 100644
index 0000000..5dd4d12
--- /dev/null
+++ b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/NoOpAsyncResult.java
@@ -0,0 +1,40 @@
+/*
+ * 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.transport.amqp.client.util;
+
+/**
+ * Simple NoOp implementation used when the result of the operation does not matter.
+ */
+public class NoOpAsyncResult implements AsyncResult {
+
+ public static final NoOpAsyncResult INSTANCE = new NoOpAsyncResult();
+
+ @Override
+ public void onFailure(Throwable result) {
+
+ }
+
+ @Override
+ public void onSuccess() {
+
+ }
+
+ @Override
+ public boolean isComplete() {
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/df41a60e/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/PropertyUtil.java
----------------------------------------------------------------------
diff --git a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/PropertyUtil.java b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/PropertyUtil.java
new file mode 100644
index 0000000..1285a0f
--- /dev/null
+++ b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/PropertyUtil.java
@@ -0,0 +1,533 @@
+/*
+ * 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.transport.amqp.client.util;
+
+import javax.net.ssl.SSLContext;
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+
+/**
+ * Utilities for properties
+ */
+public class PropertyUtil {
+
+ /**
+ * Creates a URI from the original URI and the given parameters.
+ *
+ * @param originalURI The URI whose current parameters are removed and replaced with the given remainder value.
+ * @param params The URI params that should be used to replace the current ones in the target.
+ * @return a new URI that matches the original one but has its query options replaced with
+ * the given ones.
+ * @throws URISyntaxException if the given URI is invalid.
+ */
+ public static URI replaceQuery(URI originalURI, Map<String, String> params) throws URISyntaxException {
+ String s = createQueryString(params);
+ if (s.length() == 0) {
+ s = null;
+ }
+ return replaceQuery(originalURI, s);
+ }
+
+ /**
+ * Creates a URI with the given query, removing an previous query value from the given URI.
+ *
+ * @param uri The source URI whose existing query is replaced with the newly supplied one.
+ * @param query The new URI query string that should be appended to the given URI.
+ * @return a new URI that is a combination of the original URI and the given query string.
+ * @throws URISyntaxException if the given URI is invalid.
+ */
+ public static URI replaceQuery(URI uri, String query) throws URISyntaxException {
+ String schemeSpecificPart = uri.getRawSchemeSpecificPart();
+ // strip existing query if any
+ int questionMark = schemeSpecificPart.lastIndexOf("?");
+ // make sure question mark is not within parentheses
+ if (questionMark < schemeSpecificPart.lastIndexOf(")")) {
+ questionMark = -1;
+ }
+ if (questionMark > 0) {
+ schemeSpecificPart = schemeSpecificPart.substring(0, questionMark);
+ }
+ if (query != null && query.length() > 0) {
+ schemeSpecificPart += "?" + query;
+ }
+ return new URI(uri.getScheme(), schemeSpecificPart, uri.getFragment());
+ }
+
+ /**
+ * Creates a URI with the given query, removing an previous query value from the given URI.
+ *
+ * @param uri The source URI whose existing query is replaced with the newly supplied one.
+ * @return a new URI that is a combination of the original URI and the given query string.
+ * @throws URISyntaxException if the given URI is invalid.
+ */
+ public static URI eraseQuery(URI uri) throws URISyntaxException {
+ return replaceQuery(uri, (String) null);
+ }
+
+ /**
+ * Given a key / value mapping, create and return a URI formatted query string that is valid
+ * and can be appended to a URI.
+ *
+ * @param options The Mapping that will create the new Query string.
+ * @return a URI formatted query string.
+ * @throws URISyntaxException if the given URI is invalid.
+ */
+ public static String createQueryString(Map<String, ?> options) throws URISyntaxException {
+ try {
+ if (options.size() > 0) {
+ StringBuffer rc = new StringBuffer();
+ boolean first = true;
+ for (Entry<String, ?> entry : options.entrySet()) {
+ if (first) {
+ first = false;
+ }
+ else {
+ rc.append("&");
+ }
+ rc.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
+ rc.append("=");
+ rc.append(URLEncoder.encode((String) entry.getValue(), "UTF-8"));
+ }
+ return rc.toString();
+ }
+ else {
+ return "";
+ }
+ }
+ catch (UnsupportedEncodingException e) {
+ throw (URISyntaxException) new URISyntaxException(e.toString(), "Invalid encoding").initCause(e);
+ }
+ }
+
+ /**
+ * Get properties from a URI and return them in a new {@code Map<String, String>} instance.
+ *
+ * If the URI is null or the query string of the URI is null an empty Map is returned.
+ *
+ * @param uri the URI whose parameters are to be parsed.
+ * @return <Code>Map</Code> of properties
+ * @throws Exception if an error occurs while parsing the query options.
+ */
+ public static Map<String, String> parseParameters(URI uri) throws Exception {
+ if (uri == null || uri.getQuery() == null) {
+ return Collections.emptyMap();
+ }
+
+ return parseQuery(stripPrefix(uri.getQuery(), "?"));
+ }
+
+ /**
+ * Parse properties from a named resource -eg. a URI or a simple name e.g.
+ * {@literal foo?name="fred"&size=2}
+ *
+ * @param uri the URI whose parameters are to be parsed.
+ * @return <Code>Map</Code> of properties
+ * @throws Exception if an error occurs while parsing the query options.
+ */
+ public static Map<String, String> parseParameters(String uri) throws Exception {
+ if (uri == null) {
+ return Collections.emptyMap();
+ }
+
+ return parseQuery(stripUpto(uri, '?'));
+ }
+
+ /**
+ * Get properties from a URI query string.
+ *
+ * @param queryString the string value returned from a call to the URI class getQuery method.
+ * @return <Code>Map</Code> of properties from the parsed string.
+ * @throws Exception if an error occurs while parsing the query options.
+ */
+ public static Map<String, String> parseQuery(String queryString) throws Exception {
+ if (queryString != null && !queryString.isEmpty()) {
+ Map<String, String> rc = new HashMap<>();
+ String[] parameters = queryString.split("&");
+ for (int i = 0; i < parameters.length; i++) {
+ int p = parameters[i].indexOf("=");
+ if (p >= 0) {
+ String name = URLDecoder.decode(parameters[i].substring(0, p), "UTF-8");
+ String value = URLDecoder.decode(parameters[i].substring(p + 1), "UTF-8");
+ rc.put(name, value);
+ }
+ else {
+ rc.put(parameters[i], null);
+ }
+ }
+ return rc;
+ }
+
+ return Collections.emptyMap();
+ }
+
+ /**
+ * Given a map of properties, filter out only those prefixed with the given value, the
+ * values filtered are returned in a new Map instance.
+ *
+ * @param properties The map of properties to filter.
+ * @param optionPrefix The prefix value to use when filtering.
+ * @return a filter map with only values that match the given prefix.
+ */
+ public static Map<String, String> filterProperties(Map<String, String> properties, String optionPrefix) {
+ if (properties == null) {
+ throw new IllegalArgumentException("The given properties object was null.");
+ }
+
+ HashMap<String, String> rc = new HashMap<>(properties.size());
+
+ for (Iterator<Entry<String, String>> iter = properties.entrySet().iterator(); iter.hasNext(); ) {
+ Entry<String, String> entry = iter.next();
+ if (entry.getKey().startsWith(optionPrefix)) {
+ String name = entry.getKey().substring(optionPrefix.length());
+ rc.put(name, entry.getValue());
+ iter.remove();
+ }
+ }
+
+ return rc;
+ }
+
+ /**
+ * Enumerate the properties of the target object and add them as additional entries
+ * to the query string of the given string URI.
+ *
+ * @param uri The string URI value to append the object properties to.
+ * @param bean The Object whose properties will be added to the target URI.
+ * @return a new String value that is the original URI with the added bean properties.
+ * @throws Exception if an error occurs while enumerating the bean properties.
+ */
+ public static String addPropertiesToURIFromBean(String uri, Object bean) throws Exception {
+ Map<String, String> properties = PropertyUtil.getProperties(bean);
+ return PropertyUtil.addPropertiesToURI(uri, properties);
+ }
+
+ /**
+ * Enumerate the properties of the target object and add them as additional entries
+ * to the query string of the given URI.
+ *
+ * @param uri The URI value to append the object properties to.
+ * @param properties The Object whose properties will be added to the target URI.
+ * @return a new String value that is the original URI with the added bean properties.
+ * @throws Exception if an error occurs while enumerating the bean properties.
+ */
+ public static String addPropertiesToURI(URI uri, Map<String, String> properties) throws Exception {
+ return addPropertiesToURI(uri.toString(), properties);
+ }
+
+ /**
+ * Append the given properties to the query portion of the given URI.
+ *
+ * @param uri The string URI value to append the object properties to.
+ * @param properties The properties that will be added to the target URI.
+ * @return a new String value that is the original URI with the added properties.
+ * @throws Exception if an error occurs while building the new URI string.
+ */
+ public static String addPropertiesToURI(String uri, Map<String, String> properties) throws Exception {
+ String result = uri;
+ if (uri != null && properties != null) {
+ StringBuilder base = new StringBuilder(stripBefore(uri, '?'));
+ Map<String, String> map = parseParameters(uri);
+ if (!map.isEmpty()) {
+ map.putAll(properties);
+ }
+ else {
+ map = properties;
+ }
+ if (!map.isEmpty()) {
+ base.append('?');
+ boolean first = true;
+ for (Map.Entry<String, String> entry : map.entrySet()) {
+ if (!first) {
+ base.append('&');
+ }
+ first = false;
+ base.append(entry.getKey()).append("=").append(entry.getValue());
+ }
+ result = base.toString();
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Set properties on an object using the provided map. The return value
+ * indicates if all properties from the given map were set on the target object.
+ *
+ * @param target the object whose properties are to be set from the map options.
+ * @param properties the properties that should be applied to the given object.
+ * @return true if all values in the properties map were applied to the target object.
+ */
+ public static Map<String, String> setProperties(Object target, Map<String, String> properties) {
+ if (target == null) {
+ throw new IllegalArgumentException("target object cannot be null");
+ }
+ if (properties == null) {
+ throw new IllegalArgumentException("Given Properties object cannot be null");
+ }
+
+ Map<String, String> unmatched = new HashMap<>();
+
+ for (Map.Entry<String, String> entry : properties.entrySet()) {
+ if (!setProperty(target, entry.getKey(), entry.getValue())) {
+ unmatched.put(entry.getKey(), entry.getValue());
+ }
+ }
+
+ return Collections.unmodifiableMap(unmatched);
+ }
+
+ //TODO: common impl for above and below methods.
+
+ /**
+ * Set properties on an object using the provided Properties object. The return value
+ * indicates if all properties from the given map were set on the target object.
+ *
+ * @param target the object whose properties are to be set from the map options.
+ * @param properties the properties that should be applied to the given object.
+ * @return an unmodifiable map with any values that could not be applied to the target.
+ */
+ public static Map<String, Object> setProperties(Object target, Properties properties) {
+ if (target == null) {
+ throw new IllegalArgumentException("target object cannot be null");
+ }
+ if (properties == null) {
+ throw new IllegalArgumentException("Given Properties object cannot be null");
+ }
+
+ Map<String, Object> unmatched = new HashMap<>();
+
+ for (Map.Entry<Object, Object> entry : properties.entrySet()) {
+ if (!setProperty(target, (String) entry.getKey(), entry.getValue())) {
+ unmatched.put((String) entry.getKey(), entry.getValue());
+ }
+ }
+
+ return Collections.<String, Object>unmodifiableMap(unmatched);
+ }
+
+ /**
+ * Get properties from an object using reflection. If the passed object is null an
+ * empty <code>Map</code> is returned.
+ *
+ * @param object the Object whose properties are to be extracted.
+ * @return <Code>Map</Code> of properties extracted from the given object.
+ * @throws Exception if an error occurs while examining the object's properties.
+ */
+ public static Map<String, String> getProperties(Object object) throws Exception {
+ if (object == null) {
+ return Collections.emptyMap();
+ }
+
+ Map<String, String> properties = new LinkedHashMap<>();
+ BeanInfo beanInfo = Introspector.getBeanInfo(object.getClass());
+ Object[] NULL_ARG = {};
+ PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
+ if (propertyDescriptors != null) {
+ for (int i = 0; i < propertyDescriptors.length; i++) {
+ PropertyDescriptor pd = propertyDescriptors[i];
+ if (pd.getReadMethod() != null && !pd.getName().equals("class") && !pd.getName().equals("properties") && !pd.getName().equals("reference")) {
+ Object value = pd.getReadMethod().invoke(object, NULL_ARG);
+ if (value != null) {
+ if (value instanceof Boolean || value instanceof Number || value instanceof String || value instanceof URI || value instanceof URL) {
+ properties.put(pd.getName(), ("" + value));
+ }
+ else if (value instanceof SSLContext) {
+ // ignore this one..
+ }
+ else {
+ Map<String, String> inner = getProperties(value);
+ for (Map.Entry<String, String> entry : inner.entrySet()) {
+ properties.put(pd.getName() + "." + entry.getKey(), entry.getValue());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return properties;
+ }
+
+ /**
+ * Find a specific property getter in a given object based on a property name.
+ *
+ * @param object the object to search.
+ * @param name the property name to search for.
+ * @return the result of invoking the specific property get method.
+ * @throws Exception if an error occurs while searching the object's bean info.
+ */
+ public static Object getProperty(Object object, String name) throws Exception {
+ BeanInfo beanInfo = Introspector.getBeanInfo(object.getClass());
+ PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
+ if (propertyDescriptors != null) {
+ for (int i = 0; i < propertyDescriptors.length; i++) {
+ PropertyDescriptor pd = propertyDescriptors[i];
+ if (pd.getReadMethod() != null && pd.getName().equals(name)) {
+ return pd.getReadMethod().invoke(object);
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Set a property named property on a given Object.
+ * <p>
+ * The object is searched for an set method that would match the given named
+ * property and if one is found. If necessary an attempt will be made to convert
+ * the new value to an acceptable type.
+ *
+ * @param target The object whose property is to be set.
+ * @param name The name of the property to set.
+ * @param value The new value to set for the named property.
+ * @return true if the property was able to be set on the target object.
+ */
+ public static boolean setProperty(Object target, String name, Object value) {
+ try {
+ int dotPos = name.indexOf(".");
+ while (dotPos >= 0) {
+ String getterName = name.substring(0, dotPos);
+ target = getProperty(target, getterName);
+ name = name.substring(dotPos + 1);
+ dotPos = name.indexOf(".");
+ }
+
+ Class<?> clazz = target.getClass();
+ Method setter = findSetterMethod(clazz, name);
+ if (setter == null) {
+ return false;
+ }
+ // If the type is null or it matches the needed type, just use the
+ // value directly
+ if (value == null || value.getClass() == setter.getParameterTypes()[0]) {
+ setter.invoke(target, new Object[]{value});
+ }
+ else {
+ setter.invoke(target, new Object[]{convert(value, setter.getParameterTypes()[0])});
+ }
+ return true;
+ }
+ catch (Throwable ignore) {
+ return false;
+ }
+ }
+
+ /**
+ * Return a String minus the given prefix. If the string does not start
+ * with the given prefix the original string value is returned.
+ *
+ * @param value The String whose prefix is to be removed.
+ * @param prefix The prefix string to remove from the target string.
+ * @return stripped version of the original input string.
+ */
+ public static String stripPrefix(String value, String prefix) {
+ if (value != null && prefix != null && value.startsWith(prefix)) {
+ return value.substring(prefix.length());
+ }
+ return value;
+ }
+
+ /**
+ * Return a portion of a String value by looking beyond the given
+ * character.
+ *
+ * @param value The string value to split
+ * @param c The character that marks the split point.
+ * @return the sub-string value starting beyond the given character.
+ */
+ public static String stripUpto(String value, char c) {
+ String result = null;
+ if (value != null) {
+ int index = value.indexOf(c);
+ if (index > 0) {
+ result = value.substring(index + 1);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Return a String up to and including character
+ *
+ * @param value The string value to split
+ * @param c The character that marks the start of split point.
+ * @return the sub-string value starting from the given character.
+ */
+ public static String stripBefore(String value, char c) {
+ String result = value;
+ if (value != null) {
+ int index = value.indexOf(c);
+ if (index > 0) {
+ result = value.substring(0, index);
+ }
+ }
+ return result;
+ }
+
+ private static Method findSetterMethod(Class<?> clazz, String name) {
+ // Build the method name.
+ name = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
+ Method[] methods = clazz.getMethods();
+ for (int i = 0; i < methods.length; i++) {
+ Method method = methods[i];
+ Class<?>[] params = method.getParameterTypes();
+ if (method.getName().equals(name) && params.length == 1) {
+ return method;
+ }
+ }
+ return null;
+ }
+
+ private static Object convert(Object value, Class<?> type) throws Exception {
+ if (value == null) {
+ if (boolean.class.isAssignableFrom(type)) {
+ return Boolean.FALSE;
+ }
+ return null;
+ }
+
+ if (type.isAssignableFrom(value.getClass())) {
+ return type.cast(value);
+ }
+
+ // special for String[] as we do not want to use a PropertyEditor for that
+ if (type.isAssignableFrom(String[].class)) {
+ return StringArrayConverter.convertToStringArray(value);
+ }
+
+ if (type == URI.class) {
+ return new URI(value.toString());
+ }
+
+ return TypeConversionSupport.convert(value, type);
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/df41a60e/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/StringArrayConverter.java
----------------------------------------------------------------------
diff --git a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/StringArrayConverter.java b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/StringArrayConverter.java
new file mode 100644
index 0000000..3fc9eb4
--- /dev/null
+++ b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/StringArrayConverter.java
@@ -0,0 +1,64 @@
+/*
+ * 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.transport.amqp.client.util;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+/**
+ * Class for converting to/from String[] to be used instead of a
+ * {@link java.beans.PropertyEditor} which otherwise causes memory leaks as the
+ * JDK {@link java.beans.PropertyEditorManager} is a static class and has strong
+ * references to classes, causing problems in hot-deployment environments.
+ */
+public class StringArrayConverter {
+
+ public static String[] convertToStringArray(Object value) {
+ if (value == null) {
+ return null;
+ }
+
+ String text = value.toString();
+ if (text == null || text.isEmpty()) {
+ return null;
+ }
+
+ StringTokenizer stok = new StringTokenizer(text, ",");
+ final List<String> list = new ArrayList<>();
+
+ while (stok.hasMoreTokens()) {
+ list.add(stok.nextToken());
+ }
+
+ String[] array = list.toArray(new String[list.size()]);
+ return array;
+ }
+
+ public static String convertToString(String[] value) {
+ if (value == null || value.length == 0) {
+ return null;
+ }
+
+ StringBuffer result = new StringBuffer(String.valueOf(value[0]));
+ for (int i = 1; i < value.length; i++) {
+ result.append(",").append(value[i]);
+ }
+
+ return result.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/df41a60e/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/TypeConversionSupport.java
----------------------------------------------------------------------
diff --git a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/TypeConversionSupport.java b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/TypeConversionSupport.java
new file mode 100644
index 0000000..7d07551
--- /dev/null
+++ b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/TypeConversionSupport.java
@@ -0,0 +1,218 @@
+/**
+ * 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.transport.amqp.client.util;
+
+import java.util.Date;
+import java.util.HashMap;
+
+public final class TypeConversionSupport {
+
+ static class ConversionKey {
+
+ final Class<?> from;
+ final Class<?> to;
+ final int hashCode;
+
+ ConversionKey(Class<?> from, Class<?> to) {
+ this.from = from;
+ this.to = to;
+ this.hashCode = from.hashCode() ^ (to.hashCode() << 1);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (o == null || o.getClass() != this.getClass()) {
+ return false;
+ }
+
+ ConversionKey x = (ConversionKey) o;
+ return x.from == from && x.to == to;
+ }
+
+ @Override
+ public int hashCode() {
+ return hashCode;
+ }
+ }
+
+ interface Converter {
+
+ Object convert(Object value);
+ }
+
+ private static final HashMap<ConversionKey, Converter> CONVERSION_MAP = new HashMap<>();
+
+ static {
+ Converter toStringConverter = new Converter() {
+ @Override
+ public Object convert(Object value) {
+ return value.toString();
+ }
+ };
+ CONVERSION_MAP.put(new ConversionKey(Boolean.class, String.class), toStringConverter);
+ CONVERSION_MAP.put(new ConversionKey(Byte.class, String.class), toStringConverter);
+ CONVERSION_MAP.put(new ConversionKey(Short.class, String.class), toStringConverter);
+ CONVERSION_MAP.put(new ConversionKey(Integer.class, String.class), toStringConverter);
+ CONVERSION_MAP.put(new ConversionKey(Long.class, String.class), toStringConverter);
+ CONVERSION_MAP.put(new ConversionKey(Float.class, String.class), toStringConverter);
+ CONVERSION_MAP.put(new ConversionKey(Double.class, String.class), toStringConverter);
+
+ CONVERSION_MAP.put(new ConversionKey(String.class, Boolean.class), new Converter() {
+ @Override
+ public Object convert(Object value) {
+ return Boolean.valueOf((String) value);
+ }
+ });
+ CONVERSION_MAP.put(new ConversionKey(String.class, Byte.class), new Converter() {
+ @Override
+ public Object convert(Object value) {
+ return Byte.valueOf((String) value);
+ }
+ });
+ CONVERSION_MAP.put(new ConversionKey(String.class, Short.class), new Converter() {
+ @Override
+ public Object convert(Object value) {
+ return Short.valueOf((String) value);
+ }
+ });
+ CONVERSION_MAP.put(new ConversionKey(String.class, Integer.class), new Converter() {
+ @Override
+ public Object convert(Object value) {
+ return Integer.valueOf((String) value);
+ }
+ });
+ CONVERSION_MAP.put(new ConversionKey(String.class, Long.class), new Converter() {
+ @Override
+ public Object convert(Object value) {
+ return Long.valueOf((String) value);
+ }
+ });
+ CONVERSION_MAP.put(new ConversionKey(String.class, Float.class), new Converter() {
+ @Override
+ public Object convert(Object value) {
+ return Float.valueOf((String) value);
+ }
+ });
+ CONVERSION_MAP.put(new ConversionKey(String.class, Double.class), new Converter() {
+ @Override
+ public Object convert(Object value) {
+ return Double.valueOf((String) value);
+ }
+ });
+
+ Converter longConverter = new Converter() {
+ @Override
+ public Object convert(Object value) {
+ return Long.valueOf(((Number) value).longValue());
+ }
+ };
+ CONVERSION_MAP.put(new ConversionKey(Byte.class, Long.class), longConverter);
+ CONVERSION_MAP.put(new ConversionKey(Short.class, Long.class), longConverter);
+ CONVERSION_MAP.put(new ConversionKey(Integer.class, Long.class), longConverter);
+ CONVERSION_MAP.put(new ConversionKey(Date.class, Long.class), new Converter() {
+ @Override
+ public Object convert(Object value) {
+ return Long.valueOf(((Date) value).getTime());
+ }
+ });
+
+ Converter intConverter = new Converter() {
+ @Override
+ public Object convert(Object value) {
+ return Integer.valueOf(((Number) value).intValue());
+ }
+ };
+ CONVERSION_MAP.put(new ConversionKey(Byte.class, Integer.class), intConverter);
+ CONVERSION_MAP.put(new ConversionKey(Short.class, Integer.class), intConverter);
+
+ CONVERSION_MAP.put(new ConversionKey(Byte.class, Short.class), new Converter() {
+ @Override
+ public Object convert(Object value) {
+ return Short.valueOf(((Number) value).shortValue());
+ }
+ });
+
+ CONVERSION_MAP.put(new ConversionKey(Float.class, Double.class), new Converter() {
+ @Override
+ public Object convert(Object value) {
+ return new Double(((Number) value).doubleValue());
+ }
+ });
+ }
+
+ public static Object convert(Object value, Class<?> toClass) {
+
+ assert value != null && toClass != null;
+
+ if (value.getClass() == toClass) {
+ return value;
+ }
+
+ Class<?> fromClass = value.getClass();
+
+ if (fromClass.isPrimitive()) {
+ fromClass = convertPrimitiveTypeToWrapperType(fromClass);
+ }
+
+ if (toClass.isPrimitive()) {
+ toClass = convertPrimitiveTypeToWrapperType(toClass);
+ }
+
+ Converter c = CONVERSION_MAP.get(new ConversionKey(fromClass, toClass));
+ if (c == null) {
+ return null;
+ }
+
+ return c.convert(value);
+ }
+
+ private static Class<?> convertPrimitiveTypeToWrapperType(Class<?> type) {
+ Class<?> rc = type;
+ if (type.isPrimitive()) {
+ if (type == int.class) {
+ rc = Integer.class;
+ }
+ else if (type == long.class) {
+ rc = Long.class;
+ }
+ else if (type == double.class) {
+ rc = Double.class;
+ }
+ else if (type == float.class) {
+ rc = Float.class;
+ }
+ else if (type == short.class) {
+ rc = Short.class;
+ }
+ else if (type == byte.class) {
+ rc = Byte.class;
+ }
+ else if (type == boolean.class) {
+ rc = Boolean.class;
+ }
+ }
+
+ return rc;
+ }
+
+ private TypeConversionSupport() {
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/df41a60e/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableConnection.java
----------------------------------------------------------------------
diff --git a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableConnection.java b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableConnection.java
new file mode 100644
index 0000000..32003a4
--- /dev/null
+++ b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableConnection.java
@@ -0,0 +1,202 @@
+/**
+ * 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.transport.amqp.client.util;
+
+import java.util.EnumSet;
+import java.util.Map;
+
+import org.apache.qpid.proton.amqp.Symbol;
+import org.apache.qpid.proton.amqp.transport.ErrorCondition;
+import org.apache.qpid.proton.engine.Collector;
+import org.apache.qpid.proton.engine.Connection;
+import org.apache.qpid.proton.engine.Delivery;
+import org.apache.qpid.proton.engine.EndpointState;
+import org.apache.qpid.proton.engine.Link;
+import org.apache.qpid.proton.engine.Record;
+import org.apache.qpid.proton.engine.Session;
+import org.apache.qpid.proton.engine.Transport;
+import org.apache.qpid.proton.reactor.Reactor;
+
+/**
+ * Unmodifiable Connection wrapper used to prevent test code from accidentally
+ * modifying Connection state.
+ */
+public class UnmodifiableConnection implements Connection {
+
+ private final Connection connection;
+
+ public UnmodifiableConnection(Connection connection) {
+ this.connection = connection;
+ }
+
+ @Override
+ public EndpointState getLocalState() {
+ return connection.getLocalState();
+ }
+
+ @Override
+ public EndpointState getRemoteState() {
+ return connection.getRemoteState();
+ }
+
+ @Override
+ public ErrorCondition getCondition() {
+ return connection.getCondition();
+ }
+
+ @Override
+ public void setCondition(ErrorCondition condition) {
+ throw new UnsupportedOperationException("Cannot alter the Connection");
+ }
+
+ @Override
+ public ErrorCondition getRemoteCondition() {
+ return connection.getRemoteCondition();
+ }
+
+ @Override
+ public void free() {
+ throw new UnsupportedOperationException("Cannot alter the Connection");
+ }
+
+ @Override
+ public void open() {
+ throw new UnsupportedOperationException("Cannot alter the Connection");
+ }
+
+ @Override
+ public void close() {
+ throw new UnsupportedOperationException("Cannot alter the Connection");
+ }
+
+ @Override
+ public Session session() {
+ throw new UnsupportedOperationException("Cannot alter the Connection");
+ }
+
+ @Override
+ public Session sessionHead(EnumSet<EndpointState> local, EnumSet<EndpointState> remote) {
+ Session head = connection.sessionHead(local, remote);
+ if (head != null) {
+ head = new UnmodifiableSession(head);
+ }
+
+ return head;
+ }
+
+ @Override
+ public Link linkHead(EnumSet<EndpointState> local, EnumSet<EndpointState> remote) {
+ // TODO - If implemented this method should return an unmodifiable link isntance.
+ return null;
+ }
+
+ @Override
+ public Delivery getWorkHead() {
+ // TODO - If implemented this method should return an unmodifiable delivery isntance.
+ return null;
+ }
+
+ @Override
+ public void setContainer(String container) {
+ throw new UnsupportedOperationException("Cannot alter the Connection");
+ }
+
+ @Override
+ public void setHostname(String hostname) {
+ throw new UnsupportedOperationException("Cannot alter the Connection");
+ }
+
+ @Override
+ public String getHostname() {
+ return connection.getHostname();
+ }
+
+ @Override
+ public String getRemoteContainer() {
+ return connection.getRemoteContainer();
+ }
+
+ @Override
+ public String getRemoteHostname() {
+ return connection.getRemoteHostname();
+ }
+
+ @Override
+ public void setOfferedCapabilities(Symbol[] capabilities) {
+ throw new UnsupportedOperationException("Cannot alter the Connection");
+ }
+
+ @Override
+ public void setDesiredCapabilities(Symbol[] capabilities) {
+ throw new UnsupportedOperationException("Cannot alter the Connection");
+ }
+
+ @Override
+ public Symbol[] getRemoteOfferedCapabilities() {
+ return connection.getRemoteOfferedCapabilities();
+ }
+
+ @Override
+ public Symbol[] getRemoteDesiredCapabilities() {
+ return connection.getRemoteDesiredCapabilities();
+ }
+
+ @Override
+ public Map<Symbol, Object> getRemoteProperties() {
+ return connection.getRemoteProperties();
+ }
+
+ @Override
+ public void setProperties(Map<Symbol, Object> properties) {
+ throw new UnsupportedOperationException("Cannot alter the Connection");
+ }
+
+ @Override
+ public Object getContext() {
+ return connection.getContext();
+ }
+
+ @Override
+ public void setContext(Object context) {
+ throw new UnsupportedOperationException("Cannot alter the Connection");
+ }
+
+ @Override
+ public void collect(Collector collector) {
+ throw new UnsupportedOperationException("Cannot alter the Connection");
+ }
+
+ @Override
+ public String getContainer() {
+ return connection.getContainer();
+ }
+
+ @Override
+ public Transport getTransport() {
+ return new UnmodifiableTransport(connection.getTransport());
+ }
+
+ @Override
+ public Record attachments() {
+ return connection.attachments();
+ }
+
+ @Override
+ public Reactor getReactor() {
+ return connection.getReactor();
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/df41a60e/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableDelivery.java
----------------------------------------------------------------------
diff --git a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableDelivery.java b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableDelivery.java
new file mode 100644
index 0000000..9f48b41
--- /dev/null
+++ b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableDelivery.java
@@ -0,0 +1,170 @@
+/**
+ * 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.transport.amqp.client.util;
+
+import org.apache.qpid.proton.amqp.transport.DeliveryState;
+import org.apache.qpid.proton.engine.Delivery;
+import org.apache.qpid.proton.engine.Link;
+import org.apache.qpid.proton.engine.Receiver;
+import org.apache.qpid.proton.engine.Record;
+import org.apache.qpid.proton.engine.Sender;
+
+/**
+ * Unmodifiable Delivery wrapper used to prevent test code from accidentally
+ * modifying Delivery state.
+ */
+public class UnmodifiableDelivery implements Delivery {
+
+ private final Delivery delivery;
+
+ public UnmodifiableDelivery(Delivery delivery) {
+ this.delivery = delivery;
+ }
+
+ @Override
+ public byte[] getTag() {
+ return delivery.getTag();
+ }
+
+ @Override
+ public Link getLink() {
+ if (delivery.getLink() instanceof Sender) {
+ return new UnmodifiableSender((Sender) delivery.getLink());
+ }
+ else if (delivery.getLink() instanceof Receiver) {
+ return new UnmodifiableReceiver((Receiver) delivery.getLink());
+ }
+ else {
+ throw new IllegalStateException("Delivery has unknown link type");
+ }
+ }
+
+ @Override
+ public DeliveryState getLocalState() {
+ return delivery.getLocalState();
+ }
+
+ @Override
+ public DeliveryState getRemoteState() {
+ return delivery.getRemoteState();
+ }
+
+ @Override
+ public int getMessageFormat() {
+ return delivery.getMessageFormat();
+ }
+
+ @Override
+ public void disposition(DeliveryState state) {
+ throw new UnsupportedOperationException("Cannot alter the Delivery state");
+ }
+
+ @Override
+ public void settle() {
+ throw new UnsupportedOperationException("Cannot alter the Delivery state");
+ }
+
+ @Override
+ public boolean isSettled() {
+ return delivery.isSettled();
+ }
+
+ @Override
+ public boolean remotelySettled() {
+ return delivery.remotelySettled();
+ }
+
+ @Override
+ public void free() {
+ throw new UnsupportedOperationException("Cannot alter the Delivery state");
+ }
+
+ @Override
+ public Delivery getWorkNext() {
+ return new UnmodifiableDelivery(delivery.getWorkNext());
+ }
+
+ @Override
+ public Delivery next() {
+ return new UnmodifiableDelivery(delivery.next());
+ }
+
+ @Override
+ public boolean isWritable() {
+ return delivery.isWritable();
+ }
+
+ @Override
+ public boolean isReadable() {
+ return delivery.isReadable();
+ }
+
+ @Override
+ public void setContext(Object o) {
+ throw new UnsupportedOperationException("Cannot alter the Delivery state");
+ }
+
+ @Override
+ public Object getContext() {
+ return delivery.getContext();
+ }
+
+ @Override
+ public boolean isUpdated() {
+ return delivery.isUpdated();
+ }
+
+ @Override
+ public void clear() {
+ throw new UnsupportedOperationException("Cannot alter the Delivery state");
+ }
+
+ @Override
+ public boolean isPartial() {
+ return delivery.isPartial();
+ }
+
+ @Override
+ public int pending() {
+ return delivery.pending();
+ }
+
+ @Override
+ public boolean isBuffered() {
+ return delivery.isBuffered();
+ }
+
+ @Override
+ public Record attachments() {
+ return delivery.attachments();
+ }
+
+ @Override
+ public DeliveryState getDefaultDeliveryState() {
+ return delivery.getDefaultDeliveryState();
+ }
+
+ @Override
+ public void setDefaultDeliveryState(DeliveryState state) {
+ throw new UnsupportedOperationException("Cannot alter the Delivery");
+ }
+
+ @Override
+ public void setMessageFormat(int messageFormat) {
+ throw new UnsupportedOperationException("Cannot alter the Delivery");
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/df41a60e/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableLink.java
----------------------------------------------------------------------
diff --git a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableLink.java b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableLink.java
new file mode 100644
index 0000000..a58bfe7
--- /dev/null
+++ b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableLink.java
@@ -0,0 +1,276 @@
+/**
+ * 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.transport.amqp.client.util;
+
+import java.util.EnumSet;
+import java.util.Map;
+
+import org.apache.qpid.proton.amqp.Symbol;
+import org.apache.qpid.proton.amqp.transport.ErrorCondition;
+import org.apache.qpid.proton.amqp.transport.ReceiverSettleMode;
+import org.apache.qpid.proton.amqp.transport.SenderSettleMode;
+import org.apache.qpid.proton.amqp.transport.Source;
+import org.apache.qpid.proton.amqp.transport.Target;
+import org.apache.qpid.proton.engine.Delivery;
+import org.apache.qpid.proton.engine.EndpointState;
+import org.apache.qpid.proton.engine.Link;
+import org.apache.qpid.proton.engine.Receiver;
+import org.apache.qpid.proton.engine.Record;
+import org.apache.qpid.proton.engine.Sender;
+import org.apache.qpid.proton.engine.Session;
+
+/**
+ * Unmodifiable Session wrapper used to prevent test code from accidentally
+ * modifying Session state.
+ */
+public class UnmodifiableLink implements Link {
+
+ private final Link link;
+
+ public UnmodifiableLink(Link link) {
+ this.link = link;
+ }
+
+ @Override
+ public EndpointState getLocalState() {
+ return link.getLocalState();
+ }
+
+ @Override
+ public EndpointState getRemoteState() {
+ return link.getRemoteState();
+ }
+
+ @Override
+ public ErrorCondition getCondition() {
+ return link.getCondition();
+ }
+
+ @Override
+ public void setCondition(ErrorCondition condition) {
+ throw new UnsupportedOperationException("Cannot alter the Link state");
+ }
+
+ @Override
+ public ErrorCondition getRemoteCondition() {
+ return link.getRemoteCondition();
+ }
+
+ @Override
+ public void free() {
+ throw new UnsupportedOperationException("Cannot alter the Link state");
+ }
+
+ @Override
+ public void open() {
+ throw new UnsupportedOperationException("Cannot alter the Link state");
+ }
+
+ @Override
+ public void close() {
+ throw new UnsupportedOperationException("Cannot alter the Link state");
+ }
+
+ @Override
+ public void setContext(Object o) {
+ throw new UnsupportedOperationException("Cannot alter the Link state");
+ }
+
+ @Override
+ public Object getContext() {
+ return link.getContext();
+ }
+
+ @Override
+ public String getName() {
+ return link.getName();
+ }
+
+ @Override
+ public Delivery delivery(byte[] tag) {
+ throw new UnsupportedOperationException("Cannot alter the Link state");
+ }
+
+ @Override
+ public Delivery delivery(byte[] tag, int offset, int length) {
+ throw new UnsupportedOperationException("Cannot alter the Link state");
+ }
+
+ @Override
+ public Delivery head() {
+ return new UnmodifiableDelivery(link.head());
+ }
+
+ @Override
+ public Delivery current() {
+ return new UnmodifiableDelivery(link.current());
+ }
+
+ @Override
+ public boolean advance() {
+ throw new UnsupportedOperationException("Cannot alter the Link state");
+ }
+
+ @Override
+ public Source getSource() {
+ // TODO Figure out a simple way to wrap the odd Source types in Proton-J
+ return link.getSource();
+ }
+
+ @Override
+ public Target getTarget() {
+ // TODO Figure out a simple way to wrap the odd Source types in Proton-J
+ return link.getTarget();
+ }
+
+ @Override
+ public void setSource(Source address) {
+ throw new UnsupportedOperationException("Cannot alter the Link state");
+ }
+
+ @Override
+ public void setTarget(Target address) {
+ throw new UnsupportedOperationException("Cannot alter the Link state");
+ }
+
+ @Override
+ public Source getRemoteSource() {
+ // TODO Figure out a simple way to wrap the odd Source types in Proton-J
+ return link.getRemoteSource();
+ }
+
+ @Override
+ public Target getRemoteTarget() {
+ // TODO Figure out a simple way to wrap the odd Target types in Proton-J
+ return link.getRemoteTarget();
+ }
+
+ @Override
+ public Link next(EnumSet<EndpointState> local, EnumSet<EndpointState> remote) {
+ Link next = link.next(local, remote);
+
+ if (next != null) {
+ if (next instanceof Sender) {
+ next = new UnmodifiableSender((Sender) next);
+ }
+ else {
+ next = new UnmodifiableReceiver((Receiver) next);
+ }
+ }
+
+ return next;
+ }
+
+ @Override
+ public int getCredit() {
+ return link.getCredit();
+ }
+
+ @Override
+ public int getQueued() {
+ return link.getQueued();
+ }
+
+ @Override
+ public int getUnsettled() {
+ return link.getUnsettled();
+ }
+
+ @Override
+ public Session getSession() {
+ return new UnmodifiableSession(link.getSession());
+ }
+
+ @Override
+ public SenderSettleMode getSenderSettleMode() {
+ return link.getSenderSettleMode();
+ }
+
+ @Override
+ public void setSenderSettleMode(SenderSettleMode senderSettleMode) {
+ throw new UnsupportedOperationException("Cannot alter the Link state");
+ }
+
+ @Override
+ public SenderSettleMode getRemoteSenderSettleMode() {
+ return link.getRemoteSenderSettleMode();
+ }
+
+ @Override
+ public ReceiverSettleMode getReceiverSettleMode() {
+ return link.getReceiverSettleMode();
+ }
+
+ @Override
+ public void setReceiverSettleMode(ReceiverSettleMode receiverSettleMode) {
+ throw new UnsupportedOperationException("Cannot alter the Link state");
+ }
+
+ @Override
+ public ReceiverSettleMode getRemoteReceiverSettleMode() {
+ return link.getRemoteReceiverSettleMode();
+ }
+
+ @Override
+ public void setRemoteSenderSettleMode(SenderSettleMode remoteSenderSettleMode) {
+ throw new UnsupportedOperationException("Cannot alter the Link state");
+ }
+
+ @Override
+ public int drained() {
+ return link.drained(); // TODO - Is this a mutating call?
+ }
+
+ @Override
+ public int getRemoteCredit() {
+ return link.getRemoteCredit();
+ }
+
+ @Override
+ public boolean getDrain() {
+ return link.getDrain();
+ }
+
+ @Override
+ public void detach() {
+ throw new UnsupportedOperationException("Cannot alter the Link state");
+ }
+
+ @Override
+ public boolean detached() {
+ return link.detached();
+ }
+
+ public Record attachments() {
+ return link.attachments();
+ }
+
+ @Override
+ public Map<Symbol, Object> getProperties() {
+ return link.getProperties();
+ }
+
+ @Override
+ public void setProperties(Map<Symbol, Object> properties) {
+ throw new UnsupportedOperationException("Cannot alter the Link state");
+ }
+
+ @Override
+ public Map<Symbol, Object> getRemoteProperties() {
+ return link.getRemoteProperties();
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/df41a60e/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableReceiver.java
----------------------------------------------------------------------
diff --git a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableReceiver.java b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableReceiver.java
new file mode 100644
index 0000000..92760db
--- /dev/null
+++ b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableReceiver.java
@@ -0,0 +1,59 @@
+/**
+ * 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.transport.amqp.client.util;
+
+import org.apache.qpid.proton.engine.Receiver;
+
+/**
+ * Unmodifiable Receiver wrapper used to prevent test code from accidentally
+ * modifying Receiver state.
+ */
+public class UnmodifiableReceiver extends UnmodifiableLink implements Receiver {
+
+ private final Receiver receiver;
+
+ public UnmodifiableReceiver(Receiver receiver) {
+ super(receiver);
+
+ this.receiver = receiver;
+ }
+
+ @Override
+ public void flow(int credits) {
+ throw new UnsupportedOperationException("Cannot alter the Link state");
+ }
+
+ @Override
+ public int recv(byte[] bytes, int offset, int size) {
+ throw new UnsupportedOperationException("Cannot alter the Link state");
+ }
+
+ @Override
+ public void drain(int credit) {
+ throw new UnsupportedOperationException("Cannot alter the Link state");
+ }
+
+ @Override
+ public boolean draining() {
+ return receiver.draining();
+ }
+
+ @Override
+ public void setDrain(boolean drain) {
+ throw new UnsupportedOperationException("Cannot alter the Link state");
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/df41a60e/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableSender.java
----------------------------------------------------------------------
diff --git a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableSender.java b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableSender.java
new file mode 100644
index 0000000..89742cb
--- /dev/null
+++ b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableSender.java
@@ -0,0 +1,45 @@
+/**
+ * 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.transport.amqp.client.util;
+
+import org.apache.qpid.proton.engine.Sender;
+
+/**
+ * Unmodifiable Sender wrapper used to prevent test code from accidentally
+ * modifying Sender state.
+ */
+public class UnmodifiableSender extends UnmodifiableLink implements Sender {
+
+ public UnmodifiableSender(Sender sender) {
+ super(sender);
+ }
+
+ @Override
+ public void offer(int credits) {
+ throw new UnsupportedOperationException("Cannot alter the Link state");
+ }
+
+ @Override
+ public int send(byte[] bytes, int offset, int length) {
+ throw new UnsupportedOperationException("Cannot alter the Link state");
+ }
+
+ @Override
+ public void abort() {
+ throw new UnsupportedOperationException("Cannot alter the Link state");
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/df41a60e/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableSession.java
----------------------------------------------------------------------
diff --git a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableSession.java b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableSession.java
new file mode 100644
index 0000000..a44028e
--- /dev/null
+++ b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableSession.java
@@ -0,0 +1,150 @@
+/**
+ * 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.transport.amqp.client.util;
+
+import java.util.EnumSet;
+
+import org.apache.qpid.proton.amqp.transport.ErrorCondition;
+import org.apache.qpid.proton.engine.Connection;
+import org.apache.qpid.proton.engine.EndpointState;
+import org.apache.qpid.proton.engine.Receiver;
+import org.apache.qpid.proton.engine.Record;
+import org.apache.qpid.proton.engine.Sender;
+import org.apache.qpid.proton.engine.Session;
+
+/**
+ * Unmodifiable Session wrapper used to prevent test code from accidentally
+ * modifying Session state.
+ */
+public class UnmodifiableSession implements Session {
+
+ private final Session session;
+
+ public UnmodifiableSession(Session session) {
+ this.session = session;
+ }
+
+ @Override
+ public EndpointState getLocalState() {
+ return session.getLocalState();
+ }
+
+ @Override
+ public EndpointState getRemoteState() {
+ return session.getRemoteState();
+ }
+
+ @Override
+ public ErrorCondition getCondition() {
+ return session.getCondition();
+ }
+
+ @Override
+ public void setCondition(ErrorCondition condition) {
+ throw new UnsupportedOperationException("Cannot alter the Session");
+ }
+
+ @Override
+ public ErrorCondition getRemoteCondition() {
+ return session.getRemoteCondition();
+ }
+
+ @Override
+ public void free() {
+ throw new UnsupportedOperationException("Cannot alter the Session");
+ }
+
+ @Override
+ public void open() {
+ throw new UnsupportedOperationException("Cannot alter the Session");
+ }
+
+ @Override
+ public void close() {
+ throw new UnsupportedOperationException("Cannot alter the Session");
+ }
+
+ @Override
+ public void setContext(Object o) {
+ throw new UnsupportedOperationException("Cannot alter the Session");
+ }
+
+ @Override
+ public Object getContext() {
+ return session.getContext();
+ }
+
+ @Override
+ public Sender sender(String name) {
+ throw new UnsupportedOperationException("Cannot alter the Session");
+ }
+
+ @Override
+ public Receiver receiver(String name) {
+ throw new UnsupportedOperationException("Cannot alter the Session");
+ }
+
+ @Override
+ public Session next(EnumSet<EndpointState> local, EnumSet<EndpointState> remote) {
+ Session next = session.next(local, remote);
+ if (next != null) {
+ next = new UnmodifiableSession(next);
+ }
+
+ return next;
+ }
+
+ @Override
+ public Connection getConnection() {
+ return new UnmodifiableConnection(session.getConnection());
+ }
+
+ @Override
+ public int getIncomingCapacity() {
+ return session.getIncomingCapacity();
+ }
+
+ @Override
+ public void setIncomingCapacity(int bytes) {
+ throw new UnsupportedOperationException("Cannot alter the Session");
+ }
+
+ @Override
+ public int getIncomingBytes() {
+ return session.getIncomingBytes();
+ }
+
+ @Override
+ public int getOutgoingBytes() {
+ return session.getOutgoingBytes();
+ }
+
+ @Override
+ public Record attachments() {
+ return session.attachments();
+ }
+
+ @Override
+ public long getOutgoingWindow() {
+ return session.getOutgoingWindow();
+ }
+
+ @Override
+ public void setOutgoingWindow(long outgoingWindowSize) {
+ throw new UnsupportedOperationException("Cannot alter the Session");
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/df41a60e/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableTransport.java
----------------------------------------------------------------------
diff --git a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableTransport.java b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableTransport.java
new file mode 100644
index 0000000..5e305f4
--- /dev/null
+++ b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/UnmodifiableTransport.java
@@ -0,0 +1,274 @@
+/**
+ * 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.transport.amqp.client.util;
+
+import java.nio.ByteBuffer;
+
+import org.apache.qpid.proton.amqp.transport.ErrorCondition;
+import org.apache.qpid.proton.engine.Connection;
+import org.apache.qpid.proton.engine.EndpointState;
+import org.apache.qpid.proton.engine.Record;
+import org.apache.qpid.proton.engine.Sasl;
+import org.apache.qpid.proton.engine.Ssl;
+import org.apache.qpid.proton.engine.SslDomain;
+import org.apache.qpid.proton.engine.SslPeerDetails;
+import org.apache.qpid.proton.engine.Transport;
+import org.apache.qpid.proton.engine.TransportException;
+import org.apache.qpid.proton.engine.TransportResult;
+
+/**
+ * Unmodifiable Transport wrapper used to prevent test code from accidentally
+ * modifying Transport state.
+ */
+public class UnmodifiableTransport implements Transport {
+
+ private final Transport transport;
+
+ public UnmodifiableTransport(Transport transport) {
+ this.transport = transport;
+ }
+
+ @Override
+ public void close() {
+ throw new UnsupportedOperationException("Cannot alter the Transport");
+ }
+
+ @Override
+ public void free() {
+ throw new UnsupportedOperationException("Cannot alter the Transport");
+ }
+
+ @Override
+ public Object getContext() {
+ return null;
+ }
+
+ @Override
+ public EndpointState getLocalState() {
+ return transport.getLocalState();
+ }
+
+ @Override
+ public ErrorCondition getRemoteCondition() {
+ return transport.getRemoteCondition();
+ }
+
+ @Override
+ public EndpointState getRemoteState() {
+ return transport.getRemoteState();
+ }
+
+ @Override
+ public void open() {
+ throw new UnsupportedOperationException("Cannot alter the Transport");
+ }
+
+ @Override
+ public void setCondition(ErrorCondition arg0) {
+ throw new UnsupportedOperationException("Cannot alter the Transport");
+ }
+
+ @Override
+ public void setContext(Object arg0) {
+ throw new UnsupportedOperationException("Cannot alter the Transport");
+ }
+
+ @Override
+ public void bind(Connection arg0) {
+ throw new UnsupportedOperationException("Cannot alter the Transport");
+ }
+
+ @Override
+ public int capacity() {
+ return transport.capacity();
+ }
+
+ @Override
+ public void close_head() {
+ throw new UnsupportedOperationException("Cannot alter the Transport");
+ }
+
+ @Override
+ public void close_tail() {
+ throw new UnsupportedOperationException("Cannot alter the Transport");
+ }
+
+ @Override
+ public int getChannelMax() {
+ return transport.getChannelMax();
+ }
+
+ @Override
+ public ErrorCondition getCondition() {
+ return transport.getCondition();
+ }
+
+ @Override
+ public int getIdleTimeout() {
+ return transport.getIdleTimeout();
+ }
+
+ @Override
+ public ByteBuffer getInputBuffer() {
+ return null;
+ }
+
+ @Override
+ public int getMaxFrameSize() {
+ return transport.getMaxFrameSize();
+ }
+
+ @Override
+ public ByteBuffer getOutputBuffer() {
+ return null;
+ }
+
+ @Override
+ public int getRemoteChannelMax() {
+ return transport.getRemoteChannelMax();
+ }
+
+ @Override
+ public int getRemoteIdleTimeout() {
+ return transport.getRemoteIdleTimeout();
+ }
+
+ @Override
+ public int getRemoteMaxFrameSize() {
+ return transport.getRemoteMaxFrameSize();
+ }
+
+ @Override
+ public ByteBuffer head() {
+ return null;
+ }
+
+ @Override
+ public int input(byte[] arg0, int arg1, int arg2) {
+ throw new UnsupportedOperationException("Cannot alter the Transport");
+ }
+
+ @Override
+ public boolean isClosed() {
+ return transport.isClosed();
+ }
+
+ @Override
+ public int output(byte[] arg0, int arg1, int arg2) {
+ throw new UnsupportedOperationException("Cannot alter the Transport");
+ }
+
+ @Override
+ public void outputConsumed() {
+ throw new UnsupportedOperationException("Cannot alter the Transport");
+ }
+
+ @Override
+ public int pending() {
+ return transport.pending();
+ }
+
+ @Override
+ public void pop(int arg0) {
+ throw new UnsupportedOperationException("Cannot alter the Transport");
+ }
+
+ @Override
+ public void process() throws TransportException {
+ throw new UnsupportedOperationException("Cannot alter the Transport");
+ }
+
+ @Override
+ public TransportResult processInput() {
+ throw new UnsupportedOperationException("Cannot alter the Transport");
+ }
+
+ @Override
+ public Sasl sasl() throws IllegalStateException {
+ throw new UnsupportedOperationException("Cannot alter the Transport");
+ }
+
+ @Override
+ public void setChannelMax(int arg0) {
+ throw new UnsupportedOperationException("Cannot alter the Transport");
+ }
+
+ @Override
+ public void setIdleTimeout(int arg0) {
+ throw new UnsupportedOperationException("Cannot alter the Transport");
+ }
+
+ @Override
+ public void setMaxFrameSize(int arg0) {
+ throw new UnsupportedOperationException("Cannot alter the Transport");
+ }
+
+ @Override
+ public Ssl ssl(SslDomain arg0) {
+ throw new UnsupportedOperationException("Cannot alter the Transport");
+ }
+
+ @Override
+ public Ssl ssl(SslDomain arg0, SslPeerDetails arg1) {
+ throw new UnsupportedOperationException("Cannot alter the Transport");
+ }
+
+ @Override
+ public ByteBuffer tail() {
+ return null;
+ }
+
+ @Override
+ public long tick(long arg0) {
+ throw new UnsupportedOperationException("Cannot alter the Transport");
+ }
+
+ @Override
+ public void trace(int arg0) {
+ throw new UnsupportedOperationException("Cannot alter the Transport");
+ }
+
+ @Override
+ public void unbind() {
+ throw new UnsupportedOperationException("Cannot alter the Transport");
+ }
+
+ @Override
+ public Record attachments() {
+ return transport.attachments();
+ }
+
+ @Override
+ public long getFramesInput() {
+ return transport.getFramesInput();
+ }
+
+ @Override
+ public long getFramesOutput() {
+ return transport.getFramesOutput();
+ }
+
+ @Override
+ public void setEmitFlowEventOnSend(boolean emitFlowEventOnSend) {
+ throw new UnsupportedOperationException("Cannot alter the Transport");
+ }
+
+ @Override
+ public boolean isEmitFlowEventOnSend() {
+ return transport.isEmitFlowEventOnSend();
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/df41a60e/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/WrappedAsyncResult.java
----------------------------------------------------------------------
diff --git a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/WrappedAsyncResult.java b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/WrappedAsyncResult.java
new file mode 100644
index 0000000..bfe9a80
--- /dev/null
+++ b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/util/WrappedAsyncResult.java
@@ -0,0 +1,59 @@
+/**
+ * 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.transport.amqp.client.util;
+
+/**
+ * Base class used to wrap one AsyncResult with another.
+ */
+public abstract class WrappedAsyncResult implements AsyncResult {
+
+ protected final AsyncResult wrapped;
+
+ /**
+ * Create a new WrappedAsyncResult for the target AsyncResult
+ */
+ public WrappedAsyncResult(AsyncResult wrapped) {
+ this.wrapped = wrapped;
+ }
+
+ @Override
+ public void onFailure(Throwable result) {
+ if (wrapped != null) {
+ wrapped.onFailure(result);
+ }
+ }
+
+ @Override
+ public void onSuccess() {
+ if (wrapped != null) {
+ wrapped.onSuccess();
+ }
+ }
+
+ @Override
+ public boolean isComplete() {
+ if (wrapped != null) {
+ return wrapped.isComplete();
+ }
+
+ return false;
+ }
+
+ public AsyncResult getWrappedRequest() {
+ return wrapped;
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/df41a60e/tests/integration-tests/pom.xml
----------------------------------------------------------------------
diff --git a/tests/integration-tests/pom.xml b/tests/integration-tests/pom.xml
index 752e288..5d7617c 100644
--- a/tests/integration-tests/pom.xml
+++ b/tests/integration-tests/pom.xml
@@ -340,6 +340,11 @@
<artifactId>org.apache.karaf.shell.console</artifactId>
<version>${karaf.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.activemq.tests</groupId>
+ <artifactId>artemis-test-support</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
<build>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/df41a60e/tests/pom.xml
----------------------------------------------------------------------
diff --git a/tests/pom.xml b/tests/pom.xml
index 6a9c000..a2efeac 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -46,6 +46,13 @@
<version>1.2</version>
<!-- License: Apache: 2.0 -->
</dependency>
+ <dependency>
+ <groupId>org.apache.qpid</groupId>
+ <artifactId>qpid-jms-client</artifactId>
+ <version>0.10.0</version>
+ <!-- License: Apache: 2.0 -->
+ </dependency>
+
<!-- End JMS Dependencies -->
</dependencies>
</dependencyManagement>
@@ -122,5 +129,6 @@
<module>soak-tests</module>
<module>stress-tests</module>
<module>performance-tests</module>
+ <module>artemis-test-support</module>
</modules>
</project>