diff --git a/tests/activemq5-unit-tests/README.md b/tests/activemq5-unit-tests/README.md
new file mode 100644
index 0000000000..99e17b83a1
--- /dev/null
+++ b/tests/activemq5-unit-tests/README.md
@@ -0,0 +1,15 @@
+# ActiveMQ 5 unit tests against ActiveMQ Artemis wrapper
+
+
+This maven module is used to run ActiveMQ5 unit tests against
+ActiveMQ Artemis broker.
+
+The Artemis broker is 'wrapped' in BrokerService and the unit
+tests are slightly modified.
+
+Then run the tests simply do
+
+```mvn -DskipActiveMQTests=false clean test```
+
+It will kickoff the whole test suite.
+
diff --git a/tests/activemq5-unit-tests/pom.xml b/tests/activemq5-unit-tests/pom.xml
new file mode 100644
index 0000000000..d6d87e8e92
--- /dev/null
+++ b/tests/activemq5-unit-tests/pom.xml
@@ -0,0 +1,387 @@
+
+
+ 4.0.0
+
+
+ org.apache.activemq.tests
+ artemis-tests-pom
+ 1.0.0-SNAPSHOT
+
+
+ activemq5-unit-tests
+ jar
+ ActiveMQ5.x unit tests
+
+
+ ${project.basedir}/../..
+ 5.11.1
+ 3.4.1
+ 1.0.6
+ 2.5.1
+ 3.2.11.RELEASE
+ 10.11.1.1
+ 2.4
+ 3.3
+ 0.30
+ 3.18
+ 1.3
+ 1.7.10
+ 1.9.2
+ 2.0.0-M6
+ 3.1.4
+
+
+
+
+
+
+ org.apache.activemq
+ activemq-client
+ ${activemq5.project.version}
+
+
+
+ org.apache.activemq
+ activemq-jaas
+ ${activemq5.project.version}
+
+
+
+ org.apache.activemq
+ activemq-broker
+ ${activemq5.project.version}
+ test-jar
+
+
+
+ org.apache.activemq
+ activemq-jdbc-store
+ ${activemq5.project.version}
+
+
+
+ org.apache.activemq
+ activemq-kahadb-store
+ ${activemq5.project.version}
+
+
+
+ org.apache.activemq
+ activemq-leveldb-store
+ ${activemq5.project.version}
+
+
+
+ org.apache.activemq
+ activemq-pool
+ ${activemq5.project.version}
+
+
+
+ org.apache.activemq
+ activemq-spring
+ ${activemq5.project.version}
+
+
+
+ org.apache.activemq
+ activemq-partition
+ ${activemq5.project.version}
+
+
+
+ org.apache.activemq
+ activemq-stomp
+ ${activemq5.project.version}
+
+
+
+ org.apache.activemq
+ activemq-console
+ ${activemq5.project.version}
+
+
+
+ org.apache.activemq
+ activeio-core
+ ${activeio-core-version}
+
+
+
+ junit
+ junit
+ 4.11
+ compile
+
+
+
+ org.osgi
+ org.osgi.core
+ 4.3.1
+
+
+
+ javax.jmdns
+ jmdns
+ ${jmdns-version}
+
+
+
+ org.apache.ftpserver
+ ftpserver-core
+ ${ftpserver-version}
+ test
+
+
+
+ org.jmock
+ jmock-junit4
+ ${jmock-version}
+ test
+
+
+
+ org.jmock
+ jmock-legacy
+ ${jmock-version}
+ test
+
+
+
+ org.springframework
+ spring-jms
+ ${spring-version}
+ test
+
+
+
+ org.apache.derby
+ derby
+ ${org-apache-derby-version}
+ test
+
+
+
+ commons-io
+ commons-io
+ ${commons-io-version}
+ test
+
+
+
+ commons-net
+ commons-net
+ ${commons-net-version}
+
+
+
+ org.apache.qpid
+ qpid-amqp-1-0-client-jms
+ ${qpid-jms-version}
+ test
+
+
+
+ org.apache.xbean
+ xbean-spring
+ ${xbean-version}
+ test
+
+
+
+ org.hamcrest
+ hamcrest-all
+ ${hamcrest-version}
+ test
+
+
+
+ org.slf4j
+ slf4j-log4j12
+ ${slf4j-version}
+ test
+
+
+
+ log4j
+ log4j
+ test
+
+
+
+ org.springframework
+ spring-test
+ ${spring-version}
+ test
+
+
+
+ org.jasypt
+ jasypt
+ ${jasypt-version}
+
+
+
+ org.jasypt
+ jasypt-spring31
+ ${jasypt-version}
+ true
+
+
+
+ org.apache.directory.server
+ apacheds-core-integ
+ ${directory-version}
+ test
+
+
+ bouncycastle
+ bcprov-jdk15
+
+
+
+
+
+ org.bouncycastle
+ bcprov-jdk15
+ 1.46
+ test
+
+
+
+ org.apache.directory.server
+ apacheds-server-integ
+ ${directory-version}
+ test
+
+
+
+ org.fusesource.joram-jms-tests
+ joram-jms-tests
+ 1.0
+ test
+
+
+
+ org.easymock
+ easymock
+ 3.2
+ test
+
+
+
+ org.fusesource.mqtt-client
+ mqtt-client
+ 1.10
+ test
+
+
+
+
+ org.apache.activemq
+ artemis-commons
+ ${project.version}
+
+
+
+ org.apache.activemq
+ artemis-server
+ ${project.version}
+
+
+
+ org.apache.activemq
+ artemis-openwire-protocol
+ ${project.version}
+
+
+
+
+
+
+
+ org.apache.rat
+ apache-rat-plugin
+ 0.11
+
+ ${activemq.basedir}/ratReport.txt
+ ${skipLicenseCheck}
+
+ **/*.data
+ **/*.bin
+ **/*.log
+ **/*.redo
+ **/src/test/resources/keystore
+ **/META-INF/services/*
+ **/*/*.txt
+ **/*.md
+
+
+
+
+ compile
+
+ check
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+ 2.12
+
+ true
+
+
+
+ compile
+
+ check
+
+
+
+
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ 2.5.3
+ true
+ true
+
+
+ org.apache.activemq.util.osgi.Activator
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ ${skipActiveMQ5Tests}
+
+
+
+
+
+
+
+
diff --git a/tests/activemq5-unit-tests/src/main/java/org/apache/activemq/artemiswrapper/ArtemisBrokerHelper.java b/tests/activemq5-unit-tests/src/main/java/org/apache/activemq/artemiswrapper/ArtemisBrokerHelper.java
new file mode 100644
index 0000000000..8d5cdabc38
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/main/java/org/apache/activemq/artemiswrapper/ArtemisBrokerHelper.java
@@ -0,0 +1,76 @@
+/**
+ * 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.artemiswrapper;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URI;
+
+import org.apache.activemq.command.ActiveMQDestination;
+
+public class ArtemisBrokerHelper {
+
+ private static volatile Object service = null;
+ private static Class> serviceClass;
+
+ static {
+ try {
+ serviceClass = Class.forName("org.apache.activemq.broker.BrokerService");
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+
+ }
+ // start a tcp transport artemis broker, the broker need to
+ // be invm with client.
+ public static void startArtemisBroker(URI location) throws IOException {
+ if (service != null) {
+ return;
+ }
+ try {
+ service = serviceClass.newInstance();
+ Method startMethod = serviceClass.getMethod("start");
+ startMethod.invoke(service, (Object[]) null);
+ } catch (InstantiationException e) {
+ throw new IOException("Inst exception", e);
+ } catch (IllegalAccessException e) {
+ throw new IOException("IllegalAccess exception ", e);
+ } catch (NoSuchMethodException e) {
+ throw new IOException("Nosuchmethod", e);
+ } catch (SecurityException e) {
+ throw new IOException("Security exception", e);
+ } catch (IllegalArgumentException e) {
+ throw new IOException("IllegalArgumentException exception", e);
+ } catch (InvocationTargetException e) {
+ throw new IOException("InvocationTargetException exception", e);
+ }
+ }
+
+ public static void makeSureDestinationExists(ActiveMQDestination activemqDestination) throws Exception {
+ Method startMethod = serviceClass.getMethod("makeSureDestinationExists", ActiveMQDestination.class);
+ startMethod.invoke(service, activemqDestination);
+ }
+
+ //some tests run broker in setUp(). This need be called
+ //to prevent auto broker creation.
+ public static void setBroker(Object startedBroker) {
+ service = startedBroker;
+ }
+
+}
+
diff --git a/tests/activemq5-unit-tests/src/main/java/org/apache/activemq/broker/BrokerService.java b/tests/activemq5-unit-tests/src/main/java/org/apache/activemq/broker/BrokerService.java
new file mode 100644
index 0000000000..cf9c93909c
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/main/java/org/apache/activemq/broker/BrokerService.java
@@ -0,0 +1,811 @@
+/**
+ * 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.broker;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.UnknownHostException;
+import java.security.Provider;
+import java.security.Security;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.RejectedExecutionHandler;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+import org.apache.activemq.ActiveMQConnectionMetaData;
+import org.apache.activemq.ConfigurationException;
+import org.apache.activemq.Service;
+import org.apache.activemq.advisory.AdvisoryBroker;
+import org.apache.activemq.broker.artemiswrapper.ArtemisBrokerWrapper;
+import org.apache.activemq.broker.cluster.ConnectionSplitBroker;
+import org.apache.activemq.broker.jmx.AnnotatedMBean;
+import org.apache.activemq.broker.jmx.BrokerMBeanSupport;
+import org.apache.activemq.broker.jmx.BrokerView;
+import org.apache.activemq.broker.jmx.ConnectorView;
+import org.apache.activemq.broker.jmx.ConnectorViewMBean;
+import org.apache.activemq.broker.jmx.HealthView;
+import org.apache.activemq.broker.jmx.HealthViewMBean;
+import org.apache.activemq.broker.jmx.JmsConnectorView;
+import org.apache.activemq.broker.jmx.JobSchedulerView;
+import org.apache.activemq.broker.jmx.JobSchedulerViewMBean;
+import org.apache.activemq.broker.jmx.Log4JConfigView;
+import org.apache.activemq.broker.jmx.ManagedRegionBroker;
+import org.apache.activemq.broker.jmx.ManagementContext;
+import org.apache.activemq.broker.jmx.NetworkConnectorView;
+import org.apache.activemq.broker.jmx.NetworkConnectorViewMBean;
+import org.apache.activemq.broker.jmx.ProxyConnectorView;
+import org.apache.activemq.broker.region.CompositeDestinationInterceptor;
+import org.apache.activemq.broker.region.Destination;
+import org.apache.activemq.broker.region.DestinationFactory;
+import org.apache.activemq.broker.region.DestinationFactoryImpl;
+import org.apache.activemq.broker.region.DestinationInterceptor;
+import org.apache.activemq.broker.region.RegionBroker;
+import org.apache.activemq.broker.region.policy.PolicyMap;
+import org.apache.activemq.broker.region.virtual.MirroredQueue;
+import org.apache.activemq.broker.region.virtual.VirtualDestination;
+import org.apache.activemq.broker.region.virtual.VirtualDestinationInterceptor;
+import org.apache.activemq.broker.region.virtual.VirtualTopic;
+import org.apache.activemq.broker.scheduler.JobSchedulerStore;
+import org.apache.activemq.broker.scheduler.SchedulerBroker;
+import org.apache.activemq.broker.scheduler.memory.InMemoryJobSchedulerStore;
+import org.apache.activemq.command.ActiveMQDestination;
+import org.apache.activemq.command.ActiveMQQueue;
+import org.apache.activemq.command.BrokerId;
+import org.apache.activemq.command.ProducerInfo;
+import org.apache.activemq.filter.DestinationFilter;
+import org.apache.activemq.network.ConnectionFilter;
+import org.apache.activemq.network.DiscoveryNetworkConnector;
+import org.apache.activemq.network.NetworkConnector;
+import org.apache.activemq.network.jms.JmsConnector;
+import org.apache.activemq.openwire.OpenWireFormat;
+import org.apache.activemq.proxy.ProxyConnector;
+import org.apache.activemq.security.MessageAuthorizationPolicy;
+import org.apache.activemq.selector.SelectorParser;
+import org.apache.activemq.store.JournaledStore;
+import org.apache.activemq.store.PListStore;
+import org.apache.activemq.store.PersistenceAdapter;
+import org.apache.activemq.store.PersistenceAdapterFactory;
+import org.apache.activemq.store.memory.MemoryPersistenceAdapter;
+import org.apache.activemq.thread.Scheduler;
+import org.apache.activemq.thread.TaskRunnerFactory;
+import org.apache.activemq.transport.TransportFactorySupport;
+import org.apache.activemq.transport.TransportServer;
+import org.apache.activemq.transport.vm.VMTransportFactory;
+import org.apache.activemq.usage.SystemUsage;
+import org.apache.activemq.util.BrokerSupport;
+import org.apache.activemq.util.DefaultIOExceptionHandler;
+import org.apache.activemq.util.IOExceptionHandler;
+import org.apache.activemq.util.IOExceptionSupport;
+import org.apache.activemq.util.IOHelper;
+import org.apache.activemq.util.InetAddressUtil;
+import org.apache.activemq.util.ServiceStopper;
+import org.apache.activemq.util.ThreadPoolUtils;
+import org.apache.activemq.util.TimeUtils;
+import org.apache.activemq.util.URISupport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+
+/**
+ * Manages the life-cycle of an ActiveMQ Broker. A BrokerService consists of a
+ * number of transport connectors, network connectors and a bunch of properties
+ * which can be used to configure the broker as its lazily created.
+ *
+ * @org.apache.xbean.XBean
+ */
+public class BrokerService implements Service
+{
+ public static final String DEFAULT_PORT = "61616";
+ public static final String DEFAULT_BROKER_NAME = "localhost";
+ public static final String BROKER_VERSION;
+ public static final int DEFAULT_MAX_FILE_LENGTH = 1024 * 1024 * 32;
+ public static final long DEFAULT_START_TIMEOUT = 600000L;
+
+ public String SERVER_SIDE_KEYSTORE;
+ public String KEYSTORE_PASSWORD;
+ public String SERVER_SIDE_TRUSTSTORE;
+ public String TRUSTSTORE_PASSWORD;
+ public String storeType;
+
+ private static final Logger LOG = LoggerFactory.getLogger(BrokerService.class);
+
+ @SuppressWarnings("unused")
+ private static final long serialVersionUID = 7353129142305630237L;
+
+ private String brokerName = DEFAULT_BROKER_NAME;
+ private Broker broker;
+ private BrokerId brokerId;
+ private Throwable startException = null;
+ private boolean startAsync = false;
+ public Set extraConnectors = new HashSet();
+ private File dataDirectoryFile;
+
+ static
+ {
+ InputStream in;
+ String version = null;
+ if ((in = BrokerService.class.getResourceAsStream("/org/apache/activemq/version.txt")) != null)
+ {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ try
+ {
+ version = reader.readLine();
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ BROKER_VERSION = version;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "BrokerService[" + getBrokerName() + "]";
+ }
+
+ private String getBrokerVersion()
+ {
+ String version = ActiveMQConnectionMetaData.PROVIDER_VERSION;
+ if (version == null)
+ {
+ version = BROKER_VERSION;
+ }
+
+ return version;
+ }
+
+
+ @Override
+ public void start() throws Exception
+ {
+ startBroker(startAsync);
+ }
+
+ private void startBroker(boolean async) throws Exception
+ {
+ if (async)
+ {
+ new Thread("Broker Starting Thread")
+ {
+ @Override
+ public void run()
+ {
+ try
+ {
+ doStartBroker();
+ }
+ catch (Throwable t)
+ {
+ startException = t;
+ }
+ }
+ }.start();
+ }
+ else
+ {
+ doStartBroker();
+ }
+ }
+
+ private void doStartBroker() throws Exception
+ {
+ if (startException != null)
+ {
+ return;
+ }
+
+ broker = getBroker();
+ brokerId = broker.getBrokerId();
+
+ LOG.info("Apache ActiveMQ Artemis Wrapper {} ({}, {}) is starting", new Object[]{getBrokerVersion(), getBrokerName(), brokerId});
+
+ try
+ {
+ broker.start();
+ }
+ catch (Exception e)
+ {
+ throw e;
+ }
+ catch (Throwable t)
+ {
+ throw new Exception(t);
+ }
+
+ LOG.info("Apache ActiveMQ Artemis Wrapper {} ({}, {}) started", new Object[]{getBrokerVersion(), getBrokerName(), brokerId});
+ LOG.info("For help or more information please see: http://activemq.apache.org");
+
+ }
+
+
+ /**
+ * @throws Exception
+ * @org.apache .xbean.DestroyMethod
+ */
+ @Override
+ public void stop() throws Exception
+ {
+
+ LOG.info("Apache ActiveMQ Artemis{} ({}, {}) is shutting down", new Object[]{getBrokerVersion(), getBrokerName(), brokerId});
+
+ if (broker != null)
+ {
+ broker.stop();
+ broker = null;
+ }
+ LOG.info("Apache ActiveMQ Artemis {} ({}, {}) is shutdown", new Object[]{getBrokerVersion(), getBrokerName(), brokerId});
+ }
+
+ // Properties
+ // -------------------------------------------------------------------------
+
+ /**
+ * Returns the message broker
+ */
+ public Broker getBroker() throws Exception
+ {
+ if (broker == null)
+ {
+ broker = createBroker();
+ }
+ return broker;
+ }
+
+ public String getBrokerName()
+ {
+ return brokerName;
+ }
+
+ /**
+ * Sets the name of this broker; which must be unique in the network
+ *
+ * @param brokerName
+ */
+ public void setBrokerName(String brokerName)
+ {
+ if (brokerName == null)
+ {
+ throw new NullPointerException("The broker name cannot be null");
+ }
+ String str = brokerName.replaceAll("[^a-zA-Z0-9\\.\\_\\-\\:]", "_");
+ if (!str.equals(brokerName))
+ {
+ LOG.error("Broker Name: {} contained illegal characters - replaced with {}", brokerName, str);
+ }
+ this.brokerName = str.trim();
+ }
+
+ /**
+ * Factory method to create a new broker
+ *
+ * @throws Exception
+ * @throws
+ * @throws
+ */
+ protected Broker createBroker() throws Exception
+ {
+ broker = createBrokerWrapper();
+ return broker;
+ }
+
+ private Broker createBrokerWrapper()
+ {
+ return new ArtemisBrokerWrapper(this);
+ }
+
+ public void makeSureDestinationExists(ActiveMQDestination activemqDestination) throws Exception
+ {
+ System.out.println(">>>> making sure dest exits: " + activemqDestination);
+ ArtemisBrokerWrapper hqBroker = (ArtemisBrokerWrapper) this.broker;
+ //it can be null
+ if (activemqDestination == null)
+ {
+ return;
+ }
+ if (activemqDestination.isQueue())
+ {
+ String qname = activemqDestination.getPhysicalName();
+ System.out.println("physical name: " + qname);
+ hqBroker.makeSureQueueExists(qname);
+ }
+ }
+
+ public boolean enableSsl()
+ {
+ return this.SERVER_SIDE_KEYSTORE != null;
+ }
+
+ //below are methods called directly by tests
+ //we don't actually implement any of these for now,
+ //just to make test compile pass.
+
+ //we may get class cast exception as in TestSupport it
+ //casts the broker to RegionBroker, which we didn't
+ //implement (wrap) yet. Consider solving it later.
+ public Broker getRegionBroker()
+ {
+ return broker;
+ }
+
+ public void setPersistenceAdapter(PersistenceAdapter persistenceAdapter) throws IOException
+ {
+ }
+
+ public File getDataDirectoryFile()
+ {
+ if (dataDirectoryFile == null)
+ {
+ dataDirectoryFile = new File(IOHelper.getDefaultDataDirectory());
+ }
+ return dataDirectoryFile;
+ }
+
+ public File getBrokerDataDirectory()
+ {
+ String brokerDir = getBrokerName();
+ return new File(getDataDirectoryFile(), brokerDir);
+ }
+
+ public PersistenceAdapter getPersistenceAdapter() throws IOException
+ {
+ return null;
+ }
+
+ public void waitUntilStopped()
+ {
+ }
+
+ public boolean waitUntilStarted()
+ {
+ return true;
+ }
+
+ public void setDestinationPolicy(PolicyMap policyMap)
+ {
+ }
+
+ public void setDeleteAllMessagesOnStartup(boolean deletePersistentMessagesOnStartup)
+ {
+ }
+
+ public void setUseJmx(boolean useJmx)
+ {
+ }
+
+ public ManagementContext getManagementContext()
+ {
+ return null;
+ }
+
+ public BrokerView getAdminView() throws Exception
+ {
+ return null;
+ }
+
+ public List getTransportConnectors()
+ {
+ return new ArrayList<>();
+ }
+
+ public TransportConnector addConnector(String bindAddress) throws Exception
+ {
+ return null;
+ }
+
+ public void setIoExceptionHandler(IOExceptionHandler ioExceptionHandler)
+ {
+ }
+
+ public void setPersistent(boolean persistent)
+ {
+ }
+
+ public boolean isSlave()
+ {
+ return false;
+ }
+
+ public Destination getDestination(ActiveMQDestination destination) throws Exception
+ {
+ return null;
+ }
+
+ public void setAllowTempAutoCreationOnSend(boolean allowTempAutoCreationOnSend)
+ {
+ }
+
+ public void setDedicatedTaskRunner(boolean dedicatedTaskRunner)
+ {
+ }
+
+ public void setAdvisorySupport(boolean advisorySupport)
+ {
+ }
+
+ public void setUseShutdownHook(boolean useShutdownHook)
+ {
+ }
+
+ public void deleteAllMessages() throws IOException
+ {
+ }
+
+ public Service[] getServices()
+ {
+ return null;
+ }
+
+ public void setPopulateUserNameInMBeans(boolean value)
+ {
+ }
+
+ public void setDestinations(ActiveMQDestination[] destinations)
+ {
+ }
+
+ public URI getVmConnectorURI()
+ {
+ return null;
+ }
+
+ public SystemUsage getSystemUsage()
+ {
+ return null;
+ }
+
+ public synchronized PListStore getTempDataStore()
+ {
+ return null;
+ }
+
+ public void setJmsBridgeConnectors(JmsConnector[] jmsConnectors)
+ {
+ }
+
+ public void setDestinationInterceptors(DestinationInterceptor[] destinationInterceptors)
+ {
+ }
+
+ public SslContext getSslContext()
+ {
+ return null;
+ }
+
+ public void setDataDirectory(String dataDirectory)
+ {
+ }
+
+ public void setPlugins(BrokerPlugin[] plugins)
+ {
+ }
+
+ public void setKeepDurableSubsActive(boolean keepDurableSubsActive)
+ {
+ }
+
+ public NetworkConnector addNetworkConnector(String discoveryAddress) throws Exception
+ {
+ return null;
+ }
+
+ public TransportConnector getConnectorByName(String connectorName)
+ {
+ return null;
+ }
+
+ public TransportConnector addConnector(TransportConnector connector) throws Exception
+ {
+ return connector;
+ }
+
+ public void setEnableStatistics(boolean enableStatistics)
+ {
+ }
+
+ public void setSystemUsage(SystemUsage memoryManager)
+ {
+ }
+
+ public void setManagementContext(ManagementContext managementContext)
+ {
+ }
+
+ public void setSchedulerDirectoryFile(File schedulerDirectory)
+ {
+ }
+
+ public List getNetworkConnectors()
+ {
+ return new ArrayList<>();
+ }
+
+ public void setSchedulerSupport(boolean schedulerSupport)
+ {
+ }
+
+ public void setPopulateJMSXUserID(boolean populateJMSXUserID)
+ {
+ }
+
+ public boolean isUseJmx()
+ {
+ return false;
+ }
+
+ public boolean isPersistent()
+ {
+ return false;
+ }
+
+ public TransportConnector getTransportConnectorByScheme(String scheme)
+ {
+ return null;
+ }
+
+ public TaskRunnerFactory getTaskRunnerFactory()
+ {
+ return null;
+ }
+
+ public boolean isStarted()
+ {
+ if (broker == null) return false;
+ return !broker.isStopped();
+ }
+
+ public ProxyConnector addProxyConnector(ProxyConnector connector) throws Exception
+ {
+ return connector;
+ }
+
+ public void setDataDirectoryFile(File dataDirectoryFile)
+ {
+ this.dataDirectoryFile = dataDirectoryFile;
+ }
+
+ public PolicyMap getDestinationPolicy()
+ {
+ return null;
+ }
+
+ public void setTransportConnectorURIs(String[] transportConnectorURIs)
+ {
+ }
+
+ public boolean isPopulateJMSXUserID()
+ {
+ return false;
+ }
+
+ public NetworkConnector getNetworkConnectorByName(String connectorName)
+ {
+ return null;
+ }
+
+ public boolean removeNetworkConnector(NetworkConnector connector)
+ {
+ return true;
+ }
+
+ public void setTransportConnectors(List transportConnectors) throws Exception
+ {
+ }
+
+ public NetworkConnector addNetworkConnector(NetworkConnector connector) throws Exception
+ {
+ return connector;
+ }
+
+ public void setTempDataStore(PListStore tempDataStore)
+ {
+ }
+
+ public void setJobSchedulerStore(JobSchedulerStore jobSchedulerStore)
+ {
+ }
+
+ public ObjectName getBrokerObjectName() throws MalformedObjectNameException
+ {
+ return null;
+ }
+
+ public TransportConnector addConnector(URI bindAddress) throws Exception
+ {
+ return null;
+ }
+
+ public void setCacheTempDestinations(boolean cacheTempDestinations)
+ {
+ }
+
+ public void setOfflineDurableSubscriberTimeout(long offlineDurableSubscriberTimeout)
+ {
+ }
+
+ public void setOfflineDurableSubscriberTaskSchedule(long offlineDurableSubscriberTaskSchedule)
+ {
+ }
+
+ public boolean isStopped()
+ {
+ return broker.isStopped();
+ }
+
+ public void setBrokerId(String brokerId)
+ {
+ }
+
+ public BrokerPlugin[] getPlugins()
+ {
+ return null;
+ }
+
+ public void stopAllConnectors(ServiceStopper stopper)
+ {
+ }
+
+ public void setMessageAuthorizationPolicy(MessageAuthorizationPolicy messageAuthorizationPolicy)
+ {
+ }
+
+ public void setNetworkConnectorStartAsync(boolean networkConnectorStartAsync)
+ {
+ }
+
+ public boolean isRestartAllowed()
+ {
+ return true;
+ }
+
+ public void setTaskRunnerFactory(TaskRunnerFactory taskRunnerFactory)
+ {
+ }
+
+ public void start(boolean force) throws Exception
+ {
+ this.start();
+ }
+
+ public void setMonitorConnectionSplits(boolean monitorConnectionSplits)
+ {
+ }
+
+ public void setUseMirroredQueues(boolean useMirroredQueues)
+ {
+ }
+
+ public File getTmpDataDirectory()
+ {
+ return null;
+ }
+
+ public boolean isUseShutdownHook()
+ {
+ return true;
+ }
+
+ public boolean isDeleteAllMessagesOnStartup()
+ {
+ return false;
+ }
+
+ public void setUseVirtualTopics(boolean useVirtualTopics)
+ {
+ }
+
+ public boolean isUseLoggingForShutdownErrors()
+ {
+ return true;
+ }
+
+ public TransportConnector addConnector(TransportServer transport) throws Exception
+ {
+ return null;
+ }
+
+ public synchronized JobSchedulerStore getJobSchedulerStore()
+ {
+ return null;
+ }
+
+ public boolean removeConnector(TransportConnector connector) throws Exception
+ {
+ return true;
+ }
+
+ public ConnectionContext getAdminConnectionContext() throws Exception {
+ return null;
+ }
+
+ public void setUseAuthenticatedPrincipalForJMSXUserID(boolean useAuthenticatedPrincipalForJMSXUserID)
+ {
+ }
+
+ public void setSchedulePeriodForDestinationPurge(int schedulePeriodForDestinationPurge)
+ {
+ }
+
+ public void setMbeanInvocationTimeout(long mbeanInvocationTimeout)
+ {
+ }
+
+ public void setNetworkConnectors(List> networkConnectors) throws Exception
+ {
+ }
+
+ public void removeDestination(ActiveMQDestination destination) throws Exception
+ {
+ }
+
+ public void setMaxPurgedDestinationsPerSweep(int maxPurgedDestinationsPerSweep)
+ {
+ }
+
+ public void setBrokerObjectName(ObjectName brokerObjectName)
+ {
+ }
+
+ public Map getTransportConnectorURIsAsMap()
+ {
+ return null;
+ }
+
+ public void setSslContext(SslContext sslContext)
+ {
+ }
+
+ public void setPersistenceFactory(PersistenceAdapterFactory persistenceFactory)
+ {
+ }
+
+ protected TransportConnector createTransportConnector(URI brokerURI) throws Exception
+ {
+ return null;
+ }
+
+}
+
+
+
diff --git a/tests/activemq5-unit-tests/src/main/java/org/apache/activemq/broker/SslBrokerService.java b/tests/activemq5-unit-tests/src/main/java/org/apache/activemq/broker/SslBrokerService.java
new file mode 100644
index 0000000000..9699cf3f85
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/main/java/org/apache/activemq/broker/SslBrokerService.java
@@ -0,0 +1,61 @@
+/**
+ * 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.broker;
+
+import org.apache.activemq.transport.TransportFactorySupport;
+import org.apache.activemq.transport.TransportServer;
+import org.apache.activemq.transport.tcp.SslTransportFactory;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.TrustManager;
+import java.io.IOException;
+import java.net.URI;
+import java.security.KeyManagementException;
+import java.security.SecureRandom;
+
+/**
+ * A BrokerService that allows access to the key and trust managers used by SSL
+ * connections. There is no reason to use this class unless SSL is being used
+ * AND the key and trust managers need to be specified from within code. In
+ * fact, if the URI passed to this class does not have an "ssl" scheme, this
+ * class will pass all work on to its superclass.
+ *
+ * @author sepandm@gmail.com (Sepand)
+ */
+public class SslBrokerService extends BrokerService
+{
+
+ public TransportConnector addSslConnector(String bindAddress, KeyManager[] km, TrustManager[] tm, SecureRandom random) throws Exception {
+ return null;
+ }
+
+ public TransportConnector addSslConnector(URI bindAddress, KeyManager[] km, TrustManager[] tm, SecureRandom random) throws Exception {
+ return null;
+ }
+
+ protected TransportServer createSslTransportServer(URI brokerURI, KeyManager[] km, TrustManager[] tm, SecureRandom random) throws IOException, KeyManagementException {
+ return null;
+ }
+
+ //one way
+ public void setupSsl(String keystoreType, String password, String serverKeystore) {
+ this.SERVER_SIDE_KEYSTORE = serverKeystore;
+ this.KEYSTORE_PASSWORD = password;
+ this.storeType = keystoreType;
+ }
+}
diff --git a/tests/activemq5-unit-tests/src/main/java/org/apache/activemq/broker/artemiswrapper/ArtemisBrokerBase.java b/tests/activemq5-unit-tests/src/main/java/org/apache/activemq/broker/artemiswrapper/ArtemisBrokerBase.java
new file mode 100644
index 0000000000..227ad1b10e
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/main/java/org/apache/activemq/broker/artemiswrapper/ArtemisBrokerBase.java
@@ -0,0 +1,674 @@
+/**
+ * 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.broker.artemiswrapper;
+
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ThreadPoolExecutor;
+
+import org.apache.activemq.artemis.api.core.TransportConfiguration;
+import org.apache.activemq.artemis.core.asyncio.impl.AsynchronousFileImpl;
+import org.apache.activemq.artemis.core.config.Configuration;
+import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
+import org.apache.activemq.artemis.core.remoting.impl.invm.InVMAcceptorFactory;
+import org.apache.activemq.artemis.core.remoting.impl.netty.NettyAcceptorFactory;
+import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory;
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import org.apache.activemq.artemis.core.server.ActiveMQServers;
+import org.apache.activemq.artemis.core.server.JournalType;
+import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy;
+import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
+import org.apache.activemq.broker.Broker;
+import org.apache.activemq.broker.BrokerService;
+import org.apache.activemq.broker.Connection;
+import org.apache.activemq.broker.ConnectionContext;
+import org.apache.activemq.broker.ConsumerBrokerExchange;
+import org.apache.activemq.broker.ProducerBrokerExchange;
+import org.apache.activemq.broker.region.Destination;
+import org.apache.activemq.broker.region.MessageReference;
+import org.apache.activemq.broker.region.Subscription;
+import org.apache.activemq.command.ActiveMQDestination;
+import org.apache.activemq.command.BrokerId;
+import org.apache.activemq.command.BrokerInfo;
+import org.apache.activemq.command.ConnectionInfo;
+import org.apache.activemq.command.ConsumerControl;
+import org.apache.activemq.command.ConsumerInfo;
+import org.apache.activemq.command.DestinationInfo;
+import org.apache.activemq.command.Message;
+import org.apache.activemq.command.MessageAck;
+import org.apache.activemq.command.MessageDispatch;
+import org.apache.activemq.command.MessageDispatchNotification;
+import org.apache.activemq.command.MessagePull;
+import org.apache.activemq.command.ProducerInfo;
+import org.apache.activemq.command.RemoveSubscriptionInfo;
+import org.apache.activemq.command.Response;
+import org.apache.activemq.command.SessionInfo;
+import org.apache.activemq.command.TransactionId;
+import org.apache.activemq.store.PListStore;
+import org.apache.activemq.thread.Scheduler;
+import org.apache.activemq.usage.Usage;
+import org.junit.rules.TemporaryFolder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class ArtemisBrokerBase implements Broker {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(ArtemisBrokerBase.class);
+ public static final String INVM_ACCEPTOR_FACTORY = InVMAcceptorFactory.class
+ .getCanonicalName();
+
+ public static final String NETTY_ACCEPTOR_FACTORY = NettyAcceptorFactory.class
+ .getCanonicalName();
+
+ public static final String NETTY_CONNECTOR_FACTORY = NettyConnectorFactory.class
+ .getCanonicalName();
+
+ protected static final String CLUSTER_PASSWORD = "UnitTestsClusterPassword";
+
+ protected volatile boolean stopped;
+ protected BrokerId brokerId = new BrokerId("Artemis Broker");
+ protected BrokerService bservice;
+ protected TemporaryFolder temporaryFolder = new TemporaryFolder();
+ protected String testDir;
+ protected boolean realStore = false;
+
+ protected ActiveMQServer server;
+
+ protected boolean enableSecurity = false;
+
+ public ArtemisBrokerBase() {
+ try {
+ this.temporaryFolder.create();
+ } catch (IOException e) {
+ }
+ }
+ @Override
+ public Destination addDestination(ConnectionContext context,
+ ActiveMQDestination destination, boolean createIfTemporary)
+ throws Exception {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void removeDestination(ConnectionContext context,
+ ActiveMQDestination destination, long timeout) throws Exception {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public Map getDestinationMap() {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public Subscription addConsumer(ConnectionContext context, ConsumerInfo info)
+ throws Exception {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void removeConsumer(ConnectionContext context, ConsumerInfo info)
+ throws Exception {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void removeSubscription(ConnectionContext context,
+ RemoveSubscriptionInfo info) throws Exception {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void send(ProducerBrokerExchange producerExchange, Message message)
+ throws Exception {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void acknowledge(ConsumerBrokerExchange consumerExchange,
+ MessageAck ack) throws Exception {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public Response messagePull(ConnectionContext context, MessagePull pull)
+ throws Exception {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void processDispatchNotification(
+ MessageDispatchNotification messageDispatchNotification)
+ throws Exception {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void gc() {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public Set getDestinations(ActiveMQDestination destination) {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void processConsumerControl(ConsumerBrokerExchange consumerExchange,
+ ConsumerControl control) {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void reapplyInterceptor() {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public Broker getAdaptor(Class type) {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public BrokerId getBrokerId() {
+ return brokerId;
+ }
+
+ @Override
+ public String getBrokerName() {
+ return "Artemis Broker";
+ }
+
+ @Override
+ public void addBroker(Connection connection, BrokerInfo info) {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void removeBroker(Connection connection, BrokerInfo info) {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void addConnection(ConnectionContext context, ConnectionInfo info)
+ throws Exception {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void removeConnection(ConnectionContext context,
+ ConnectionInfo info, Throwable error) throws Exception {
+ throw new RuntimeException("Don't call me!");
+
+ }
+
+ @Override
+ public void addSession(ConnectionContext context, SessionInfo info)
+ throws Exception {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void removeSession(ConnectionContext context, SessionInfo info)
+ throws Exception {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void addProducer(ConnectionContext context, ProducerInfo info)
+ throws Exception {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void removeProducer(ConnectionContext context, ProducerInfo info)
+ throws Exception {
+ throw new RuntimeException("Don't call me!");
+
+ }
+
+ @Override
+ public Connection[] getClients() throws Exception {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public ActiveMQDestination[] getDestinations() throws Exception {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public Map getDestinationMap(
+ ActiveMQDestination destination) {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public TransactionId[] getPreparedTransactions(ConnectionContext context)
+ throws Exception {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void beginTransaction(ConnectionContext context, TransactionId xid)
+ throws Exception {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public int prepareTransaction(ConnectionContext context, TransactionId xid)
+ throws Exception {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void rollbackTransaction(ConnectionContext context, TransactionId xid)
+ throws Exception {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void commitTransaction(ConnectionContext context, TransactionId xid,
+ boolean onePhase) throws Exception {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void forgetTransaction(ConnectionContext context,
+ TransactionId transactionId) throws Exception {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public BrokerInfo[] getPeerBrokerInfos() {
+ return null;
+ }
+
+ @Override
+ public void preProcessDispatch(MessageDispatch messageDispatch) {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void postProcessDispatch(MessageDispatch messageDispatch) {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public boolean isStopped() {
+ return stopped;
+ }
+
+ @Override
+ public Set getDurableDestinations() {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void addDestinationInfo(ConnectionContext context,
+ DestinationInfo info) throws Exception {
+ throw new RuntimeException("Don't call me!");
+
+ }
+
+ @Override
+ public void removeDestinationInfo(ConnectionContext context,
+ DestinationInfo info) throws Exception {
+ throw new RuntimeException("Don't call me!");
+
+ }
+
+ @Override
+ public boolean isFaultTolerantConfiguration() {
+ return false;
+ }
+
+ @Override
+ public ConnectionContext getAdminConnectionContext() {
+ return null;
+ }
+
+ @Override
+ public void setAdminConnectionContext(
+ ConnectionContext adminConnectionContext) {
+ //
+ }
+
+ @Override
+ public PListStore getTempDataStore() {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public URI getVmConnectorURI() {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void brokerServiceStarted() {
+ stopped = false;
+ }
+
+ @Override
+ public BrokerService getBrokerService() {
+ return this.bservice;
+ }
+
+ @Override
+ public Broker getRoot() {
+ return this;
+ }
+
+ @Override
+ public boolean isExpired(MessageReference messageReference) {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void messageExpired(ConnectionContext context,
+ MessageReference messageReference, Subscription subscription) {
+ throw new RuntimeException("Don't call me!");
+
+ }
+
+ @Override
+ public boolean sendToDeadLetterQueue(ConnectionContext context,
+ MessageReference messageReference, Subscription subscription,
+ Throwable poisonCause) {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public long getBrokerSequenceId() {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void messageConsumed(ConnectionContext context,
+ MessageReference messageReference) {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void messageDelivered(ConnectionContext context,
+ MessageReference messageReference) {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void messageDiscarded(ConnectionContext context, Subscription sub,
+ MessageReference messageReference) {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void slowConsumer(ConnectionContext context,
+ Destination destination, Subscription subs) {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void fastProducer(ConnectionContext context,
+ ProducerInfo producerInfo, ActiveMQDestination destination) {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void isFull(ConnectionContext context, Destination destination,
+ Usage usage) {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void nowMasterBroker() {
+ }
+
+ @Override
+ public Scheduler getScheduler() {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public ThreadPoolExecutor getExecutor() {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void networkBridgeStarted(BrokerInfo brokerInfo,
+ boolean createdByDuplex, String remoteIp) {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ @Override
+ public void networkBridgeStopped(BrokerInfo brokerInfo) {
+ throw new RuntimeException("Don't call me!");
+ }
+
+ protected final ActiveMQServer createServer(final boolean realFiles,
+ final boolean netty) throws Exception {
+ return createServer(realFiles, createDefaultConfig(netty), -1, -1,
+ new HashMap());
+ }
+
+ protected final ActiveMQServer createServer(final boolean realFiles,
+ final Configuration configuration, final int pageSize,
+ final int maxAddressSize,
+ final Map settings) {
+ return createServer(realFiles, configuration, pageSize, maxAddressSize,
+ AddressFullMessagePolicy.PAGE, settings);
+ }
+
+ protected final ActiveMQServer createServer(final boolean realFiles,
+ final Configuration configuration, final int pageSize,
+ final int maxAddressSize,
+ final AddressFullMessagePolicy fullPolicy,
+ final Map settings) {
+ ActiveMQServer server = ActiveMQServers.newActiveMQServer(configuration,
+ realFiles);
+ if (settings != null) {
+ for (Map.Entry setting : settings
+ .entrySet()) {
+ server.getAddressSettingsRepository().addMatch(
+ setting.getKey(), setting.getValue());
+ }
+ }
+
+ AddressSettings defaultSetting = new AddressSettings();
+ defaultSetting.setPageSizeBytes(pageSize);
+ defaultSetting.setMaxSizeBytes(maxAddressSize);
+ defaultSetting.setAddressFullMessagePolicy(fullPolicy);
+
+ server.getAddressSettingsRepository().addMatch("#", defaultSetting);
+
+ return server;
+ }
+
+ protected Configuration createDefaultConfig(final boolean netty)
+ throws Exception {
+ if (netty) {
+ return createDefaultConfig(new HashMap(),
+ INVM_ACCEPTOR_FACTORY, NETTY_ACCEPTOR_FACTORY);
+ } else {
+ return createDefaultConfig(new HashMap(),
+ INVM_ACCEPTOR_FACTORY);
+ }
+ }
+
+ protected Configuration createDefaultConfig(
+ final Map params, final String... acceptors)
+ throws Exception {
+ ConfigurationImpl configuration = createBasicConfig(-1)
+ .setJMXManagementEnabled(false)
+ .clearAcceptorConfigurations();
+
+ for (String acceptor : acceptors) {
+ TransportConfiguration transportConfig = new TransportConfiguration(
+ acceptor, params);
+ configuration.addAcceptorConfiguration(transportConfig);
+ }
+
+ return configuration;
+ }
+
+ protected final ConfigurationImpl createBasicConfig(final int serverID) {
+ ConfigurationImpl configuration = new ConfigurationImpl()
+ .setSecurityEnabled(false)
+ .setJournalMinFiles(2)
+ .setJournalFileSize(100 * 1024)
+ .setJournalType(getDefaultJournalType())
+ .setJournalDirectory(getJournalDir(serverID, false))
+ .setBindingsDirectory(getBindingsDir(serverID, false))
+ .setPagingDirectory(getPageDir(serverID, false))
+ .setLargeMessagesDirectory(getLargeMessagesDir(serverID, false))
+ .setJournalCompactMinFiles(0).setJournalCompactPercentage(0)
+ .setClusterPassword(CLUSTER_PASSWORD);
+
+ return configuration;
+ }
+
+ protected String getLargeMessagesDir(final int index, final boolean backup) {
+ return getLargeMessagesDir(testDir, index, backup);
+ }
+
+ protected static String getLargeMessagesDir(final String testDir,
+ final int index, final boolean backup) {
+ return getLargeMessagesDir(testDir)
+ + directoryNameSuffix(index, backup);
+ }
+
+ protected String getPageDir(final int index, final boolean backup) {
+ return getPageDir(testDir, index, backup);
+ }
+
+ protected static String getPageDir(final String testDir, final int index,
+ final boolean backup) {
+ return getPageDir(testDir) + directoryNameSuffix(index, backup);
+ }
+
+ protected String getBindingsDir(final int index, final boolean backup) {
+ return getBindingsDir(testDir, index, backup);
+ }
+
+ protected static String getBindingsDir(final String testDir,
+ final int index, final boolean backup) {
+ return getBindingsDir(testDir) + directoryNameSuffix(index, backup);
+ }
+
+ protected String getJournalDir(final int index, final boolean backup) {
+ return getJournalDir(testDir, index, backup);
+ }
+
+ protected static String getJournalDir(final String testDir,
+ final int index, final boolean backup) {
+ return getJournalDir(testDir) + directoryNameSuffix(index, backup);
+ }
+
+ private static String directoryNameSuffix(int index, boolean backup) {
+ if (index == -1)
+ return "";
+ return index + "-" + (backup ? "B" : "L");
+ }
+
+ protected static JournalType getDefaultJournalType() {
+ if (AsynchronousFileImpl.isLoaded()) {
+ return JournalType.ASYNCIO;
+ } else {
+ return JournalType.NIO;
+ }
+ }
+
+ protected final void clearDataRecreateServerDirs() {
+ clearDataRecreateServerDirs(testDir);
+ }
+
+ protected void clearDataRecreateServerDirs(final String testDir1) {
+ // Need to delete the root
+
+ File file = new File(testDir1);
+ deleteDirectory(file);
+ file.mkdirs();
+
+ recreateDirectory(getJournalDir(testDir1));
+ recreateDirectory(getBindingsDir(testDir1));
+ recreateDirectory(getPageDir(testDir1));
+ recreateDirectory(getLargeMessagesDir(testDir1));
+ recreateDirectory(getClientLargeMessagesDir(testDir1));
+ recreateDirectory(getTemporaryDir(testDir1));
+ }
+
+ protected String getTemporaryDir(final String testDir1) {
+ return testDir1 + "/temp";
+ }
+
+ protected String getClientLargeMessagesDir(final String testDir1) {
+ return testDir1 + "/client-large-msg";
+ }
+
+ protected static String getLargeMessagesDir(final String testDir1) {
+ return testDir1 + "/large-msg";
+ }
+
+ protected static String getPageDir(final String testDir1) {
+ return testDir1 + "/page";
+ }
+
+ protected static String getBindingsDir(final String testDir1) {
+ return testDir1 + "/bindings";
+ }
+
+ protected static String getJournalDir(final String testDir1) {
+ return testDir1 + "/journal";
+ }
+
+ protected static final void recreateDirectory(final String directory) {
+ File file = new File(directory);
+ deleteDirectory(file);
+ file.mkdirs();
+ }
+
+ protected static final boolean deleteDirectory(final File directory) {
+ if (directory.isDirectory()) {
+ String[] files = directory.list();
+ int num = 5;
+ int attempts = 0;
+ while (files == null && (attempts < num)) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ }
+ files = directory.list();
+ attempts++;
+ }
+
+ for (String file : files) {
+ File f = new File(directory, file);
+ if (!deleteDirectory(f)) {
+ LOG.warn("Failed to clean up file: " + f.getAbsolutePath());
+ }
+ }
+ }
+
+ return directory.delete();
+ }
+
+}
diff --git a/tests/activemq5-unit-tests/src/main/java/org/apache/activemq/broker/artemiswrapper/ArtemisBrokerWrapper.java b/tests/activemq5-unit-tests/src/main/java/org/apache/activemq/broker/artemiswrapper/ArtemisBrokerWrapper.java
new file mode 100644
index 0000000000..86580e1c75
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/main/java/org/apache/activemq/broker/artemiswrapper/ArtemisBrokerWrapper.java
@@ -0,0 +1,209 @@
+/**
+ * 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.broker.artemiswrapper;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.activemq.artemis.api.core.ActiveMQQueueExistsException;
+import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.api.core.TransportConfiguration;
+import org.apache.activemq.artemis.core.config.Configuration;
+import org.apache.activemq.artemis.core.config.impl.SecurityConfiguration;
+import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
+import org.apache.activemq.artemis.core.security.Role;
+import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
+import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManagerImpl;
+import org.apache.activemq.artemiswrapper.ArtemisBrokerHelper;
+import org.apache.activemq.broker.BrokerService;
+
+public class ArtemisBrokerWrapper extends ArtemisBrokerBase
+{
+
+ protected Map testQueues = new HashMap();
+
+ public ArtemisBrokerWrapper(BrokerService brokerService)
+ {
+ this.bservice = brokerService;
+ }
+
+ @Override
+ public void start() throws Exception
+ {
+ testDir = temporaryFolder.getRoot().getAbsolutePath();
+ clearDataRecreateServerDirs();
+ server = createServer(realStore, false);
+ HashMap params = new HashMap();
+ params.put(TransportConstants.PORT_PROP_NAME, "61616");
+ params.put(TransportConstants.PROTOCOLS_PROP_NAME, "OPENWIRE");
+ TransportConfiguration transportConfiguration = new TransportConfiguration(NETTY_ACCEPTOR_FACTORY, params);
+
+ Configuration serverConfig = server.getConfiguration();
+
+ Set acceptors0 = serverConfig.getAcceptorConfigurations();
+ Iterator iter0 = acceptors0.iterator();
+
+ while (iter0.hasNext())
+ {
+ System.out.println("===>: " + iter0.next());
+ }
+
+ Map addressSettings = serverConfig.getAddressesSettings();
+ String match = "jms.queue.#";
+ AddressSettings dlaSettings = new AddressSettings();
+ SimpleString dla = new SimpleString("jms.queue.ActiveMQ.DLQ");
+ dlaSettings.setDeadLetterAddress(dla);
+ addressSettings.put(match, dlaSettings);
+
+ serverConfig.getAcceptorConfigurations().add(transportConfiguration);
+ if (this.bservice.enableSsl())
+ {
+ params = new HashMap();
+ params.put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
+ params.put(TransportConstants.PORT_PROP_NAME, 61611);
+ params.put(TransportConstants.PROTOCOLS_PROP_NAME, "OPENWIRE");
+ params.put(TransportConstants.KEYSTORE_PATH_PROP_NAME, bservice.SERVER_SIDE_KEYSTORE);
+ params.put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, bservice.KEYSTORE_PASSWORD);
+ params.put(TransportConstants.KEYSTORE_PROVIDER_PROP_NAME, bservice.storeType);
+ if (bservice.SERVER_SIDE_TRUSTSTORE != null)
+ {
+ params.put(TransportConstants.NEED_CLIENT_AUTH_PROP_NAME, true);
+ params.put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME, bservice.SERVER_SIDE_TRUSTSTORE);
+ params.put(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, bservice.TRUSTSTORE_PASSWORD);
+ params.put(TransportConstants.TRUSTSTORE_PROVIDER_PROP_NAME, bservice.storeType);
+ }
+ TransportConfiguration sslTransportConfig = new TransportConfiguration(NETTY_ACCEPTOR_FACTORY, params);
+ serverConfig.getAcceptorConfigurations().add(sslTransportConfig);
+ }
+
+ for (Integer port : bservice.extraConnectors)
+ {
+ if (port.intValue() != 61616)
+ {
+ //extra port
+ params = new HashMap();
+ params.put(TransportConstants.PORT_PROP_NAME, port.intValue());
+ params.put(TransportConstants.PROTOCOLS_PROP_NAME, "OPENWIRE");
+ TransportConfiguration extraTransportConfiguration = new TransportConfiguration(NETTY_ACCEPTOR_FACTORY, params);
+ serverConfig.getAcceptorConfigurations().add(extraTransportConfiguration);
+ }
+ }
+
+ serverConfig.setSecurityEnabled(enableSecurity);
+
+ //extraServerConfig(serverConfig);
+
+ if (enableSecurity)
+ {
+ ActiveMQSecurityManagerImpl sm = (ActiveMQSecurityManagerImpl) server.getSecurityManager();
+ SecurityConfiguration securityConfig = sm.getConfiguration();
+ securityConfig.addRole("openwireSender", "sender");
+ securityConfig.addUser("openwireSender", "SeNdEr");
+ //sender cannot receive
+ Role senderRole = new Role("sender", true, false, false, false, true, true, false);
+
+ securityConfig.addRole("openwireReceiver", "receiver");
+ securityConfig.addUser("openwireReceiver", "ReCeIvEr");
+ //receiver cannot send
+ Role receiverRole = new Role("receiver", false, true, false, false, true, true, false);
+
+ securityConfig.addRole("openwireGuest", "guest");
+ securityConfig.addUser("openwireGuest", "GuEsT");
+
+ //guest cannot do anything
+ Role guestRole = new Role("guest", false, false, false, false, false, false, false);
+
+ securityConfig.addRole("openwireDestinationManager", "manager");
+ securityConfig.addUser("openwireDestinationManager", "DeStInAtIoN");
+
+ //guest cannot do anything
+ Role destRole = new Role("manager", false, false, false, false, true, true, false);
+
+ Map> settings = server.getConfiguration().getSecurityRoles();
+ if (settings == null)
+ {
+ settings = new HashMap>();
+ server.getConfiguration().setSecurityRoles(settings);
+ }
+ Set anySet = settings.get("#");
+ if (anySet == null)
+ {
+ anySet = new HashSet();
+ settings.put("#", anySet);
+ }
+ anySet.add(senderRole);
+ anySet.add(receiverRole);
+ anySet.add(guestRole);
+ anySet.add(destRole);
+ }
+/* no need to start jms server here
+ jmsServer = new JMSServerManagerImpl(server);
+ jmsServer.setContext(new InVMNamingContext());
+ jmsServer.start();
+*/
+ Set acceptors = serverConfig.getAcceptorConfigurations();
+ Iterator iter = acceptors.iterator();
+
+ while (iter.hasNext())
+ {
+ System.out.println(">: " + iter.next());
+ }
+ server.start();
+
+/*
+ registerConnectionFactory();
+ mbeanServer = MBeanServerFactory.createMBeanServer();
+*/
+
+ ArtemisBrokerHelper.setBroker(this.bservice);
+ stopped = false;
+
+ }
+
+ @Override
+ public void stop() throws Exception
+ {
+ server.stop();
+ testQueues.clear();
+ stopped = true;
+ }
+
+ public void makeSureQueueExists(String qname) throws Exception
+ {
+ synchronized (testQueues)
+ {
+ SimpleString coreQ = testQueues.get(qname);
+ if (coreQ == null)
+ {
+ coreQ = new SimpleString("jms.queue." + qname);
+ try
+ {
+ this.server.createQueue(coreQ, coreQ, null, false, false);
+ testQueues.put(qname, coreQ);
+ }
+ catch (ActiveMQQueueExistsException e)
+ {
+ //ignore
+ }
+ }
+ }
+ }
+}
diff --git a/tests/activemq5-unit-tests/src/main/java/org/apache/activemq/broker/artemiswrapper/InVMNameParser.java b/tests/activemq5-unit-tests/src/main/java/org/apache/activemq/broker/artemiswrapper/InVMNameParser.java
new file mode 100644
index 0000000000..293cdb023e
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/main/java/org/apache/activemq/broker/artemiswrapper/InVMNameParser.java
@@ -0,0 +1,74 @@
+/**
+ * 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.broker.artemiswrapper;
+
+import java.io.Serializable;
+import java.util.Properties;
+
+import javax.naming.CompoundName;
+import javax.naming.Name;
+import javax.naming.NameParser;
+import javax.naming.NamingException;
+
+/**
+ * @author Ovidiu Feodorov
+ * @version $Revision: 2868 $
+ *
+ */
+public class InVMNameParser implements NameParser, Serializable
+{
+ // Constants -----------------------------------------------------
+
+ private static final long serialVersionUID = 2925203703371001031L;
+
+ // Static --------------------------------------------------------
+
+ static Properties syntax;
+
+ static
+ {
+ InVMNameParser.syntax = new Properties();
+ InVMNameParser.syntax.put("jndi.syntax.direction", "left_to_right");
+ InVMNameParser.syntax.put("jndi.syntax.ignorecase", "false");
+ InVMNameParser.syntax.put("jndi.syntax.separator", "/");
+ }
+
+ // Attributes ----------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ // Public --------------------------------------------------------
+
+ public static Properties getSyntax()
+ {
+ return InVMNameParser.syntax;
+ }
+
+ public Name parse(final String name) throws NamingException
+ {
+ return new CompoundName(name, InVMNameParser.syntax);
+ }
+
+ // Package protected ---------------------------------------------
+
+ // Protected -----------------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ // Inner classes -------------------------------------------------
+
+}
diff --git a/tests/activemq5-unit-tests/src/main/java/org/apache/activemq/broker/artemiswrapper/InVMNamingContext.java b/tests/activemq5-unit-tests/src/main/java/org/apache/activemq/broker/artemiswrapper/InVMNamingContext.java
new file mode 100644
index 0000000000..017fa1775e
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/main/java/org/apache/activemq/broker/artemiswrapper/InVMNamingContext.java
@@ -0,0 +1,370 @@
+/**
+ * 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.broker.artemiswrapper;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.naming.Binding;
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NameAlreadyBoundException;
+import javax.naming.NameClassPair;
+import javax.naming.NameNotFoundException;
+import javax.naming.NameParser;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.RefAddr;
+import javax.naming.Reference;
+
+public class InVMNamingContext implements Context, Serializable
+{
+ // Constants -----------------------------------------------------
+
+ private static final long serialVersionUID = 385743957345L;
+
+ // Static --------------------------------------------------------
+
+ // Attributes ----------------------------------------------------
+
+ protected Map map;
+
+ protected NameParser parser = new InVMNameParser();
+
+ private String nameInNamespace = "";
+
+ // Constructors --------------------------------------------------
+
+ public InVMNamingContext()
+ {
+ map = Collections.synchronizedMap(new HashMap());
+ }
+
+ public InVMNamingContext(final String nameInNamespace)
+ {
+ this();
+ this.nameInNamespace = nameInNamespace;
+ }
+
+ // Context implementation ----------------------------------------
+
+ public Object lookup(final Name name) throws NamingException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object lookup(String name) throws NamingException
+ {
+ name = trimSlashes(name);
+ int i = name.indexOf("/");
+ String tok = i == -1 ? name : name.substring(0, i);
+ Object value = map.get(tok);
+ if (value == null)
+ {
+ throw new NameNotFoundException("Name not found: " + tok);
+ }
+ if (value instanceof InVMNamingContext && i != -1)
+ {
+ return ((InVMNamingContext)value).lookup(name.substring(i));
+ }
+ if (value instanceof Reference)
+ {
+ Reference ref = (Reference)value;
+ RefAddr refAddr = ref.get("nns");
+
+ // we only deal with references create by NonSerializableFactory
+ String key = (String)refAddr.getContent();
+ return NonSerializableFactory.lookup(key);
+ }
+ else
+ {
+ return value;
+ }
+ }
+
+ public void bind(final Name name, final Object obj) throws NamingException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void bind(final String name, final Object obj) throws NamingException
+ {
+ internalBind(name, obj, false);
+ }
+
+ public void rebind(final Name name, final Object obj) throws NamingException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void rebind(final String name, final Object obj) throws NamingException
+ {
+ internalBind(name, obj, true);
+ }
+
+ public void unbind(final Name name) throws NamingException
+ {
+ unbind(name.toString());
+ }
+
+ public void unbind(String name) throws NamingException
+ {
+ name = trimSlashes(name);
+ int i = name.indexOf("/");
+ boolean terminal = i == -1;
+ if (terminal)
+ {
+ map.remove(name);
+ }
+ else
+ {
+ String tok = name.substring(0, i);
+ InVMNamingContext c = (InVMNamingContext)map.get(tok);
+ if (c == null)
+ {
+ throw new NameNotFoundException("Context not found: " + tok);
+ }
+ c.unbind(name.substring(i));
+ }
+ }
+
+ public void rename(final Name oldName, final Name newName) throws NamingException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void rename(final String oldName, final String newName) throws NamingException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public NamingEnumeration list(final Name name) throws NamingException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public NamingEnumeration list(final String name) throws NamingException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public NamingEnumeration listBindings(final Name name) throws NamingException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public NamingEnumeration listBindings(String contextName) throws NamingException
+ {
+ contextName = trimSlashes(contextName);
+ if (!"".equals(contextName) && !".".equals(contextName))
+ {
+ try
+ {
+ return ((InVMNamingContext)lookup(contextName)).listBindings("");
+ }
+ catch (Throwable t)
+ {
+ throw new NamingException(t.getMessage());
+ }
+ }
+
+ List l = new ArrayList();
+ for (Object element : map.keySet())
+ {
+ String name = (String)element;
+ Object object = map.get(name);
+ l.add(new Binding(name, object));
+ }
+ return new NamingEnumerationImpl(l.iterator());
+ }
+
+ public void destroySubcontext(final Name name) throws NamingException
+ {
+ destroySubcontext(name.toString());
+ }
+
+ public void destroySubcontext(final String name) throws NamingException
+ {
+ map.remove(trimSlashes(name));
+ }
+
+ public Context createSubcontext(final Name name) throws NamingException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Context createSubcontext(String name) throws NamingException
+ {
+ name = trimSlashes(name);
+ if (map.get(name) != null)
+ {
+ throw new NameAlreadyBoundException(name);
+ }
+ InVMNamingContext c = new InVMNamingContext(getNameInNamespace());
+ map.put(name, c);
+ return c;
+ }
+
+ public Object lookupLink(final Name name) throws NamingException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object lookupLink(final String name) throws NamingException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public NameParser getNameParser(final Name name) throws NamingException
+ {
+ return getNameParser(name.toString());
+ }
+
+ public NameParser getNameParser(final String name) throws NamingException
+ {
+ return parser;
+ }
+
+ public Name composeName(final Name name, final Name prefix) throws NamingException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public String composeName(final String name, final String prefix) throws NamingException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object addToEnvironment(final String propName, final Object propVal) throws NamingException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object removeFromEnvironment(final String propName) throws NamingException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Hashtable getEnvironment() throws NamingException
+ {
+ Hashtable env = new Hashtable();
+ env.put("java.naming.factory.initial", "org.apache.activemq.artemis.jms.tests.tools.container.InVMInitialContextFactory");
+ return env;
+ }
+
+ public void close() throws NamingException
+ {
+ }
+
+ public String getNameInNamespace() throws NamingException
+ {
+ return nameInNamespace;
+ }
+
+ // Public --------------------------------------------------------
+
+ // Package protected ---------------------------------------------
+
+ // Protected -----------------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ private String trimSlashes(String s)
+ {
+ int i = 0;
+ while (true)
+ {
+ if (i == s.length() || s.charAt(i) != '/')
+ {
+ break;
+ }
+ i++;
+ }
+ s = s.substring(i);
+ i = s.length() - 1;
+ while (true)
+ {
+ if (i == -1 || s.charAt(i) != '/')
+ {
+ break;
+ }
+ i--;
+ }
+ return s.substring(0, i + 1);
+ }
+
+ private void internalBind(String name, final Object obj, final boolean rebind) throws NamingException
+ {
+ name = trimSlashes(name);
+ int i = name.lastIndexOf("/");
+ InVMNamingContext c = this;
+ if (i != -1)
+ {
+ String path = name.substring(0, i);
+ c = (InVMNamingContext)lookup(path);
+ }
+ name = name.substring(i + 1);
+ if (!rebind && c.map.get(name) != null)
+ {
+ throw new NameAlreadyBoundException(name);
+ }
+ c.map.put(name, obj);
+ }
+
+ // Inner classes -------------------------------------------------
+
+ private class NamingEnumerationImpl implements NamingEnumeration
+ {
+ private final Iterator iterator;
+
+ NamingEnumerationImpl(final Iterator bindingIterator)
+ {
+ iterator = bindingIterator;
+ }
+
+ public void close() throws NamingException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean hasMore() throws NamingException
+ {
+ return iterator.hasNext();
+ }
+
+ public T next() throws NamingException
+ {
+ return iterator.next();
+ }
+
+ public boolean hasMoreElements()
+ {
+ return iterator.hasNext();
+ }
+
+ public T nextElement()
+ {
+ return iterator.next();
+ }
+ }
+}
diff --git a/tests/activemq5-unit-tests/src/main/java/org/apache/activemq/broker/artemiswrapper/NonSerializableFactory.java b/tests/activemq5-unit-tests/src/main/java/org/apache/activemq/broker/artemiswrapper/NonSerializableFactory.java
new file mode 100644
index 0000000000..0c39f130f3
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/main/java/org/apache/activemq/broker/artemiswrapper/NonSerializableFactory.java
@@ -0,0 +1,111 @@
+/**
+ * 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.broker.artemiswrapper;
+
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NamingException;
+import javax.naming.RefAddr;
+import javax.naming.Reference;
+import javax.naming.StringRefAddr;
+import javax.naming.spi.ObjectFactory;
+
+//import org.jboss.util.naming.Util;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+/**
+ * used by the default context when running in embedded local configuration
+ *
+ * @author Andy Taylor
+ */
+public class NonSerializableFactory implements ObjectFactory
+{
+
+ public NonSerializableFactory()
+ {
+ }
+/*
+ public static void unbind(final Context ctx, final String strName) throws NamingException
+ {
+ Name name = ctx.getNameParser("").parse(strName);
+ int size = name.size();
+ String atom = name.get(size - 1);
+ Context parentCtx = Util.createSubcontext(ctx, name.getPrefix(size - 1));
+ String key = new StringBuilder().append(parentCtx.getNameInNamespace()).append("/").append(atom).toString();
+ NonSerializableFactory.getWrapperMap().remove(key);
+ Util.unbind(ctx, strName);
+ }
+
+ public static void rebind(final Context ctx, final String strName, final Object value) throws NamingException
+ {
+ Name name = ctx.getNameParser("").parse(strName);
+ int size = name.size();
+ String atom = name.get(size - 1);
+ Context parentCtx = Util.createSubcontext(ctx, name.getPrefix(size - 1));
+ String key = new StringBuilder().append(parentCtx.getNameInNamespace()).append("/").append(atom).toString();
+ NonSerializableFactory.getWrapperMap().put(key, value);
+ String className = value.getClass().getName();
+ String factory = NonSerializableFactory.class.getName();
+ StringRefAddr addr = new StringRefAddr("nns", key);
+ Reference memoryRef = new Reference(className, addr, factory, null);
+ parentCtx.rebind(atom, memoryRef);
+ }
+
+ public static void bind(final Context ctx, final String strName, final Object value) throws NamingException
+ {
+ Name name = ctx.getNameParser("").parse(strName);
+ int size = name.size();
+ String atom = name.get(size - 1);
+ Context parentCtx = Util.createSubcontext(ctx, name.getPrefix(size - 1));
+ String key = new StringBuilder().append(parentCtx.getNameInNamespace()).append("/").append(atom).toString();
+ NonSerializableFactory.getWrapperMap().put(key, value);
+ String className = value.getClass().getName();
+ String factory = NonSerializableFactory.class.getName();
+ StringRefAddr addr = new StringRefAddr("nns", key);
+ Reference memoryRef = new Reference(className, addr, factory, null);
+
+ parentCtx.bind(atom, memoryRef);
+ }
+*/
+ public static Object lookup(final String name) throws NamingException
+ {
+ if (NonSerializableFactory.getWrapperMap().get(name) == null)
+ {
+ throw new NamingException(name + " not found");
+ }
+ return NonSerializableFactory.getWrapperMap().get(name);
+ }
+
+ public Object getObjectInstance(final Object obj, final Name name, final Context nameCtx, final Hashtable, ?> env) throws Exception
+ {
+ Reference ref = (Reference) obj;
+ RefAddr addr = ref.get("nns");
+ String key = (String) addr.getContent();
+ return NonSerializableFactory.getWrapperMap().get(key);
+ }
+
+ public static Map getWrapperMap()
+ {
+ return NonSerializableFactory.wrapperMap;
+ }
+
+ private static Map wrapperMap = Collections.synchronizedMap(new HashMap());
+}
diff --git a/tests/activemq5-unit-tests/src/main/resources/META-INF/services/org.apache.activemq.artemis.spi.core.protocol.ProtocolManagerFactory b/tests/activemq5-unit-tests/src/main/resources/META-INF/services/org.apache.activemq.artemis.spi.core.protocol.ProtocolManagerFactory
new file mode 100644
index 0000000000..c76e40e79c
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/main/resources/META-INF/services/org.apache.activemq.artemis.spi.core.protocol.ProtocolManagerFactory
@@ -0,0 +1,2 @@
+org.apache.activemq.artemis.core.protocol.openwire.OpenWireProtocolManagerFactory
+
diff --git a/tests/activemq5-unit-tests/src/test/java/activemq-browse.properties b/tests/activemq5-unit-tests/src/test/java/activemq-browse.properties
new file mode 100644
index 0000000000..36559c7877
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/test/java/activemq-browse.properties
@@ -0,0 +1,61 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+# Remote addresses for the other brokers in mesh
+
+
+# 1a
+1a.name=1a-nc
+1a.uri=failover:(tcp://localhost:6106)?randomize=false
+1a.transport=tcp://localhost:6106
+1a.jmx=1090
+1a.data=target/data/1a_store
+
+# 1b
+1b.name=1b-nc
+1b.uri=failover:(tcp://localhost:6107)?randomize=false
+1b.transport=tcp://localhost:6107
+1b.jmx=1091
+1b.data=target/data/1b_store
+
+# 2a
+2a.name=2a-nc
+2a.uri=failover:(tcp://localhost:6108)?randomize=false
+2a.transport=tcp://localhost:6108
+2a.jmx=1092
+2a.data=target/data/2a_store
+
+# 2b
+2b.name=2b-nc
+2b.uri=failover:(tcp://localhost:6109)?randomize=false
+2b.transport=tcp://localhost:6109
+2b.jmx=1093
+2b.data=target/data/2b_store
+
+# 3a
+3a.name=3a-nc
+3a.uri=failover:(tcp://localhost:6110)?randomize=false
+3a.transport=tcp://localhost:6110
+3a.jmx=1094
+3a.data=target/data/3a_store
+
+# 3b
+3b.name=3b-nc
+3b.uri=failover:(tcp://localhost:6111)?randomize=false
+3b.transport=tcp://localhost:6111
+3b.jmx=1095
+3b.data=target/data/3b_store
diff --git a/tests/activemq5-unit-tests/src/test/java/activemq-partition.xml b/tests/activemq5-unit-tests/src/test/java/activemq-partition.xml
new file mode 100644
index 0000000000..4bb96f22a9
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/test/java/activemq-partition.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/activemq5-unit-tests/src/test/java/activemq.xml b/tests/activemq5-unit-tests/src/test/java/activemq.xml
new file mode 100644
index 0000000000..eb49ca08d0
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/test/java/activemq.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/activemq5-unit-tests/src/test/java/client.keystore b/tests/activemq5-unit-tests/src/test/java/client.keystore
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/activemq5-unit-tests/src/test/java/credentials.properties b/tests/activemq5-unit-tests/src/test/java/credentials.properties
new file mode 100644
index 0000000000..86f719940f
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/test/java/credentials.properties
@@ -0,0 +1,24 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+# Defines credentials that will be used by components (like web console) to access the broker
+
+activemq.username=system
+#activemq.password=manager
+activemq.password=ENC(mYRkg+4Q4hua1kvpCCI2hg==)
+#guest.password=password
+guest.password=ENC(Cf3Jf3tM+UrSOoaKU50od5CuBa8rxjoL)
\ No newline at end of file
diff --git a/tests/activemq5-unit-tests/src/test/java/dummy.keystore b/tests/activemq5-unit-tests/src/test/java/dummy.keystore
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/activemq5-unit-tests/src/test/java/jmx.access b/tests/activemq5-unit-tests/src/test/java/jmx.access
new file mode 100644
index 0000000000..4625b7dea4
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/test/java/jmx.access
@@ -0,0 +1,18 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+admin readwrite
\ No newline at end of file
diff --git a/tests/activemq5-unit-tests/src/test/java/jmx.password b/tests/activemq5-unit-tests/src/test/java/jmx.password
new file mode 100644
index 0000000000..053aa659f8
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/test/java/jmx.password
@@ -0,0 +1,18 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+admin activemq
\ No newline at end of file
diff --git a/tests/activemq5-unit-tests/src/test/java/jndi.properties b/tests/activemq5-unit-tests/src/test/java/jndi.properties
new file mode 100644
index 0000000000..d627de9c34
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/test/java/jndi.properties
@@ -0,0 +1,38 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+# START SNIPPET: jndi
+
+java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory
+
+# use the following property to configure the default connector
+java.naming.provider.url = vm://localhost
+
+# use the following property to specify the JNDI name the connection factory
+# should appear as.
+#connectionFactoryNames = connectionFactory, queueConnectionFactory, topicConnectionFactry
+
+# register some queues in JNDI using the form
+# queue.[jndiName] = [physicalName]
+queue.MyQueue = example.MyQueue
+
+
+# register some topics in JNDI using the form
+# topic.[jndiName] = [physicalName]
+topic.MyTopic = example.MyTopic
+
+# END SNIPPET: jndi
diff --git a/tests/activemq5-unit-tests/src/test/java/log4j.properties b/tests/activemq5-unit-tests/src/test/java/log4j.properties
new file mode 100644
index 0000000000..4704dbc325
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/test/java/log4j.properties
@@ -0,0 +1,46 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+#
+# The logging properties used during tests..
+#
+log4j.rootLogger=INFO, out, stdout
+
+#log4j.logger.org.apache.activemq.broker.scheduler=DEBUG
+#log4j.logger.org.apache.activemq.store.kahadb.scheduler=DEBUG
+#log4j.logger.org.apache.activemq.network.DemandForwardingBridgeSupport=DEBUG
+#log4j.logger.org.apache.activemq.transport.failover=TRACE
+#log4j.logger.org.apache.activemq.store.jdbc=TRACE
+#log4j.logger.org.apache.activemq.store.kahadb=TRACE
+#log4j.logger.org.apache.activemq.broker.region.cursors.AbstractStoreCursor=DEBUG
+#log4j.logger.org.apache.activemq.store.jdbc.JDBCMessageStore=DEBUG
+#log4j.logger.org.apache.activemq.store.kahadb.disk.journal=DEBUG
+#log4j.logger.org.apache.activemq.store.kahadb.AbstractKahaDBStore=DEBUG
+
+# CONSOLE appender not used by default
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d [%-15.15t] - %-5p %-30.30c{1} - %m%n
+#log4j.appender.stdout.layout.ConversionPattern=%d [%-15.15t] - %-5p %-30.30c{1} - %-10.10X{activemq.broker} %-20.20X{activemq.connector} %-10.10X{activemq.destination} - %m%n
+
+# File appender
+log4j.appender.out=org.apache.log4j.FileAppender
+log4j.appender.out.layout=org.apache.log4j.PatternLayout
+log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] - %-5p %-30.30c{1} - %m%n
+#log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] - %-5p %-30.30c{1} - %-10.10X{activemq.broker} %-20.20X{activemq.connector} %-10.10X{activemq.destination} - %m%n
+log4j.appender.out.file=target/activemq-test.log
+log4j.appender.out.append=true
diff --git a/tests/activemq5-unit-tests/src/test/java/login.config b/tests/activemq5-unit-tests/src/test/java/login.config
new file mode 100644
index 0000000000..1f5f77c805
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/test/java/login.config
@@ -0,0 +1,87 @@
+/**
+ * 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.
+ */
+activemq-domain {
+ org.apache.activemq.jaas.PropertiesLoginModule required
+ debug=true
+ org.apache.activemq.jaas.properties.user="org/apache/activemq/security/users.properties"
+ org.apache.activemq.jaas.properties.group="org/apache/activemq/security/groups.properties";
+};
+
+activemq-guest-domain {
+ org.apache.activemq.jaas.PropertiesLoginModule sufficient
+ debug=true
+ org.apache.activemq.jaas.properties.user="org/apache/activemq/security/users.properties"
+ org.apache.activemq.jaas.properties.group="org/apache/activemq/security/groups.properties";
+ org.apache.activemq.jaas.GuestLoginModule sufficient
+ debug=true
+ org.apache.activemq.jaas.guest.user="guest"
+ org.apache.activemq.jaas.guest.group="guests";
+};
+
+activemq-guest-when-no-creds-only-domain {
+ org.apache.activemq.jaas.GuestLoginModule sufficient
+ debug=true
+ credentialsInvalidate=true
+ org.apache.activemq.jaas.guest.user="guest"
+ org.apache.activemq.jaas.guest.group="guests";
+
+ org.apache.activemq.jaas.PropertiesLoginModule requisite
+ debug=true
+ org.apache.activemq.jaas.properties.user="org/apache/activemq/security/users.properties"
+ org.apache.activemq.jaas.properties.group="org/apache/activemq/security/groups.properties";
+};
+
+cert-login {
+ org.apache.activemq.jaas.TextFileCertificateLoginModule required
+ debug=true
+ org.apache.activemq.jaas.textfiledn.user="org/apache/activemq/security/users.properties"
+ org.apache.activemq.jaas.textfiledn.group="org/apache/activemq/security/groups.properties";
+
+};
+
+broker1 {
+ org.apache.activemq.jaas.TextFileCertificateLoginModule required
+ debug=true
+ org.apache.activemq.jaas.textfiledn.user="org/apache/activemq/security/users1.properties"
+ org.apache.activemq.jaas.textfiledn.group="org/apache/activemq/security/groups.properties";
+};
+
+broker2 {
+ org.apache.activemq.jaas.TextFileCertificateLoginModule required
+ debug=true
+ org.apache.activemq.jaas.textfiledn.user="org/apache/activemq/security/users2.properties"
+ org.apache.activemq.jaas.textfiledn.group="org/apache/activemq/security/groups.properties";
+};
+
+LDAPLogin {
+ org.apache.activemq.jaas.LDAPLoginModule required
+ debug=true
+ initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory
+ connectionURL="ldap://localhost:1024"
+ connectionUsername="uid=admin,ou=system"
+ connectionPassword=secret
+ connectionProtocol=s
+ authentication=simple
+ userBase="ou=User,ou=ActiveMQ,ou=system"
+ userSearchMatching="(uid={0})"
+ userSearchSubtree=false
+ roleBase="ou=Group,ou=ActiveMQ,ou=system"
+ roleName=cn
+ roleSearchMatching="(uid={1})"
+ roleSearchSubtree=true
+ ;
+};
\ No newline at end of file
diff --git a/tests/activemq5-unit-tests/src/test/java/openwire-control/org.apache.activemq.openwire.BrokerInfoData.bin b/tests/activemq5-unit-tests/src/test/java/openwire-control/org.apache.activemq.openwire.BrokerInfoData.bin
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/activemq5-unit-tests/src/test/java/openwire-control/org.apache.activemq.openwire.WireFormatInfoData.bin b/tests/activemq5-unit-tests/src/test/java/openwire-control/org.apache.activemq.openwire.WireFormatInfoData.bin
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/ActiveMQConnectionFactoryTest.java b/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/ActiveMQConnectionFactoryTest.java
new file mode 100644
index 0000000000..353f1d3262
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/ActiveMQConnectionFactoryTest.java
@@ -0,0 +1,261 @@
+/**
+ * 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;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import javax.jms.ExceptionListener;
+import javax.jms.JMSException;
+import javax.jms.Session;
+
+import org.apache.activemq.broker.BrokerRegistry;
+import org.apache.activemq.broker.BrokerService;
+import org.apache.activemq.broker.TransportConnector;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ActiveMQConnectionFactoryTest extends CombinationTestSupport {
+ private static final Logger LOG = LoggerFactory.getLogger(ActiveMQConnectionFactoryTest.class);
+
+ private ActiveMQConnection connection;
+ private BrokerService broker;
+
+ public void testUseURIToSetUseClientIDPrefixOnConnectionFactory() throws URISyntaxException, JMSException {
+ ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory(
+ "vm://localhost?jms.clientIDPrefix=Cheese");
+ assertEquals("Cheese", cf.getClientIDPrefix());
+
+ connection = (ActiveMQConnection)cf.createConnection();
+ connection.start();
+
+ String clientID = connection.getClientID();
+ LOG.info("Got client ID: " + clientID);
+
+ assertTrue("should start with Cheese! but was: " + clientID, clientID.startsWith("Cheese"));
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ // Try our best to close any previously opend connection.
+ try {
+ connection.close();
+ } catch (Throwable ignore) {
+ }
+ // Try our best to stop any previously started broker.
+ try {
+ broker.stop();
+ } catch (Throwable ignore) {
+ }
+ }
+
+ public void testUseURIToSetOptionsOnConnectionFactory() throws URISyntaxException, JMSException {
+ ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("vm://localhost?jms.useAsyncSend=true");
+ assertTrue(cf.isUseAsyncSend());
+ // the broker url have been adjusted.
+ assertEquals("vm://localhost", cf.getBrokerURL());
+
+ cf = new ActiveMQConnectionFactory("vm://localhost?jms.useAsyncSend=false");
+ assertFalse(cf.isUseAsyncSend());
+ // the broker url have been adjusted.
+ assertEquals("vm://localhost", cf.getBrokerURL());
+
+ cf = new ActiveMQConnectionFactory("vm:(broker:()/localhost)?jms.useAsyncSend=true");
+ assertTrue(cf.isUseAsyncSend());
+ // the broker url have been adjusted.
+ assertEquals("vm:(broker:()/localhost)", cf.getBrokerURL());
+
+ cf = new ActiveMQConnectionFactory("vm://localhost?jms.auditDepth=5000");
+ assertEquals(5000, cf.getAuditDepth());
+ }
+
+ public void testUseURIToConfigureRedeliveryPolicy() throws URISyntaxException, JMSException {
+ ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory(
+ "vm://localhost?jms.redeliveryPolicy.maximumRedeliveries=2");
+ assertEquals("connection redeliveries", 2, cf.getRedeliveryPolicy().getMaximumRedeliveries());
+
+ ActiveMQConnection connection = (ActiveMQConnection)cf.createConnection();
+ assertEquals("connection redeliveries", 2, connection.getRedeliveryPolicy().getMaximumRedeliveries());
+
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ ActiveMQMessageConsumer consumer = (ActiveMQMessageConsumer)session.createConsumer(session
+ .createQueue("FOO.BAR"));
+ assertEquals("consumer redeliveries", 2, consumer.getRedeliveryPolicy().getMaximumRedeliveries());
+ connection.close();
+ }
+
+ public void testCreateVMConnectionWithEmbdeddBroker() throws URISyntaxException, JMSException {
+ ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("vm://myBroker2?broker.persistent=false");
+ // Make sure the broker is not created until the connection is
+ // instantiated.
+ assertNull(BrokerRegistry.getInstance().lookup("myBroker2"));
+ connection = (ActiveMQConnection)cf.createConnection();
+ // This should create the connection.
+ assertNotNull(connection);
+ // Verify the broker was created.
+ assertNotNull(BrokerRegistry.getInstance().lookup("myBroker2"));
+
+ connection.close();
+
+ // Verify the broker was destroyed.
+ assertNull(BrokerRegistry.getInstance().lookup("myBroker2"));
+ }
+
+ public void testGetBrokerName() throws URISyntaxException, JMSException {
+ ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false");
+ connection = (ActiveMQConnection)cf.createConnection();
+ connection.start();
+
+ String brokerName = connection.getBrokerName();
+ LOG.info("Got broker name: " + brokerName);
+
+ assertNotNull("No broker name available!", brokerName);
+ }
+
+ public void testCreateTcpConnectionUsingAllocatedPort() throws Exception {
+ assertCreateConnection("tcp://localhost:0?wireFormat.tcpNoDelayEnabled=true");
+ }
+
+ public void testCreateTcpConnectionUsingKnownPort() throws Exception {
+ assertCreateConnection("tcp://localhost:61610?wireFormat.tcpNoDelayEnabled=true");
+ }
+
+ public void testCreateTcpConnectionUsingKnownLocalPort() throws Exception {
+ broker = new BrokerService();
+ broker.setPersistent(false);
+ broker.addConnector("tcp://localhost:61610?wireFormat.tcpNoDelayEnabled=true");
+ broker.start();
+
+ // This should create the connection.
+ ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("tcp://localhost:61610/localhost:51610");
+ connection = (ActiveMQConnection)cf.createConnection();
+ assertNotNull(connection);
+
+ connection.close();
+
+ broker.stop();
+ }
+
+ public void testConnectionFailsToConnectToVMBrokerThatIsNotRunning() throws Exception {
+ ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://localhost?create=false");
+ try {
+ factory.createConnection();
+ fail("Expected connection failure.");
+ } catch (JMSException e) {
+ }
+ }
+
+ public void testFactorySerializable() throws Exception {
+ String clientID = "TestClientID";
+ ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory();
+ cf.setClientID(clientID);
+ ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
+ ObjectOutputStream objectsOut = new ObjectOutputStream(bytesOut);
+ objectsOut.writeObject(cf);
+ objectsOut.flush();
+ byte[] data = bytesOut.toByteArray();
+ ByteArrayInputStream bytesIn = new ByteArrayInputStream(data);
+ ObjectInputStream objectsIn = new ObjectInputStream(bytesIn);
+ cf = (ActiveMQConnectionFactory)objectsIn.readObject();
+ assertEquals(cf.getClientID(), clientID);
+ }
+
+ public void testSetExceptionListener() throws Exception {
+ ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false");
+ connection = (ActiveMQConnection)cf.createConnection();
+ assertNull(connection.getExceptionListener());
+
+ ExceptionListener exListener = new ExceptionListener() {
+ @Override
+ public void onException(JMSException arg0) {
+ }
+ };
+ cf.setExceptionListener(exListener);
+ connection.close();
+
+ connection = (ActiveMQConnection)cf.createConnection();
+ assertNotNull(connection.getExceptionListener());
+ assertEquals(exListener, connection.getExceptionListener());
+ connection.close();
+
+ connection = (ActiveMQConnection)cf.createConnection();
+ assertEquals(exListener, connection.getExceptionListener());
+
+ assertEquals(exListener, cf.getExceptionListener());
+ connection.close();
+
+ }
+
+
+ public void testSetClientInternalExceptionListener() throws Exception {
+ ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false");
+ connection = (ActiveMQConnection)cf.createConnection();
+ assertNull(connection.getClientInternalExceptionListener());
+
+ ClientInternalExceptionListener listener = new ClientInternalExceptionListener() {
+ @Override
+ public void onException(Throwable exception) {
+ }
+ };
+ connection.setClientInternalExceptionListener(listener);
+ cf.setClientInternalExceptionListener(listener);
+ connection.close();
+
+ connection = (ActiveMQConnection)cf.createConnection();
+ assertNotNull(connection.getClientInternalExceptionListener());
+ assertEquals(listener, connection.getClientInternalExceptionListener());
+ connection.close();
+
+ connection = (ActiveMQConnection)cf.createConnection();
+ assertEquals(listener, connection.getClientInternalExceptionListener());
+ assertEquals(listener, cf.getClientInternalExceptionListener());
+ connection.close();
+
+ }
+
+ protected void assertCreateConnection(String uri) throws Exception {
+ // Start up a broker with a tcp connector.
+ broker = new BrokerService();
+ broker.setPersistent(false);
+ broker.setUseJmx(false);
+ TransportConnector connector = broker.addConnector(uri);
+ broker.start();
+
+ URI temp = new URI(uri);
+ // URI connectURI = connector.getServer().getConnectURI();
+ // TODO this sometimes fails when using the actual local host name
+ URI currentURI = new URI(connector.getPublishableConnectString());
+
+ // sometimes the actual host name doesn't work in this test case
+ // e.g. on OS X so lets use the original details but just use the actual
+ // port
+ URI connectURI = new URI(temp.getScheme(), temp.getUserInfo(), temp.getHost(), currentURI.getPort(),
+ temp.getPath(), temp.getQuery(), temp.getFragment());
+
+ LOG.info("connection URI is: " + connectURI);
+
+ // This should create the connection.
+ ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory(connectURI);
+ connection = (ActiveMQConnection)cf.createConnection();
+ assertNotNull(connection);
+ }
+
+}
diff --git a/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/ActiveMQInputStreamTest.java b/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/ActiveMQInputStreamTest.java
new file mode 100644
index 0000000000..77f422e159
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/ActiveMQInputStreamTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.jms.Queue;
+import javax.jms.Session;
+
+import junit.framework.TestCase;
+
+import org.apache.activemq.broker.BrokerService;
+import org.apache.activemq.command.ActiveMQDestination;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Deprecated
+public class ActiveMQInputStreamTest extends TestCase {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ActiveMQInputStreamTest.class);
+
+ private static final String BROKER_URL = "tcp://localhost:0";
+ private static final String DESTINATION = "destination";
+ private static final int STREAM_LENGTH = 64 * 1024 + 0; // change 0 to 1 to make it not crash
+
+ private BrokerService broker;
+ private String connectionUri;
+
+ @Override
+ public void setUp() throws Exception {
+ broker = new BrokerService();
+ broker.setUseJmx(false);
+ broker.setPersistent(false);
+ broker.setDestinations(new ActiveMQDestination[] {
+ ActiveMQDestination.createDestination(DESTINATION, ActiveMQDestination.QUEUE_TYPE),
+ });
+ broker.addConnector(BROKER_URL);
+ broker.start();
+ broker.waitUntilStarted();
+
+ connectionUri = broker.getTransportConnectors().get(0).getPublishableConnectString();
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ broker.stop();
+ broker.waitUntilStopped();
+ }
+
+ public void testInputStreamSetSyncSendOption() throws Exception {
+
+ ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(connectionUri);
+ ActiveMQConnection connection = (ActiveMQConnection) connectionFactory.createConnection();
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Queue destination = session.createQueue(DESTINATION + "?producer.alwaysSyncSend=true");
+
+ OutputStream out = null;
+ try {
+ out = connection.createOutputStream(destination);
+
+ assertTrue(((ActiveMQOutputStream)out).isAlwaysSyncSend());
+
+ LOG.debug("writing...");
+ for (int i = 0; i < STREAM_LENGTH; ++i) {
+ out.write(0);
+ }
+ LOG.debug("wrote " + STREAM_LENGTH + " bytes");
+ } finally {
+ if (out != null) {
+ out.close();
+ }
+ }
+
+ InputStream in = null;
+ try {
+ in = connection.createInputStream(destination);
+ LOG.debug("reading...");
+ int count = 0;
+ while (-1 != in.read()) {
+ ++count;
+ }
+ LOG.debug("read " + count + " bytes");
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+
+ connection.close();
+ }
+
+ public void testInputStreamMatchesDefaultChuckSize() throws Exception {
+
+ ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(connectionUri);
+ ActiveMQConnection connection = (ActiveMQConnection) connectionFactory.createConnection();
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Queue destination = session.createQueue(DESTINATION);
+
+ OutputStream out = null;
+ try {
+ out = connection.createOutputStream(destination);
+ LOG.debug("writing...");
+ for (int i = 0; i < STREAM_LENGTH; ++i) {
+ out.write(0);
+ }
+ LOG.debug("wrote " + STREAM_LENGTH + " bytes");
+ } finally {
+ if (out != null) {
+ out.close();
+ }
+ }
+
+ InputStream in = null;
+ try {
+ in = connection.createInputStream(destination);
+ LOG.debug("reading...");
+ int count = 0;
+ while (-1 != in.read()) {
+ ++count;
+ }
+ LOG.debug("read " + count + " bytes");
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+
+ connection.close();
+ }
+}
diff --git a/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/ActiveMQMessageAuditTest.java b/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/ActiveMQMessageAuditTest.java
new file mode 100644
index 0000000000..af18084683
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/ActiveMQMessageAuditTest.java
@@ -0,0 +1,186 @@
+/**
+ * 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;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import junit.framework.TestCase;
+import org.apache.activemq.broker.region.MessageReference;
+import org.apache.activemq.command.ActiveMQMessage;
+import org.apache.activemq.command.MessageId;
+import org.apache.activemq.command.ProducerId;
+import org.apache.activemq.util.IdGenerator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * ActiveMQMessageAuditTest
+ *
+ *
+ */
+public class ActiveMQMessageAuditTest extends TestCase {
+
+ static final Logger LOG = LoggerFactory.getLogger(ActiveMQMessageAuditTest.class);
+
+ /**
+ * Constructor for ActiveMQMessageAuditTest.
+ *
+ * @param name
+ */
+ public ActiveMQMessageAuditTest(String name) {
+ super(name);
+ }
+
+ public static void main(String[] args) {
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ /**
+ * test case for isDuplicate
+ */
+ public void testIsDuplicateString() {
+ int count = 10000;
+ ActiveMQMessageAudit audit = new ActiveMQMessageAudit();
+ IdGenerator idGen = new IdGenerator();
+ // add to a list
+ List list = new ArrayList();
+ for (int i = 0; i < count; i++) {
+ String id = idGen.generateId();
+ list.add(id);
+ assertFalse(audit.isDuplicate(id));
+ }
+ List windowList = list.subList(list.size() -1 -audit.getAuditDepth(), list.size() -1);
+ for (String id : windowList) {
+ assertTrue("duplicate, id:" + id, audit.isDuplicate(id));
+ }
+ }
+
+ public void testIsDuplicateMessageReference() {
+ int count = 10000;
+ ActiveMQMessageAudit audit = new ActiveMQMessageAudit();
+ // add to a list
+ List list = new ArrayList();
+ for (int i = 0; i < count; i++) {
+ ProducerId pid = new ProducerId();
+ pid.setConnectionId("test");
+ pid.setSessionId(0);
+ pid.setValue(1);
+ MessageId id = new MessageId();
+ id.setProducerId(pid);
+ id.setProducerSequenceId(i);
+ ActiveMQMessage msg = new ActiveMQMessage();
+ msg.setMessageId(id);
+ list.add(msg);
+ assertFalse(audit.isDuplicate(msg.getMessageId()));
+ }
+ List windowList = list.subList(list.size() -1 -audit.getAuditDepth(), list.size() -1);
+ for (MessageReference msg : windowList) {
+ assertTrue("duplicate msg:" + msg, audit.isDuplicate(msg));
+ }
+ }
+
+ public void testIsInOrderString() {
+ int count = 10000;
+ ActiveMQMessageAudit audit = new ActiveMQMessageAudit();
+ IdGenerator idGen = new IdGenerator();
+ // add to a list
+ List list = new ArrayList();
+ for (int i = 0; i < count; i++) {
+ String id = idGen.generateId();
+ if (i==0) {
+ assertFalse(audit.isDuplicate(id));
+ assertTrue(audit.isInOrder(id));
+ }
+ if (i > 1 && i%2 != 0) {
+ list.add(id);
+ }
+
+ }
+ for (String id : list) {
+ assertFalse(audit.isInOrder(id));
+ assertFalse(audit.isDuplicate(id));
+ }
+ }
+
+ public void testSerialization() throws Exception {
+ ActiveMQMessageAuditNoSync audit = new ActiveMQMessageAuditNoSync();
+
+ byte[] bytes = serialize(audit);
+ LOG.debug("Length: " + bytes.length);
+ audit = recover(bytes);
+
+ List list = new ArrayList();
+
+ for (int j = 0; j < 1000; j++) {
+ ProducerId pid = new ProducerId();
+ pid.setConnectionId("test");
+ pid.setSessionId(0);
+ pid.setValue(j);
+ LOG.debug("producer " + j);
+
+ for (int i = 0; i < 1000; i++) {
+ MessageId id = new MessageId();
+ id.setProducerId(pid);
+ id.setProducerSequenceId(i);
+ ActiveMQMessage msg = new ActiveMQMessage();
+ msg.setMessageId(id);
+ list.add(msg);
+ assertFalse(audit.isDuplicate(msg.getMessageId().toString()));
+
+ if (i % 100 == 0) {
+ bytes = serialize(audit);
+ LOG.debug("Length: " + bytes.length);
+ audit = recover(bytes);
+ }
+
+ if (i % 250 == 0) {
+ for (MessageReference message : list) {
+ audit.rollback(message.getMessageId().toString());
+ }
+ list.clear();
+ bytes = serialize(audit);
+ LOG.debug("Length: " + bytes.length);
+ audit = recover(bytes);
+ }
+ }
+ }
+ }
+
+ protected byte[] serialize(ActiveMQMessageAuditNoSync audit) throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oout = new ObjectOutputStream(baos);
+ oout.writeObject(audit);
+ oout.flush();
+ return baos.toByteArray();
+ }
+
+ protected ActiveMQMessageAuditNoSync recover(byte[] bytes) throws Exception {
+ ObjectInputStream objectIn = new ObjectInputStream(new ByteArrayInputStream(bytes));
+ return (ActiveMQMessageAuditNoSync)objectIn.readObject();
+ }
+}
diff --git a/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/ActiveMQSslConnectionFactoryTest.java b/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/ActiveMQSslConnectionFactoryTest.java
new file mode 100644
index 0000000000..5d1ec8034e
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/ActiveMQSslConnectionFactoryTest.java
@@ -0,0 +1,262 @@
+/**
+ * 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;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.security.KeyStore;
+import java.security.SecureRandom;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+
+import org.apache.activemq.broker.BrokerService;
+import org.apache.activemq.broker.SslBrokerService;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class ActiveMQSslConnectionFactoryTest extends CombinationTestSupport {
+ private static final Log LOG = LogFactory.getLog(ActiveMQSslConnectionFactoryTest.class);
+
+ public static final String KEYSTORE_TYPE = "jks";
+ public static final String PASSWORD = "password";
+ public static final String SERVER_KEYSTORE = "src/test/resources/server.keystore";
+ public static final String TRUST_KEYSTORE = "src/test/resources/client.keystore";
+
+ private ActiveMQConnection connection;
+ private BrokerService broker;
+
+ @Override
+ protected void tearDown() throws Exception {
+ // Try our best to close any previously opend connection.
+ try {
+ connection.close();
+ } catch (Throwable ignore) {
+ }
+ // Try our best to stop any previously started broker.
+ try {
+ broker.stop();
+ } catch (Throwable ignore) {
+ }
+ }
+
+ public void testCreateTcpConnectionUsingKnownPort() throws Exception {
+ // Control case: check that the factory can create an ordinary (non-ssl) connection.
+ broker = createBroker("tcp://localhost:61610?wireFormat.tcpNoDelayEnabled=true");
+
+ // This should create the connection.
+ ActiveMQSslConnectionFactory cf = new ActiveMQSslConnectionFactory("tcp://localhost:61610?wireFormat.tcpNoDelayEnabled=true");
+ connection = (ActiveMQConnection)cf.createConnection();
+ assertNotNull(connection);
+ connection.start();
+ connection.stop();
+ brokerStop();
+ }
+
+ public void testCreateFailoverTcpConnectionUsingKnownPort() throws Exception {
+ // Control case: check that the factory can create an ordinary (non-ssl) connection.
+ broker = createBroker("tcp://localhost:61610?wireFormat.tcpNoDelayEnabled=true");
+
+ // This should create the connection.
+ ActiveMQSslConnectionFactory cf = new ActiveMQSslConnectionFactory("failover:(tcp://localhost:61610?wireFormat.tcpNoDelayEnabled=true)");
+ connection = (ActiveMQConnection)cf.createConnection();
+ assertNotNull(connection);
+ connection.start();
+ connection.stop();
+ brokerStop();
+ }
+
+ public void testCreateSslConnection() throws Exception {
+ // Create SSL/TLS connection with trusted cert from truststore.
+ String sslUri = "ssl://localhost:61611";
+ broker = createSslBroker(sslUri);
+ assertNotNull(broker);
+
+ // This should create the connection.
+ ActiveMQSslConnectionFactory cf = new ActiveMQSslConnectionFactory(sslUri);
+ cf.setTrustStore("server.keystore");
+ cf.setTrustStorePassword("password");
+ connection = (ActiveMQConnection)cf.createConnection();
+ LOG.info("Created client connection");
+ assertNotNull(connection);
+ connection.start();
+ connection.stop();
+ brokerStop();
+ }
+
+ public void testFailoverSslConnection() throws Exception {
+ // Create SSL/TLS connection with trusted cert from truststore.
+ String sslUri = "ssl://localhost:61611";
+ broker = createSslBroker(sslUri);
+ assertNotNull(broker);
+
+ // This should create the connection.
+ ActiveMQSslConnectionFactory cf = new ActiveMQSslConnectionFactory("failover:(" + sslUri + ")?maxReconnectAttempts=4");
+ cf.setTrustStore("server.keystore");
+ cf.setTrustStorePassword("password");
+ connection = (ActiveMQConnection)cf.createConnection();
+ LOG.info("Created client connection");
+ assertNotNull(connection);
+ connection.start();
+ connection.stop();
+
+ brokerStop();
+ }
+
+ public void testFailoverSslConnectionWithKeyAndTrustManagers() throws Exception {
+ String sslUri = "ssl://localhost:61611";
+ broker = createSslBroker(sslUri);
+ assertNotNull(broker);
+
+ ActiveMQSslConnectionFactory cf = new ActiveMQSslConnectionFactory("failover:(" + sslUri + ")?maxReconnectAttempts=4");
+ cf.setKeyAndTrustManagers(getKeyManager(), getTrustManager(), new SecureRandom());
+ connection = (ActiveMQConnection)cf.createConnection();
+ LOG.info("Created client connection");
+ assertNotNull(connection);
+ connection.start();
+ connection.stop();
+
+ brokerStop();
+ }
+
+ public void testNegativeCreateSslConnectionWithWrongPassword() throws Exception {
+ // Create SSL/TLS connection with trusted cert from truststore.
+ String sslUri = "ssl://localhost:61611";
+ broker = createSslBroker(sslUri);
+ assertNotNull(broker);
+
+ // This should FAIL to connect, due to wrong password.
+ ActiveMQSslConnectionFactory cf = new ActiveMQSslConnectionFactory(sslUri);
+ cf.setTrustStore("server.keystore");
+ cf.setTrustStorePassword("wrongPassword");
+ try {
+ connection = (ActiveMQConnection)cf.createConnection();
+ }
+ catch (javax.jms.JMSException ignore) {
+ // Expected exception
+ LOG.info("Expected java.io.Exception [" + ignore + "]");
+ }
+ assertNull(connection);
+
+ brokerStop();
+ }
+
+ public void testNegativeCreateSslConnectionWithWrongCert() throws Exception {
+ // Create SSL/TLS connection with trusted cert from truststore.
+ String sslUri = "ssl://localhost:61611";
+ broker = createSslBroker(sslUri);
+ assertNotNull(broker);
+
+ // This should FAIL to connect, due to wrong password.
+ ActiveMQSslConnectionFactory cf = new ActiveMQSslConnectionFactory(sslUri);
+ cf.setTrustStore("dummy.keystore");
+ cf.setTrustStorePassword("password");
+ try {
+ connection = (ActiveMQConnection)cf.createConnection();
+ }
+ catch (javax.jms.JMSException ignore) {
+ // Expected exception
+ LOG.info("Expected SSLHandshakeException [" + ignore + "]");
+ }
+ assertNull(connection);
+
+ brokerStop();
+ }
+
+ protected BrokerService createBroker(String uri) throws Exception {
+ // Start up a broker with a tcp connector.
+ BrokerService service = new BrokerService();
+ service.setPersistent(false);
+ service.setUseJmx(false);
+ service.addConnector(uri);
+ service.start();
+
+ return service;
+ }
+
+ protected BrokerService createSslBroker(String uri) throws Exception {
+
+ // http://java.sun.com/javase/javaseforbusiness/docs/TLSReadme.html
+ // work around: javax.net.ssl.SSLHandshakeException: renegotiation is not allowed
+ //System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");
+
+ SslBrokerService service = new SslBrokerService();
+ service.setPersistent(false);
+
+ service.setupSsl(KEYSTORE_TYPE, PASSWORD, SERVER_KEYSTORE);
+
+ service.start();
+
+ return service;
+ }
+
+ protected void brokerStop() throws Exception {
+ broker.stop();
+ }
+
+ public static TrustManager[] getTrustManager() throws Exception {
+ TrustManager[] trustStoreManagers = null;
+ KeyStore trustedCertStore = KeyStore.getInstance(ActiveMQSslConnectionFactoryTest.KEYSTORE_TYPE);
+
+ trustedCertStore.load(new FileInputStream(ActiveMQSslConnectionFactoryTest.TRUST_KEYSTORE), null);
+ TrustManagerFactory tmf =
+ TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+
+ tmf.init(trustedCertStore);
+ trustStoreManagers = tmf.getTrustManagers();
+ return trustStoreManagers;
+ }
+
+ public static KeyManager[] getKeyManager() throws Exception {
+ KeyManagerFactory kmf =
+ KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+ KeyStore ks = KeyStore.getInstance(ActiveMQSslConnectionFactoryTest.KEYSTORE_TYPE);
+ KeyManager[] keystoreManagers = null;
+
+ byte[] sslCert = loadClientCredential(ActiveMQSslConnectionFactoryTest.SERVER_KEYSTORE);
+
+
+ if (sslCert != null && sslCert.length > 0) {
+ ByteArrayInputStream bin = new ByteArrayInputStream(sslCert);
+ ks.load(bin, ActiveMQSslConnectionFactoryTest.PASSWORD.toCharArray());
+ kmf.init(ks, ActiveMQSslConnectionFactoryTest.PASSWORD.toCharArray());
+ keystoreManagers = kmf.getKeyManagers();
+ }
+ return keystoreManagers;
+ }
+
+ private static byte[] loadClientCredential(String fileName) throws IOException {
+ if (fileName == null) {
+ return null;
+ }
+ FileInputStream in = new FileInputStream(fileName);
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ byte[] buf = new byte[512];
+ int i = in.read(buf);
+ while (i > 0) {
+ out.write(buf, 0, i);
+ i = in.read(buf);
+ }
+ in.close();
+ return out.toByteArray();
+ }
+
+}
diff --git a/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/ActiveMQXAConnectionFactoryTest.java b/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/ActiveMQXAConnectionFactoryTest.java
new file mode 100644
index 0000000000..4b89851ffb
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/ActiveMQXAConnectionFactoryTest.java
@@ -0,0 +1,584 @@
+/**
+ * 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;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.TextMessage;
+import javax.jms.XAConnection;
+import javax.jms.XAQueueConnection;
+import javax.jms.XASession;
+import javax.jms.XATopicConnection;
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+
+import org.apache.activemq.broker.BrokerFactory;
+import org.apache.activemq.broker.BrokerRegistry;
+import org.apache.activemq.broker.BrokerService;
+import org.apache.activemq.broker.TransactionBroker;
+import org.apache.activemq.broker.TransportConnection;
+import org.apache.activemq.broker.TransportConnector;
+import org.apache.activemq.command.ActiveMQQueue;
+import org.apache.activemq.command.ActiveMQTextMessage;
+import org.apache.activemq.command.ConnectionId;
+import org.apache.activemq.command.TransactionInfo;
+import org.apache.activemq.command.XATransactionId;
+import org.apache.activemq.management.JMSConnectionStatsImpl;
+import org.apache.activemq.transport.failover.FailoverTransport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ActiveMQXAConnectionFactoryTest extends CombinationTestSupport {
+ private static final Logger LOG = LoggerFactory.getLogger(ActiveMQXAConnectionFactoryTest.class);
+ long txGenerator = System.currentTimeMillis();
+ private ActiveMQConnection connection;
+ private BrokerService broker;
+
+ @Override
+ public void tearDown() throws Exception {
+ // Try our best to close any previously opend connection.
+ try {
+ connection.close();
+ } catch (Throwable ignore) {
+ }
+ // Try our best to stop any previously started broker.
+ try {
+ broker.stop();
+ } catch (Throwable ignore) {
+ }
+ }
+
+ public void testCopy() throws URISyntaxException, JMSException {
+ ActiveMQXAConnectionFactory cf = new ActiveMQXAConnectionFactory("vm://localhost?");
+ ActiveMQConnectionFactory copy = cf.copy();
+ assertTrue("Should be an ActiveMQXAConnectionFactory", copy instanceof ActiveMQXAConnectionFactory);
+ }
+
+ public void testUseURIToSetOptionsOnConnectionFactory() throws URISyntaxException, JMSException {
+ ActiveMQXAConnectionFactory cf = new ActiveMQXAConnectionFactory(
+ "vm://localhost?jms.useAsyncSend=true");
+ assertTrue(cf.isUseAsyncSend());
+ // the broker url have been adjusted.
+ assertEquals("vm://localhost", cf.getBrokerURL());
+
+ cf = new ActiveMQXAConnectionFactory("vm://localhost?jms.useAsyncSend=false");
+ assertFalse(cf.isUseAsyncSend());
+ // the broker url have been adjusted.
+ assertEquals("vm://localhost", cf.getBrokerURL());
+
+ cf = new ActiveMQXAConnectionFactory("vm:(broker:()/localhost)?jms.useAsyncSend=true");
+ assertTrue(cf.isUseAsyncSend());
+ // the broker url have been adjusted.
+ assertEquals("vm:(broker:()/localhost)", cf.getBrokerURL());
+
+ cf = new ActiveMQXAConnectionFactory(
+ "vm://localhost?jms.redeliveryPolicy.maximumRedeliveries=10&" +
+ "jms.redeliveryPolicy.initialRedeliveryDelay=10000&" +
+ "jms.redeliveryPolicy.redeliveryDelay=10000&" +
+ "jms.redeliveryPolicy.useExponentialBackOff=true&" +
+ "jms.redeliveryPolicy.backOffMultiplier=2");
+ assertEquals(10, cf.getRedeliveryPolicy().getMaximumRedeliveries());
+ assertEquals(10000, cf.getRedeliveryPolicy().getInitialRedeliveryDelay());
+ assertEquals(10000, cf.getRedeliveryPolicy().getRedeliveryDelay());
+ assertEquals(true, cf.getRedeliveryPolicy().isUseExponentialBackOff());
+ assertEquals(2.0, cf.getRedeliveryPolicy().getBackOffMultiplier(), 0.1);
+
+ // the broker url have been adjusted.
+ assertEquals("vm://localhost", cf.getBrokerURL());
+ }
+
+ public void testCreateVMConnectionWithEmbdeddBroker() throws URISyntaxException, JMSException {
+ ActiveMQXAConnectionFactory cf = new ActiveMQXAConnectionFactory("vm://myBroker?broker.persistent=false");
+ // Make sure the broker is not created until the connection is
+ // instantiated.
+ assertNull(BrokerRegistry.getInstance().lookup("myBroker"));
+ connection = (ActiveMQConnection) cf.createConnection();
+ // This should create the connection.
+ assertNotNull(connection);
+ // Verify the broker was created.
+ assertNotNull(BrokerRegistry.getInstance().lookup("myBroker"));
+ connection.close();
+ // Verify the broker was destroyed.
+ assertNull(BrokerRegistry.getInstance().lookup("myBroker"));
+
+ connection.close();
+ }
+
+ public void testGetBrokerName() throws URISyntaxException, JMSException {
+ ActiveMQXAConnectionFactory cf = new ActiveMQXAConnectionFactory("vm://localhost?broker.persistent=false");
+ connection = (ActiveMQConnection)cf.createConnection();
+ connection.start();
+
+ String brokerName = connection.getBrokerName();
+ LOG.info("Got broker name: " + brokerName);
+
+ assertNotNull("No broker name available!", brokerName);
+ connection.close();
+ }
+
+ public void testCreateTcpConnectionUsingAllocatedPort() throws Exception {
+ assertCreateConnection("tcp://localhost:0?wireFormat.tcpNoDelayEnabled=true");
+ }
+
+ public void testCreateTcpConnectionUsingKnownPort() throws Exception {
+ assertCreateConnection("tcp://localhost:61610?wireFormat.tcpNoDelayEnabled=true");
+ }
+
+ public void testIsSameRM() throws URISyntaxException, JMSException, XAException {
+
+ XAConnection connection1 = null;
+ XAConnection connection2 = null;
+ try {
+ ActiveMQXAConnectionFactory cf1 = new ActiveMQXAConnectionFactory("vm://localhost?broker.persistent=false");
+ connection1 = (XAConnection)cf1.createConnection();
+ XASession session1 = connection1.createXASession();
+ XAResource resource1 = session1.getXAResource();
+
+ ActiveMQXAConnectionFactory cf2 = new ActiveMQXAConnectionFactory("vm://localhost?broker.persistent=false");
+ connection2 = (XAConnection)cf2.createConnection();
+ XASession session2 = connection2.createXASession();
+ XAResource resource2 = session2.getXAResource();
+
+ assertTrue(resource1.isSameRM(resource2));
+ session1.close();
+ session2.close();
+ } finally {
+ if (connection1 != null) {
+ try {
+ connection1.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ if (connection2 != null) {
+ try {
+ connection2.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+ }
+
+ public void testIsSameRMOverride() throws URISyntaxException, JMSException, XAException {
+
+ XAConnection connection1 = null;
+ XAConnection connection2 = null;
+ try {
+ ActiveMQXAConnectionFactory cf1 = new ActiveMQXAConnectionFactory("vm://localhost?broker.persistent=false&jms.rmIdFromConnectionId=true");
+ connection1 = (XAConnection)cf1.createConnection();
+ XASession session1 = connection1.createXASession();
+ XAResource resource1 = session1.getXAResource();
+
+ ActiveMQXAConnectionFactory cf2 = new ActiveMQXAConnectionFactory("vm://localhost?broker.persistent=false");
+ connection2 = (XAConnection)cf2.createConnection();
+ XASession session2 = connection2.createXASession();
+ XAResource resource2 = session2.getXAResource();
+
+ assertFalse(resource1.isSameRM(resource2));
+
+ // ensure identity is preserved
+ XASession session1a = connection1.createXASession();
+ assertTrue(resource1.isSameRM(session1a.getXAResource()));
+ session1.close();
+ session2.close();
+ } finally {
+ if (connection1 != null) {
+ try {
+ connection1.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ if (connection2 != null) {
+ try {
+ connection2.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+ }
+
+ public void testVanilaTransactionalProduceReceive() throws Exception {
+
+ XAConnection connection1 = null;
+ try {
+ ActiveMQXAConnectionFactory cf1 = new ActiveMQXAConnectionFactory("vm://localhost?broker.persistent=false");
+ connection1 = (XAConnection)cf1.createConnection();
+ connection1.start();
+ XASession session = connection1.createXASession();
+ XAResource resource = session.getXAResource();
+ Destination dest = new ActiveMQQueue(getName());
+
+ // publish a message
+ Xid tid = createXid();
+ resource.start(tid, XAResource.TMNOFLAGS);
+ MessageProducer producer = session.createProducer(dest);
+ ActiveMQTextMessage message = new ActiveMQTextMessage();
+ message.setText(getName());
+ producer.send(message);
+ resource.end(tid, XAResource.TMSUCCESS);
+ resource.commit(tid, true);
+ session.close();
+
+ session = connection1.createXASession();
+ MessageConsumer consumer = session.createConsumer(dest);
+ tid = createXid();
+ resource = session.getXAResource();
+ resource.start(tid, XAResource.TMNOFLAGS);
+ TextMessage receivedMessage = (TextMessage) consumer.receive(1000);
+ assertNotNull(receivedMessage);
+ assertEquals(getName(), receivedMessage.getText());
+ resource.end(tid, XAResource.TMSUCCESS);
+ resource.commit(tid, true);
+ session.close();
+
+ } finally {
+ if (connection1 != null) {
+ try {
+ connection1.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+ }
+
+ public void testConsumerCloseTransactionalSendReceive() throws Exception {
+
+ ActiveMQXAConnectionFactory cf1 = new ActiveMQXAConnectionFactory("vm://localhost?broker.persistent=false");
+ XAConnection connection1 = (XAConnection)cf1.createConnection();
+ connection1.start();
+ XASession session = connection1.createXASession();
+ XAResource resource = session.getXAResource();
+ Destination dest = new ActiveMQQueue(getName());
+
+ // publish a message
+ Xid tid = createXid();
+ resource.start(tid, XAResource.TMNOFLAGS);
+ MessageProducer producer = session.createProducer(dest);
+ ActiveMQTextMessage message = new ActiveMQTextMessage();
+ message.setText(getName());
+ producer.send(message);
+ producer.close();
+ resource.end(tid, XAResource.TMSUCCESS);
+ resource.commit(tid, true);
+ session.close();
+
+ session = connection1.createXASession();
+ MessageConsumer consumer = session.createConsumer(dest);
+ tid = createXid();
+ resource = session.getXAResource();
+ resource.start(tid, XAResource.TMNOFLAGS);
+ TextMessage receivedMessage = (TextMessage) consumer.receive(1000);
+ consumer.close();
+ assertNotNull(receivedMessage);
+ assertEquals(getName(), receivedMessage.getText());
+ resource.end(tid, XAResource.TMSUCCESS);
+ resource.commit(tid, true);
+
+ session = connection1.createXASession();
+ consumer = session.createConsumer(dest);
+ tid = createXid();
+ resource = session.getXAResource();
+ resource.start(tid, XAResource.TMNOFLAGS);
+ assertNull(consumer.receive(1000));
+ resource.end(tid, XAResource.TMSUCCESS);
+ resource.commit(tid, true);
+
+ }
+
+ public void testSessionCloseTransactionalSendReceive() throws Exception {
+
+ ActiveMQXAConnectionFactory cf1 = new ActiveMQXAConnectionFactory("vm://localhost?broker.persistent=false");
+ XAConnection connection1 = (XAConnection)cf1.createConnection();
+ connection1.start();
+ XASession session = connection1.createXASession();
+ XAResource resource = session.getXAResource();
+ Destination dest = new ActiveMQQueue(getName());
+
+ // publish a message
+ Xid tid = createXid();
+ resource.start(tid, XAResource.TMNOFLAGS);
+ MessageProducer producer = session.createProducer(dest);
+ ActiveMQTextMessage message = new ActiveMQTextMessage();
+ message.setText(getName());
+ producer.send(message);
+ session.close();
+ resource.end(tid, XAResource.TMSUCCESS);
+ resource.commit(tid, true);
+
+
+ session = connection1.createXASession();
+ MessageConsumer consumer = session.createConsumer(dest);
+ tid = createXid();
+ resource = session.getXAResource();
+ resource.start(tid, XAResource.TMNOFLAGS);
+ TextMessage receivedMessage = (TextMessage) consumer.receive(1000);
+ session.close();
+ assertNotNull(receivedMessage);
+ assertEquals(getName(), receivedMessage.getText());
+ resource.end(tid, XAResource.TMSUCCESS);
+ resource.commit(tid, true);
+
+ session = connection1.createXASession();
+ consumer = session.createConsumer(dest);
+ tid = createXid();
+ resource = session.getXAResource();
+ resource.start(tid, XAResource.TMNOFLAGS);
+ assertNull(consumer.receive(1000));
+ resource.end(tid, XAResource.TMSUCCESS);
+ resource.commit(tid, true);
+ }
+
+
+ public void testReadonlyNoLeak() throws Exception {
+ final String brokerName = "readOnlyNoLeak";
+ BrokerService broker = BrokerFactory.createBroker(new URI("broker:(tcp://localhost:0)/" + brokerName));
+ broker.setPersistent(false);
+ broker.start();
+ ActiveMQXAConnectionFactory cf1 = new ActiveMQXAConnectionFactory("failover:(" + broker.getTransportConnectors().get(0).getConnectUri() + ")");
+ cf1.setStatsEnabled(true);
+ ActiveMQXAConnection xaConnection = (ActiveMQXAConnection)cf1.createConnection();
+ xaConnection.start();
+ XASession session = xaConnection.createXASession();
+ XAResource resource = session.getXAResource();
+ Xid tid = createXid();
+ resource.start(tid, XAResource.TMNOFLAGS);
+ session.close();
+ resource.end(tid, XAResource.TMSUCCESS);
+ resource.commit(tid, true);
+
+ assertTransactionGoneFromBroker(tid);
+ assertTransactionGoneFromConnection(brokerName, xaConnection.getClientID(), xaConnection.getConnectionInfo().getConnectionId(), tid);
+ assertSessionGone(xaConnection, session);
+ assertTransactionGoneFromFailoverState(xaConnection, tid);
+
+ // two phase
+ session = xaConnection.createXASession();
+ resource = session.getXAResource();
+ tid = createXid();
+ resource.start(tid, XAResource.TMNOFLAGS);
+ session.close();
+ resource.end(tid, XAResource.TMSUCCESS);
+ assertEquals(XAResource.XA_RDONLY, resource.prepare(tid));
+
+ // no need for a commit on read only
+ assertTransactionGoneFromBroker(tid);
+ assertTransactionGoneFromConnection(brokerName, xaConnection.getClientID(), xaConnection.getConnectionInfo().getConnectionId(), tid);
+ assertSessionGone(xaConnection, session);
+ assertTransactionGoneFromFailoverState(xaConnection, tid);
+
+ xaConnection.close();
+ broker.stop();
+
+ }
+
+ public void testCloseSendConnection() throws Exception {
+ String brokerName = "closeSend";
+ BrokerService broker = BrokerFactory.createBroker(new URI("broker:(tcp://localhost:0)/" + brokerName));
+ broker.start();
+ broker.waitUntilStarted();
+ ActiveMQXAConnectionFactory cf = new ActiveMQXAConnectionFactory(broker.getTransportConnectors().get(0).getConnectUri());
+ XAConnection connection = (XAConnection)cf.createConnection();
+ connection.start();
+ XASession session = connection.createXASession();
+ XAResource resource = session.getXAResource();
+ Destination dest = new ActiveMQQueue(getName());
+
+ // publish a message
+ Xid tid = createXid();
+ resource.start(tid, XAResource.TMNOFLAGS);
+ MessageProducer producer = session.createProducer(dest);
+ ActiveMQTextMessage message = new ActiveMQTextMessage();
+ message.setText(getName());
+ producer.send(message);
+
+ connection.close();
+
+ assertTransactionGoneFromBroker(tid);
+
+ broker.stop();
+ }
+
+ public void testExceptionAfterClose() throws Exception {
+
+ ActiveMQXAConnectionFactory cf1 = new ActiveMQXAConnectionFactory("vm://localhost?broker.persistent=false");
+ XAConnection connection1 = (XAConnection)cf1.createConnection();
+ connection1.start();
+
+ XASession session = connection1.createXASession();
+ session.close();
+ try {
+ session.commit();
+ fail("expect exception after close");
+ } catch (javax.jms.IllegalStateException expected) {}
+
+ try {
+ session.rollback();
+ fail("expect exception after close");
+ } catch (javax.jms.IllegalStateException expected) {}
+
+ try {
+ session.getTransacted();
+ fail("expect exception after close");
+ } catch (javax.jms.IllegalStateException expected) {}
+ }
+
+ public void testRollbackXaErrorCode() throws Exception {
+ String brokerName = "rollbackErrorCode";
+ BrokerService broker = BrokerFactory.createBroker(new URI("broker:(tcp://localhost:0)/" + brokerName));
+ broker.start();
+ broker.waitUntilStarted();
+ ActiveMQXAConnectionFactory cf = new ActiveMQXAConnectionFactory(broker.getTransportConnectors().get(0).getConnectUri());
+ XAConnection connection = (XAConnection)cf.createConnection();
+ connection.start();
+ XASession session = connection.createXASession();
+ XAResource resource = session.getXAResource();
+
+ Xid tid = createXid();
+ try {
+ resource.rollback(tid);
+ fail("Expected xa exception on no tx");
+ } catch (XAException expected) {
+ LOG.info("got expected xa", expected);
+ assertEquals("no tx", XAException.XAER_NOTA, expected.errorCode);
+ }
+ connection.close();
+ broker.stop();
+ }
+
+ private void assertTransactionGoneFromFailoverState(
+ ActiveMQXAConnection connection1, Xid tid) throws Exception {
+
+ FailoverTransport transport = (FailoverTransport) connection1.getTransport().narrow(FailoverTransport.class);
+ TransactionInfo info = new TransactionInfo(connection1.getConnectionInfo().getConnectionId(), new XATransactionId(tid), TransactionInfo.COMMIT_ONE_PHASE);
+ assertNull("transaction should not exist in the state tracker",
+ transport.getStateTracker().processCommitTransactionOnePhase(info));
+ }
+
+ private void assertSessionGone(ActiveMQXAConnection connection1,
+ XASession session) {
+ JMSConnectionStatsImpl stats = (JMSConnectionStatsImpl)connection1.getStats();
+ // should be no dangling sessions maintained by the transaction
+ assertEquals("should be no sessions", 0, stats.getSessions().length);
+ }
+
+ private void assertTransactionGoneFromConnection(String brokerName, String clientId, ConnectionId connectionId, Xid tid) throws Exception {
+ BrokerService broker = BrokerRegistry.getInstance().lookup(brokerName);
+ CopyOnWriteArrayList connections = broker.getTransportConnectors().get(0).getConnections();
+ for (TransportConnection connection: connections) {
+ if (connection.getConnectionId().equals(clientId)) {
+ try {
+ connection.processPrepareTransaction(new TransactionInfo(connectionId, new XATransactionId(tid), TransactionInfo.PREPARE));
+ fail("did not get expected excepton on missing transaction, it must be still there in error!");
+ } catch (IllegalStateException expectedOnNoTransaction) {
+ }
+ }
+ }
+ }
+
+ private void assertTransactionGoneFromBroker(Xid tid) throws Exception {
+ BrokerService broker = BrokerRegistry.getInstance().lookup("localhost");
+ TransactionBroker transactionBroker = (TransactionBroker)broker.getBroker().getAdaptor(TransactionBroker.class);
+ try {
+ transactionBroker.getTransaction(null, new XATransactionId(tid), false);
+ fail("expected exception on tx not found");
+ } catch (XAException expectedOnNotFound) {
+ }
+ }
+
+ protected void assertCreateConnection(String uri) throws Exception {
+ // Start up a broker with a tcp connector.
+ broker = new BrokerService();
+ broker.setPersistent(false);
+ broker.setUseJmx(false);
+ TransportConnector connector = broker.addConnector(uri);
+ broker.start();
+
+ URI temp = new URI(uri);
+ // URI connectURI = connector.getServer().getConnectURI();
+ // TODO this sometimes fails when using the actual local host name
+ URI currentURI = new URI(connector.getPublishableConnectString());
+
+ // sometimes the actual host name doesn't work in this test case
+ // e.g. on OS X so lets use the original details but just use the actual
+ // port
+ URI connectURI = new URI(temp.getScheme(), temp.getUserInfo(), temp.getHost(), currentURI.getPort(),
+ temp.getPath(), temp.getQuery(), temp.getFragment());
+
+ LOG.info("connection URI is: " + connectURI);
+
+ // This should create the connection.
+ ActiveMQXAConnectionFactory cf = new ActiveMQXAConnectionFactory(connectURI);
+ Connection connection = cf.createConnection();
+
+ assertXAConnection(connection);
+
+ assertNotNull(connection);
+ connection.close();
+
+ connection = cf.createXAConnection();
+
+ assertXAConnection(connection);
+
+ assertNotNull(connection);
+ }
+
+ private void assertXAConnection(Connection connection) {
+ assertTrue("Should be an XAConnection", connection instanceof XAConnection);
+ assertTrue("Should be an XATopicConnection", connection instanceof XATopicConnection);
+ assertTrue("Should be an XAQueueConnection", connection instanceof XAQueueConnection);
+ }
+
+ public Xid createXid() throws IOException {
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ DataOutputStream os = new DataOutputStream(baos);
+ os.writeLong(++txGenerator);
+ os.close();
+ final byte[] bs = baos.toByteArray();
+
+ return new Xid() {
+ public int getFormatId() {
+ return 86;
+ }
+
+ public byte[] getGlobalTransactionId() {
+ return bs;
+ }
+
+ public byte[] getBranchQualifier() {
+ return bs;
+ }
+ };
+
+ }
+
+}
diff --git a/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/ClientTestSupport.java b/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/ClientTestSupport.java
new file mode 100644
index 0000000000..eafe359540
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/ClientTestSupport.java
@@ -0,0 +1,177 @@
+/**
+ * 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;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.jms.JMSException;
+
+import junit.framework.TestCase;
+
+import org.apache.activemq.broker.Broker;
+import org.apache.activemq.broker.BrokerFactory;
+import org.apache.activemq.broker.BrokerService;
+import org.apache.activemq.broker.StubConnection;
+import org.apache.activemq.broker.TransportConnector;
+import org.apache.activemq.command.ActiveMQDestination;
+import org.apache.activemq.command.ConnectionId;
+import org.apache.activemq.command.ConnectionInfo;
+import org.apache.activemq.command.ConsumerInfo;
+import org.apache.activemq.command.Message;
+import org.apache.activemq.command.MessageAck;
+import org.apache.activemq.command.MessageDispatch;
+import org.apache.activemq.command.RemoveInfo;
+import org.apache.activemq.command.SessionInfo;
+import org.apache.activemq.transport.TransportFactory;
+
+public class ClientTestSupport extends TestCase {
+
+ protected BrokerService broker;
+ protected long idGenerator;
+
+ private ActiveMQConnectionFactory connFactory;
+ private final String brokerURL = "vm://localhost?broker.persistent=false";
+
+ @Override
+ public void setUp() throws Exception {
+ final AtomicBoolean connected = new AtomicBoolean(false);
+ TransportConnector connector;
+
+ // Start up a broker with a tcp connector.
+ try {
+ broker = BrokerFactory.createBroker(new URI(this.brokerURL));
+ broker.getBrokerName();
+ connector = new TransportConnector(TransportFactory.bind(new URI(this.brokerURL))) {
+ // Hook into the connector so we can assert that the server
+ // accepted a connection.
+ @Override
+ protected org.apache.activemq.broker.Connection createConnection(org.apache.activemq.transport.Transport transport) throws IOException {
+ connected.set(true);
+ return super.createConnection(transport);
+ }
+ };
+ broker.addConnector(connector);
+ broker.start();
+
+ } catch (IOException e) {
+ throw new JMSException("Error creating broker " + e);
+ } catch (URISyntaxException e) {
+ throw new JMSException("Error creating broker " + e);
+ }
+
+ URI connectURI;
+ connectURI = connector.getServer().getConnectURI();
+
+ // This should create the connection.
+ connFactory = new ActiveMQConnectionFactory(connectURI);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ if (broker != null) {
+ broker.stop();
+ }
+ }
+
+ public ActiveMQConnectionFactory getConnectionFactory() throws JMSException {
+ if (this.connFactory == null) {
+ throw new JMSException("ActiveMQConnectionFactory is null ");
+ }
+ return this.connFactory;
+ }
+
+ // Helper Classes
+ protected ConnectionInfo createConnectionInfo() throws Exception {
+ ConnectionInfo info = new ConnectionInfo();
+ info.setConnectionId(new ConnectionId("connection:" + (++idGenerator)));
+ info.setClientId(info.getConnectionId().getValue());
+ return info;
+ }
+
+ protected SessionInfo createSessionInfo(ConnectionInfo connectionInfo) throws Exception {
+ SessionInfo info = new SessionInfo(connectionInfo, ++idGenerator);
+ return info;
+ }
+
+ protected ConsumerInfo createConsumerInfo(SessionInfo sessionInfo, ActiveMQDestination destination) throws Exception {
+ ConsumerInfo info = new ConsumerInfo(sessionInfo, ++idGenerator);
+ info.setBrowser(false);
+ info.setDestination(destination);
+ info.setPrefetchSize(1000);
+ info.setDispatchAsync(false);
+ return info;
+ }
+
+ protected RemoveInfo closeConsumerInfo(ConsumerInfo consumerInfo) {
+ return consumerInfo.createRemoveCommand();
+ }
+
+ protected MessageAck createAck(ConsumerInfo consumerInfo, Message msg, int count, byte ackType) {
+ MessageAck ack = new MessageAck();
+ ack.setAckType(ackType);
+ ack.setConsumerId(consumerInfo.getConsumerId());
+ ack.setDestination(msg.getDestination());
+ ack.setLastMessageId(msg.getMessageId());
+ ack.setMessageCount(count);
+ return ack;
+ }
+
+ protected Message receiveMessage(StubConnection connection, int maxWait) throws InterruptedException {
+ while (true) {
+ Object o = connection.getDispatchQueue().poll(maxWait, TimeUnit.MILLISECONDS);
+
+ if (o == null) {
+ return null;
+ }
+
+ if (o instanceof MessageDispatch) {
+ MessageDispatch dispatch = (MessageDispatch)o;
+ return dispatch.getMessage();
+ }
+ }
+ }
+
+ protected Broker getBroker() throws Exception {
+ return this.broker != null ? this.broker.getBroker() : null;
+ }
+
+ public static void removeMessageStore() {
+ if (System.getProperty("activemq.store.dir") != null) {
+ recursiveDelete(new File(System.getProperty("activemq.store.dir")));
+ }
+ if (System.getProperty("derby.system.home") != null) {
+ recursiveDelete(new File(System.getProperty("derby.system.home")));
+ }
+ }
+
+ public static void recursiveDelete(File f) {
+ if (f.isDirectory()) {
+ File[] files = f.listFiles();
+ for (int i = 0; i < files.length; i++) {
+ recursiveDelete(files[i]);
+ }
+ }
+ f.delete();
+ }
+
+}
diff --git a/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/CombinationTestSupport.java b/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/CombinationTestSupport.java
new file mode 100644
index 0000000000..a11505c610
--- /dev/null
+++ b/tests/activemq5-unit-tests/src/test/java/org/apache/activemq/CombinationTestSupport.java
@@ -0,0 +1,272 @@
+/**
+ * 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;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Poor mans way of getting JUnit to run a test case through a few different
+ * combinations of options. Usage: If you have a test case called testFoo what
+ * you want to run through a few combinations, of of values for the attributes
+ * age and color, you would something like:
+ * public void initCombosForTestFoo() {
+ * addCombinationValues( "age", new Object[]{ new Integer(21), new Integer(30) } );
+ * addCombinationValues( "color", new Object[]{"blue", "green"} );
+ * }
+ *
+ * The testFoo test case would be run for each possible combination of age and
+ * color that you setup in the initCombosForTestFoo method. Before each
+ * combination is run, the age and color fields of the test class are set to one
+ * of the values defined. This is done before the normal setUp method is called.
+ * If you want the test combinations to show up as separate test runs in the
+ * JUnit reports, add a suite method to your test case similar to:
+ * public static Test suite() {
+ * return suite(FooTest.class);
+ * }
+ *
+ *
+ *
+ */
+public abstract class CombinationTestSupport extends AutoFailTestSupport {
+
+ private static final Logger LOG = LoggerFactory.getLogger(CombinationTestSupport.class);
+
+ private final HashMap comboOptions = new HashMap();
+ private boolean combosEvaluated;
+ private Map options;
+ protected File basedir;
+
+ static protected File basedir(Class> clazz) {
+ try {
+ ProtectionDomain protectionDomain = clazz.getProtectionDomain();
+ return new File(new File(protectionDomain.getCodeSource().getLocation().getPath()), "../..").getCanonicalFile();
+ } catch (IOException e) {
+ return new File(".");
+ }
+ }
+
+ static class ComboOption {
+ final String attribute;
+ final LinkedHashSet