You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ta...@apache.org on 2014/09/23 20:20:38 UTC
[14/27] Initial drop of donated AMQP Client Code.
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/StopWatch.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/StopWatch.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/StopWatch.java
new file mode 100644
index 0000000..72c871d
--- /dev/null
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/StopWatch.java
@@ -0,0 +1,79 @@
+/**
+ * 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.qpid.jms.util;
+
+/**
+ * A very simple stop watch.
+ * <p/>
+ * This implementation is not thread safe and can only time one task at any given time.
+ */
+public final class StopWatch {
+
+ private long start;
+ private long stop;
+
+ /**
+ * Starts the stop watch
+ */
+ public StopWatch() {
+ this(true);
+ }
+
+ /**
+ * Creates the stop watch
+ *
+ * @param started whether it should start immediately
+ */
+ public StopWatch(boolean started) {
+ if (started) {
+ restart();
+ }
+ }
+
+ /**
+ * Starts or restarts the stop watch
+ */
+ public void restart() {
+ start = System.currentTimeMillis();
+ stop = 0;
+ }
+
+ /**
+ * Stops the stop watch
+ *
+ * @return the time taken in millis.
+ */
+ public long stop() {
+ stop = System.currentTimeMillis();
+ return taken();
+ }
+
+ /**
+ * Returns the time taken in millis.
+ *
+ * @return time in millis
+ */
+ public long taken() {
+ if (start > 0 && stop > 0) {
+ return stop - start;
+ } else if (start > 0) {
+ return System.currentTimeMillis() - start;
+ } else {
+ return 0;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/ThreadPoolUtils.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/ThreadPoolUtils.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/ThreadPoolUtils.java
new file mode 100644
index 0000000..71ae92e
--- /dev/null
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/ThreadPoolUtils.java
@@ -0,0 +1,190 @@
+/**
+ * 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.qpid.jms.util;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Utility methods for working with thread pools {@link ExecutorService}.
+ */
+public final class ThreadPoolUtils {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ThreadPoolUtils.class);
+
+ public static final long DEFAULT_SHUTDOWN_AWAIT_TERMINATION = 10 * 1000L;
+
+ /**
+ * Shutdown the given executor service only (ie not graceful shutdown).
+ *
+ * @see java.util.concurrent.ExecutorService#shutdown()
+ */
+ public static void shutdown(ExecutorService executorService) {
+ doShutdown(executorService, 0);
+ }
+
+ /**
+ * Shutdown now the given executor service aggressively.
+ *
+ * @param executorService
+ * the executor service to shutdown now
+ * @return list of tasks that never commenced execution
+ * @see java.util.concurrent.ExecutorService#shutdownNow()
+ */
+ public static List<Runnable> shutdownNow(ExecutorService executorService) {
+ if (executorService == null) {
+ return Collections.emptyList();
+ }
+
+ List<Runnable> answer = null;
+ if (!executorService.isShutdown()) {
+ LOG.debug("Forcing shutdown of ExecutorService: {}", executorService);
+ answer = executorService.shutdownNow();
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Shutdown of ExecutorService: {} is shutdown: {} and terminated: {}.",
+ new Object[] { executorService, executorService.isShutdown(), executorService.isTerminated() });
+ }
+ }
+
+ return answer;
+ }
+
+ /**
+ * Shutdown the given executor service graceful at first, and then aggressively if the await
+ * termination timeout was hit.
+ * <p/>
+ * This implementation invokes the
+ * {@link #shutdownGraceful(java.util.concurrent.ExecutorService, long)} with a timeout
+ * value of {@link #DEFAULT_SHUTDOWN_AWAIT_TERMINATION} millis.
+ */
+ public static void shutdownGraceful(ExecutorService executorService) {
+ doShutdown(executorService, DEFAULT_SHUTDOWN_AWAIT_TERMINATION);
+ }
+
+ /**
+ * Shutdown the given executor service graceful at first, and then aggressively if the await
+ * termination timeout was hit.
+ * <p/>
+ * Will try to perform an orderly shutdown by giving the running threads time to complete
+ * tasks, before going more aggressively by doing a
+ * {@link #shutdownNow(java.util.concurrent.ExecutorService)} which forces a shutdown. The
+ * parameter <tt>shutdownAwaitTermination</tt> is used as timeout value waiting for orderly
+ * shutdown to complete normally, before going aggressively.
+ *
+ * @param executorService
+ * the executor service to shutdown
+ * @param shutdownAwaitTermination
+ * timeout in millis to wait for orderly shutdown
+ */
+ public static void shutdownGraceful(ExecutorService executorService, long shutdownAwaitTermination) {
+ doShutdown(executorService, shutdownAwaitTermination);
+ }
+
+ private static void doShutdown(ExecutorService executorService, long shutdownAwaitTermination) {
+ if (executorService == null) {
+ return;
+ }
+
+ // shutting down a thread pool is a 2 step process. First we try graceful, and if
+ // that fails, then we go more aggressively and try shutting down again. In both
+ // cases we wait at most the given shutdown timeout value given
+ //
+ // total wait could then be 2 x shutdownAwaitTermination, but when we shutdown the
+ // 2nd time we are aggressive and thus we ought to shutdown much faster
+ if (!executorService.isShutdown()) {
+ boolean warned = false;
+ StopWatch watch = new StopWatch();
+
+ LOG.trace("Shutdown of ExecutorService: {} with await termination: {} millis", executorService, shutdownAwaitTermination);
+ executorService.shutdown();
+
+ if (shutdownAwaitTermination > 0) {
+ try {
+ if (!awaitTermination(executorService, shutdownAwaitTermination)) {
+ warned = true;
+ LOG.warn("Forcing shutdown of ExecutorService: {} due first await termination elapsed.", executorService);
+ executorService.shutdownNow();
+ // we are now shutting down aggressively, so wait to see
+ // if we can completely shutdown or not
+ if (!awaitTermination(executorService, shutdownAwaitTermination)) {
+ LOG.warn("Cannot completely force shutdown of ExecutorService: {} due second await termination elapsed.", executorService);
+ }
+ }
+ } catch (InterruptedException e) {
+ warned = true;
+ LOG.warn("Forcing shutdown of ExecutorService: {} due interrupted.", executorService);
+ // we were interrupted during shutdown, so force shutdown
+ executorService.shutdownNow();
+ }
+ }
+
+ // if we logged at WARN level, then report at INFO level when we are
+ // complete so the end user can see this in the log
+ if (warned) {
+ LOG.info("Shutdown of ExecutorService: {} is shutdown: {} and terminated: {} took: {}.",
+ new Object[] { executorService, executorService.isShutdown(), executorService.isTerminated(), TimeUtils.printDuration(watch.taken()) });
+ } else if (LOG.isDebugEnabled()) {
+ LOG.debug("Shutdown of ExecutorService: {} is shutdown: {} and terminated: {} took: {}.",
+ new Object[] { executorService, executorService.isShutdown(), executorService.isTerminated(), TimeUtils.printDuration(watch.taken()) });
+ }
+ }
+ }
+
+ /**
+ * Awaits the termination of the thread pool.
+ * <p/>
+ * This implementation will log every 2nd second at INFO level that we are waiting, so the
+ * end user can see we are not hanging in case it takes longer time to terminate the pool.
+ *
+ * @param executorService
+ * the thread pool
+ * @param shutdownAwaitTermination
+ * time in millis to use as timeout
+ *
+ * @return <tt>true</tt> if the pool is terminated, or <tt>false</tt> if we timed out
+ *
+ * @throws InterruptedException
+ * is thrown if we are interrupted during the waiting
+ */
+ public static boolean awaitTermination(ExecutorService executorService, long shutdownAwaitTermination) throws InterruptedException {
+
+ if (executorService == null) {
+ return true;
+ }
+
+ // log progress every 5th second so end user is aware of we are shutting down
+ StopWatch watch = new StopWatch();
+ long interval = Math.min(2000, shutdownAwaitTermination);
+ boolean done = false;
+ while (!done && interval > 0) {
+ if (executorService.awaitTermination(interval, TimeUnit.MILLISECONDS)) {
+ done = true;
+ } else {
+ LOG.info("Waited {} for ExecutorService: {} to terminate...", TimeUtils.printDuration(watch.taken()), executorService);
+ // recalculate interval
+ interval = Math.min(2000, shutdownAwaitTermination - watch.taken());
+ }
+ }
+
+ return done;
+ }
+}
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/TimeUtils.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/TimeUtils.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/TimeUtils.java
new file mode 100644
index 0000000..979d2f0
--- /dev/null
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/TimeUtils.java
@@ -0,0 +1,73 @@
+/**
+ * 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.qpid.jms.util;
+
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
+import java.util.Locale;
+
+/**
+ * Time utils.
+ */
+public final class TimeUtils {
+
+ private TimeUtils() {
+ }
+
+ /**
+ * Prints the duration in a human readable format as X days Y hours Z minutes etc.
+ *
+ * @param uptime
+ * the uptime in millis
+ * @return the time used for displaying on screen or in logs
+ */
+ public static String printDuration(double uptime) {
+
+ NumberFormat fmtI = new DecimalFormat("###,###", new DecimalFormatSymbols(Locale.ENGLISH));
+ NumberFormat fmtD = new DecimalFormat("###,##0.000", new DecimalFormatSymbols(Locale.ENGLISH));
+
+ uptime /= 1000;
+ if (uptime < 60) {
+ return fmtD.format(uptime) + " seconds";
+ }
+ uptime /= 60;
+ if (uptime < 60) {
+ long minutes = (long) uptime;
+ String s = fmtI.format(minutes) + (minutes > 1 ? " minutes" : " minute");
+ return s;
+ }
+ uptime /= 60;
+ if (uptime < 24) {
+ long hours = (long) uptime;
+ long minutes = (long) ((uptime - hours) * 60);
+ String s = fmtI.format(hours) + (hours > 1 ? " hours" : " hour");
+ if (minutes != 0) {
+ s += " " + fmtI.format(minutes) + (minutes > 1 ? " minutes" : " minute");
+ }
+ return s;
+ }
+ uptime /= 24;
+ long days = (long) uptime;
+ long hours = (long) ((uptime - days) * 24);
+ String s = fmtI.format(days) + (days > 1 ? " days" : " day");
+ if (hours != 0) {
+ s += " " + fmtI.format(hours) + (hours > 1 ? " hours" : " hour");
+ }
+ return s;
+ }
+}
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/ToStringSupport.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/ToStringSupport.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/ToStringSupport.java
new file mode 100644
index 0000000..6ed6a3a
--- /dev/null
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/ToStringSupport.java
@@ -0,0 +1,125 @@
+/**
+ * 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.qpid.jms.util;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class ToStringSupport {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ToStringSupport.class);
+
+ private ToStringSupport() {
+ }
+
+ public static String toString(Object target) {
+ return toString(target, Object.class, null);
+ }
+
+ @SuppressWarnings({ "rawtypes" })
+ public static String toString(Object target, Class stopClass) {
+ return toString(target, stopClass, null);
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public static String toString(Object target, Class stopClass, Map<String, Object> overrideFields) {
+ LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
+ addFields(target, target.getClass(), stopClass, map);
+ if (overrideFields != null) {
+ for(String key : overrideFields.keySet()) {
+ Object value = overrideFields.get(key);
+ map.put(key, value);
+ }
+
+ }
+ StringBuffer buffer = new StringBuffer(simpleName(target.getClass()));
+ buffer.append(" {");
+ Set<Entry<String, Object>> entrySet = map.entrySet();
+ boolean first = true;
+ for (Map.Entry<String,Object> entry : entrySet) {
+ Object value = entry.getValue();
+ Object key = entry.getKey();
+ if (first) {
+ first = false;
+ } else {
+ buffer.append(", ");
+ }
+ buffer.append(key);
+ buffer.append(" = ");
+
+ appendToString(buffer, key, value);
+ }
+ buffer.append("}");
+ return buffer.toString();
+ }
+
+ protected static void appendToString(StringBuffer buffer, Object key, Object value) {
+ if (key.toString().toLowerCase(Locale.ENGLISH).contains("password")){
+ buffer.append("*****");
+ } else {
+ buffer.append(value);
+ }
+ }
+
+ public static String simpleName(Class<?> clazz) {
+ String name = clazz.getName();
+ int p = name.lastIndexOf(".");
+ if (p >= 0) {
+ name = name.substring(p + 1);
+ }
+ return name;
+ }
+
+ @SuppressWarnings({ "rawtypes" })
+ private static void addFields(Object target, Class startClass, Class<Object> stopClass, LinkedHashMap<String, Object> map) {
+
+ if (startClass != stopClass) {
+ addFields(target, startClass.getSuperclass(), stopClass, map);
+ }
+
+ Field[] fields = startClass.getDeclaredFields();
+ for (Field field : fields) {
+ if (Modifier.isStatic(field.getModifiers()) || Modifier.isTransient(field.getModifiers())
+ || Modifier.isPrivate(field.getModifiers())) {
+ continue;
+ }
+
+ try {
+ field.setAccessible(true);
+ Object o = field.get(target);
+ if (o != null && o.getClass().isArray()) {
+ try {
+ o = Arrays.asList((Object[])o);
+ } catch (Exception e) {
+ }
+ }
+ map.put(field.getName(), o);
+ } catch (Exception e) {
+ LOG.debug("Error getting field " + field + " on class " + startClass + ". This exception is ignored.", e);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/TypeConversionSupport.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/TypeConversionSupport.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/TypeConversionSupport.java
new file mode 100644
index 0000000..08c378c
--- /dev/null
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/TypeConversionSupport.java
@@ -0,0 +1,180 @@
+/**
+ * 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.qpid.jms.util;
+
+import java.util.Date;
+import java.util.HashMap;
+
+import org.apache.qpid.jms.JmsDestination;
+import org.apache.qpid.jms.JmsQueue;
+
+public final class TypeConversionSupport {
+
+ static class ConversionKey {
+ final Class<?> from;
+ final Class<?> to;
+ final int hashCode;
+
+ public ConversionKey(Class<?> from, Class<?> to) {
+ this.from = from;
+ this.to = to;
+ this.hashCode = from.hashCode() ^ (to.hashCode() << 1);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ 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<ConversionKey, Converter>();
+
+ 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());
+ }
+ });
+
+ CONVERSION_MAP.put(new ConversionKey(String.class, JmsDestination.class), new Converter() {
+ @Override
+ public Object convert(Object value) {
+ // TODO - Right now we go right to a Queue, we need to examine the name
+ // and correctly map to the appropriate destination type.
+ return new JmsQueue(value.toString());
+ }
+ });
+ }
+
+ private TypeConversionSupport() {
+ }
+
+ public static Object convert(Object value, Class<?> clazz) {
+
+ assert value != null && clazz != null;
+
+ if (value.getClass() == clazz) {
+ return value;
+ }
+
+ Converter c = CONVERSION_MAP.get(new ConversionKey(value.getClass(), clazz));
+ if (c == null) {
+ return null;
+ }
+ return c.convert(value);
+ }
+}
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/URISupport.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/URISupport.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/URISupport.java
new file mode 100644
index 0000000..0a649f3
--- /dev/null
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/URISupport.java
@@ -0,0 +1,430 @@
+/**
+ * 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.qpid.jms.util;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Provides support methods for dealing with URI values.
+ */
+public class URISupport {
+
+ /**
+ * A composite URI can be split into one or more CompositeData object which each represent
+ * the individual URIs that comprise the composite one.
+ */
+ public static class CompositeData {
+ private String host;
+ private String scheme;
+ private String path;
+ private URI components[];
+ private Map<String, String> parameters;
+ private String fragment;
+
+ public URI[] getComponents() {
+ return components;
+ }
+
+ public String getFragment() {
+ return fragment;
+ }
+
+ public Map<String, String> getParameters() {
+ return parameters;
+ }
+
+ public String getScheme() {
+ return scheme;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public String getHost() {
+ return host;
+ }
+
+ public URI toURI() throws URISyntaxException {
+ StringBuffer sb = new StringBuffer();
+ if (scheme != null) {
+ sb.append(scheme);
+ sb.append(':');
+ }
+
+ if (host != null && host.length() != 0) {
+ sb.append(host);
+ } else {
+ sb.append('(');
+ for (int i = 0; i < components.length; i++) {
+ if (i != 0) {
+ sb.append(',');
+ }
+ sb.append(components[i].toString());
+ }
+ sb.append(')');
+ }
+
+ if (path != null) {
+ sb.append('/');
+ sb.append(path);
+ }
+ if (!parameters.isEmpty()) {
+ sb.append("?");
+ sb.append(PropertyUtil.createQueryString(parameters));
+ }
+ if (fragment != null) {
+ sb.append("#");
+ sb.append(fragment);
+ }
+ return new URI(sb.toString());
+ }
+ }
+
+ /**
+ * Given a composite URI, parse the individual URI elements contained within that URI and
+ * return a CompsoteData instance that contains the parsed URI values.
+ *
+ * @param uri
+ * The target URI that should be parsed.
+ *
+ * @return a new CompsiteData instance representing the parsed composite URI.
+ * @throws URISyntaxException
+ */
+ public static CompositeData parseComposite(URI uri) throws URISyntaxException {
+
+ CompositeData rc = new CompositeData();
+ rc.scheme = uri.getScheme();
+ String ssp = PropertyUtil.stripPrefix(uri.getRawSchemeSpecificPart().trim(), "//").trim();
+
+ try {
+ parseComposite(uri, rc, ssp);
+ } catch (Exception e) {
+ throw new URISyntaxException(uri.toString(), e.getMessage());
+ }
+
+ rc.fragment = uri.getFragment();
+ return rc;
+ }
+
+ /**
+ * Given a composite URI and a CompositeData instance and the scheme specific part extracted
+ * from the source URI, parse the composite URI and populate the CompositeData object with
+ * the results. The source URI is used only for logging as the ssp should have already been
+ * extracted from it and passed here.
+ *
+ * @param uri
+ * The original source URI whose ssp is parsed into the composite data.
+ * @param rc
+ * The CompsositeData instance that will be populated from the given ssp.
+ * @param ssp
+ * The scheme specific part from the original string that is a composite or one or
+ * more URIs.
+ *
+ * @throws URISyntaxException
+ */
+ private static void parseComposite(URI uri, CompositeData rc, String ssp) throws Exception {
+ String componentString;
+ String params;
+
+ if (!checkParenthesis(ssp)) {
+ throw new URISyntaxException(uri.toString(), "Not a matching number of '(' and ')' parenthesis");
+ }
+
+ int p;
+ int initialParen = ssp.indexOf("(");
+ if (initialParen == 0) {
+
+ rc.host = ssp.substring(0, initialParen);
+ p = rc.host.indexOf("/");
+
+ if (p >= 0) {
+ rc.path = rc.host.substring(p);
+ rc.host = rc.host.substring(0, p);
+ }
+
+ p = indexOfParenthesisMatch(ssp, initialParen);
+ componentString = ssp.substring(initialParen + 1, p);
+ params = ssp.substring(p + 1).trim();
+
+ } else {
+ componentString = ssp;
+ params = "";
+ }
+
+ String components[] = splitComponents(componentString);
+ rc.components = new URI[components.length];
+ for (int i = 0; i < components.length; i++) {
+ rc.components[i] = new URI(components[i].trim());
+ }
+
+ p = params.indexOf("?");
+ if (p >= 0) {
+ if (p > 0) {
+ rc.path = PropertyUtil.stripPrefix(params.substring(0, p), "/");
+ }
+ rc.parameters = PropertyUtil.parseQuery(params.substring(p + 1));
+ } else {
+ if (params.length() > 0) {
+ rc.path = PropertyUtil.stripPrefix(params, "/");
+ }
+ rc.parameters = Collections.emptyMap();
+ }
+ }
+
+ /**
+ * Examine a URI and determine if it is a Composite type or not.
+ *
+ * @param uri
+ * The URI that is to be examined.
+ *
+ * @return true if the given URI is a Composite type.
+ */
+ public static boolean isCompositeURI(URI uri) {
+ String ssp = PropertyUtil.stripPrefix(uri.getRawSchemeSpecificPart().trim(), "//").trim();
+
+ if (ssp.indexOf('(') == 0 && checkParenthesis(ssp)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Examine the supplied string and ensure that all parends appear as matching pairs.
+ *
+ * @param str
+ * The target string to examine.
+ *
+ * @return true if the target string has valid parend pairings.
+ */
+ public static boolean checkParenthesis(String str) {
+ boolean result = true;
+ if (str != null) {
+ int open = 0;
+ int closed = 0;
+
+ int i = 0;
+ while ((i = str.indexOf('(', i)) >= 0) {
+ i++;
+ open++;
+ }
+ i = 0;
+ while ((i = str.indexOf(')', i)) >= 0) {
+ i++;
+ closed++;
+ }
+ result = open == closed;
+ }
+ return result;
+ }
+
+ /**
+ * Given a string and a position in that string of an open parend, find the matching close
+ * parend.
+ *
+ * @param str
+ * The string to be searched for a matching parend.
+ * @param first
+ * The index in the string of the opening parend whose close value is to be searched.
+ *
+ * @return the index in the string where the closing parend is located.
+ *
+ * @throws URISyntaxException
+ * if the string does not contain a matching parend.
+ */
+ public static int indexOfParenthesisMatch(String str, int first) throws URISyntaxException {
+ int index = -1;
+
+ if (first < 0 || first > str.length()) {
+ throw new IllegalArgumentException("Invalid position for first parenthesis: " + first);
+ }
+
+ if (str.charAt(first) != '(') {
+ throw new IllegalArgumentException("character at indicated position is not a parenthesis");
+ }
+
+ int depth = 1;
+ char[] array = str.toCharArray();
+ for (index = first + 1; index < array.length; ++index) {
+ char current = array[index];
+ if (current == '(') {
+ depth++;
+ } else if (current == ')') {
+ if (--depth == 0) {
+ break;
+ }
+ }
+ }
+
+ if (depth != 0) {
+ throw new URISyntaxException(str, "URI did not contain a matching parenthesis.");
+ }
+
+ return index;
+ }
+
+ /**
+ * Given the inner portion of a composite URI, split and return each inner URI as a string
+ * element in a new String array.
+ *
+ * @param str
+ * The inner URI elements of a composite URI string.
+ *
+ * @return an array containing each inner URI from the composite one.
+ */
+ public static String[] splitComponents(String str) {
+ List<String> l = new ArrayList<String>();
+
+ int last = 0;
+ int depth = 0;
+ char chars[] = str.toCharArray();
+ for (int i = 0; i < chars.length; i++) {
+ switch (chars[i]) {
+ case '(':
+ depth++;
+ break;
+ case ')':
+ depth--;
+ break;
+ case ',':
+ if (depth == 0) {
+ String s = str.substring(last, i);
+ l.add(s);
+ last = i + 1;
+ }
+ break;
+ default:
+ }
+ }
+
+ String s = str.substring(last);
+ if (s.length() != 0) {
+ l.add(s);
+ }
+
+ String rc[] = new String[l.size()];
+ l.toArray(rc);
+ return rc;
+ }
+
+ /**
+ * Removes any URI query from the given uri and return a new URI that does not contain the
+ * query portion.
+ *
+ * @param uri
+ * The URI whose query value is to be removed.
+ *
+ * @return a new URI that does not contain a query value.
+ * @throws URISyntaxException
+ */
+ public static URI removeQuery(URI uri) throws URISyntaxException {
+ return PropertyUtil.replaceQuery(uri, (String) null);
+ }
+
+ /**
+ * Given a URI parse and extract any URI query options and return them as a Key / Value
+ * mapping.
+ *
+ * This method differs from the {@link parseQuery} method in that it handles composite URI
+ * types and will extract the URI options from the outermost composite URI.
+ *
+ * @param uri
+ * The URI whose query should be extracted and processed.
+ *
+ * @return A Mapping of the URI options.
+ * @throws URISyntaxException
+ */
+ public static Map<String, String> parseParameters(URI uri) throws URISyntaxException {
+ if (!isCompositeURI(uri)) {
+ if (uri.getQuery() == null) {
+ return Collections.emptyMap();
+ } else {
+ try {
+ return PropertyUtil.parseQuery(PropertyUtil.stripPrefix(uri.getQuery(), "?"));
+ } catch (Exception e) {
+ throw new URISyntaxException(uri.toString(), e.getMessage());
+ }
+ }
+ } else {
+ CompositeData data = URISupport.parseComposite(uri);
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.putAll(data.getParameters());
+ if (parameters.isEmpty()) {
+ parameters = Collections.emptyMap();
+ }
+
+ return parameters;
+ }
+ }
+
+ /**
+ * Given a Key / Value mapping create and append a URI query value that represents the
+ * mapped entries, return the newly updated URI that contains the value of the given URI and
+ * the appended query value.
+ *
+ * @param uri
+ * The source URI that will have the Map entries appended as a URI query value.
+ * @param queryParameters
+ * The Key / Value mapping that will be transformed into a URI query string.
+ *
+ * @return A new URI value that combines the given URI and the constructed query string.
+ * @throws URISyntaxException
+ */
+ public static URI applyParameters(URI uri, Map<String, String> queryParameters) throws URISyntaxException {
+ return applyParameters(uri, queryParameters, "");
+ }
+
+ /**
+ * Given a Key / Value mapping create and append a URI query value that represents the
+ * mapped entries, return the newly updated URI that contains the value of the given URI and
+ * the appended query value. Each entry in the query string is prefixed by the supplied
+ * optionPrefix string.
+ *
+ * @param uri
+ * The source URI that will have the Map entries appended as a URI query value.
+ * @param queryParameters
+ * The Key / Value mapping that will be transformed into a URI query string.
+ * @param optionPrefix
+ * A string value that when not null or empty is used to prefix each query option
+ * key.
+ *
+ * @return A new URI value that combines the given URI and the constructed query string.
+ * @throws URISyntaxException
+ */
+ public static URI applyParameters(URI uri, Map<String, String> queryParameters, String optionPrefix) throws URISyntaxException {
+ if (queryParameters != null && !queryParameters.isEmpty()) {
+ StringBuffer newQuery = uri.getRawQuery() != null ? new StringBuffer(uri.getRawQuery()) : new StringBuffer();
+ for (Map.Entry<String, String> param : queryParameters.entrySet()) {
+ if (param.getKey().startsWith(optionPrefix)) {
+ if (newQuery.length() != 0) {
+ newQuery.append('&');
+ }
+ final String key = param.getKey().substring(optionPrefix.length());
+ newQuery.append(key).append('=').append(param.getValue());
+ }
+ }
+ uri = PropertyUtil.replaceQuery(uri, newQuery.toString());
+ }
+ return uri;
+ }
+}
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/provider/amqp
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/provider/amqp b/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/provider/amqp
new file mode 100644
index 0000000..fe3ecca
--- /dev/null
+++ b/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/provider/amqp
@@ -0,0 +1,17 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+class=org.apache.qpid.jms.provider.amqp.AmqpProviderFactory
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/provider/amqp+nio
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/provider/amqp+nio b/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/provider/amqp+nio
new file mode 100644
index 0000000..fe3ecca
--- /dev/null
+++ b/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/provider/amqp+nio
@@ -0,0 +1,17 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+class=org.apache.qpid.jms.provider.amqp.AmqpProviderFactory
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/provider/amqp+nio+ssl
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/provider/amqp+nio+ssl b/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/provider/amqp+nio+ssl
new file mode 100644
index 0000000..69cd431
--- /dev/null
+++ b/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/provider/amqp+nio+ssl
@@ -0,0 +1,17 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+class=org.apache.qpid.jms.provider.amqp.AmqpSslProviderFactory
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/provider/amqp+ssl
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/provider/amqp+ssl b/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/provider/amqp+ssl
new file mode 100644
index 0000000..69cd431
--- /dev/null
+++ b/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/provider/amqp+ssl
@@ -0,0 +1,17 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+class=org.apache.qpid.jms.provider.amqp.AmqpSslProviderFactory
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/provider/amqps
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/provider/amqps b/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/provider/amqps
new file mode 100644
index 0000000..69cd431
--- /dev/null
+++ b/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/provider/amqps
@@ -0,0 +1,17 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+class=org.apache.qpid.jms.provider.amqp.AmqpSslProviderFactory
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/provider/failover
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/provider/failover b/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/provider/failover
new file mode 100644
index 0000000..b66f21e
--- /dev/null
+++ b/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/provider/failover
@@ -0,0 +1,17 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+class=org.apache.qpid.jms.provider.failover.FailoverProviderFactory
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/sasl/ANONYMOUS
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/sasl/ANONYMOUS b/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/sasl/ANONYMOUS
new file mode 100644
index 0000000..00b9f52
--- /dev/null
+++ b/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/sasl/ANONYMOUS
@@ -0,0 +1,17 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+class=org.apache.qpid.jms.sasl.AnonymousMechanismFactory
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/sasl/CRAM-MD5
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/sasl/CRAM-MD5 b/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/sasl/CRAM-MD5
new file mode 100644
index 0000000..fb2d223
--- /dev/null
+++ b/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/sasl/CRAM-MD5
@@ -0,0 +1,17 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+class=org.apache.qpid.jms.sasl.CramMD5MechanismFactory
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/sasl/PLAIN
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/sasl/PLAIN b/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/sasl/PLAIN
new file mode 100644
index 0000000..cf06fa1
--- /dev/null
+++ b/qpid-jms-client/src/main/resources/META-INF/services/org/apache/qpid/jms/sasl/PLAIN
@@ -0,0 +1,17 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+class=org.apache.qpid.jms.sasl.PlainMechanismFactory
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/ConnectionIntegrationTest.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/ConnectionIntegrationTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/ConnectionIntegrationTest.java
new file mode 100644
index 0000000..3a7b6ac
--- /dev/null
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/ConnectionIntegrationTest.java
@@ -0,0 +1,66 @@
+/*
+ *
+ * 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.qpid.jms.integration;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionMetaData;
+import javax.jms.Session;
+
+import org.apache.qpid.jms.test.QpidJmsTestCase;
+import org.apache.qpid.jms.test.testpeer.TestAmqpPeer;
+import org.junit.Test;
+
+// TODO find a way to make the test abort immediately if the TestAmqpPeer throws an exception
+public class ConnectionIntegrationTest extends QpidJmsTestCase {
+ private final IntegrationTestFixture testFixture = new IntegrationTestFixture();
+
+ @Test(timeout=10000)
+ public void testCreateAndCloseConnection() throws Exception {
+ try (TestAmqpPeer testPeer = new TestAmqpPeer(IntegrationTestFixture.PORT);) {
+ Connection connection = testFixture.establishConnecton(testPeer);
+ testPeer.expectClose();
+ connection.close();
+ }
+ }
+
+ @Test(timeout=10000)
+ public void testCreateAutoAckSession() throws Exception {
+ try (TestAmqpPeer testPeer = new TestAmqpPeer(IntegrationTestFixture.PORT);) {
+ Connection connection = testFixture.establishConnecton(testPeer);
+ testPeer.expectBegin(true);
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ assertNotNull("Session should not be null", session);
+ }
+ }
+
+ @Test(timeout=5000)
+ public void testConnectionMetaDataVersion() throws Exception {
+ try (TestAmqpPeer testPeer = new TestAmqpPeer(IntegrationTestFixture.PORT);) {
+ Connection connection = testFixture.establishConnecton(testPeer);
+
+ ConnectionMetaData meta = connection.getMetaData();
+ assertTrue("Expected non-zero provider major version", meta.getProviderMajorVersion() != 0);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/IntegrationTestFixture.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/IntegrationTestFixture.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/IntegrationTestFixture.java
new file mode 100644
index 0000000..cf19d67
--- /dev/null
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/IntegrationTestFixture.java
@@ -0,0 +1,48 @@
+/*
+ * 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.qpid.jms.integration;
+
+import static org.junit.Assert.assertNull;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.JMSException;
+
+import org.apache.qpid.jms.JmsConnectionFactory;
+import org.apache.qpid.jms.test.testpeer.TestAmqpPeer;
+
+public class IntegrationTestFixture {
+ static final int PORT = 25672;
+
+ Connection establishConnecton(TestAmqpPeer testPeer) throws JMSException {
+ testPeer.expectPlainConnect("guest", "guest", true);
+
+ // Each connection creates a session for managing temporary destinations etc
+ testPeer.expectBegin(true);
+
+ ConnectionFactory factory = new JmsConnectionFactory("amqp://localhost:" + PORT);
+ Connection connection = factory.createConnection("guest", "guest");
+
+ // Set a clientId to provoke the actual AMQP connection process to occur.
+ connection.setClientID("clientName");
+
+ assertNull(testPeer.getThrowable());
+ return connection;
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org