ARTEMIS-127 Adding activemq unit test module to Artemis

This test module brings in activemq unit tests and run them
against Artemis broker.
This commit is contained in:
Howard Gao 2015-06-08 10:45:30 +08:00 committed by Clebert Suconic
parent afe5b5cefe
commit 60979268e1
1630 changed files with 190668 additions and 0 deletions

View File

@ -70,6 +70,7 @@
<skipPerformanceTests>true</skipPerformanceTests>
<skipConcurrentTests>true</skipConcurrentTests>
<skipRestTests>true</skipRestTests>
<skipActiveMQ5Tests>true</skipActiveMQ5Tests>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
@ -949,6 +950,12 @@
<exclude>**/org/apache/activemq/artemis/utils/json/**</exclude>
<exclude>**/org/apache/activemq/artemis/utils/Base64.java</exclude>
<exclude>ratReport.txt</exclude>
<!-- activemq5 unit tests exclude -->
<exclude>**/*.data</exclude>
<exclude>**/*.bin</exclude>
<exclude>**/src/test/resources/keystore</exclude>
<exclude>**/*.log</exclude>
<exclude>**/*.redo</exclude>
</excludes>
</configuration>
<executions>

View File

@ -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.

View File

@ -0,0 +1,387 @@
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.activemq.tests</groupId>
<artifactId>artemis-tests-pom</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>activemq5-unit-tests</artifactId>
<packaging>jar</packaging>
<name>ActiveMQ5.x unit tests</name>
<properties>
<activemq.basedir>${project.basedir}/../..</activemq.basedir>
<activemq5.project.version>5.11.1</activemq5.project.version>
<jmdns-version>3.4.1</jmdns-version>
<ftpserver-version>1.0.6</ftpserver-version>
<jmock-version>2.5.1</jmock-version>
<spring-version>3.2.11.RELEASE</spring-version>
<org-apache-derby-version>10.11.1.1</org-apache-derby-version>
<commons-io-version>2.4</commons-io-version>
<commons-net-version>3.3</commons-net-version>
<qpid-jms-version>0.30</qpid-jms-version>
<xbean-version>3.18</xbean-version>
<hamcrest-version>1.3</hamcrest-version>
<slf4j-version>1.7.10</slf4j-version>
<jasypt-version>1.9.2</jasypt-version>
<directory-version>2.0.0-M6</directory-version>
<activeio-core-version>3.1.4</activeio-core-version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-client</artifactId>
<version>${activemq5.project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-jaas</artifactId>
<version>${activemq5.project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-broker</artifactId>
<version>${activemq5.project.version}</version>
<type>test-jar</type>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-jdbc-store</artifactId>
<version>${activemq5.project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-kahadb-store</artifactId>
<version>${activemq5.project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-leveldb-store</artifactId>
<version>${activemq5.project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>${activemq5.project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-spring</artifactId>
<version>${activemq5.project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-partition</artifactId>
<version>${activemq5.project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-stomp</artifactId>
<version>${activemq5.project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-console</artifactId>
<version>${activemq5.project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activeio-core</artifactId>
<version>${activeio-core-version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<version>4.3.1</version>
</dependency>
<dependency>
<groupId>javax.jmdns</groupId>
<artifactId>jmdns</artifactId>
<version>${jmdns-version}</version>
</dependency>
<dependency>
<groupId>org.apache.ftpserver</groupId>
<artifactId>ftpserver-core</artifactId>
<version>${ftpserver-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jmock</groupId>
<artifactId>jmock-junit4</artifactId>
<version>${jmock-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jmock</groupId>
<artifactId>jmock-legacy</artifactId>
<version>${jmock-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${spring-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>${org-apache-derby-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>${commons-net-version}</version>
</dependency>
<dependency>
<groupId>org.apache.qpid</groupId>
<artifactId>qpid-amqp-1-0-client-jms</artifactId>
<version>${qpid-jms-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.xbean</groupId>
<artifactId>xbean-spring</artifactId>
<version>${xbean-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>${hamcrest-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jasypt</groupId>
<artifactId>jasypt</artifactId>
<version>${jasypt-version}</version>
</dependency>
<dependency>
<groupId>org.jasypt</groupId>
<artifactId>jasypt-spring31</artifactId>
<version>${jasypt-version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.directory.server</groupId>
<artifactId>apacheds-core-integ</artifactId>
<version>${directory-version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>bouncycastle</groupId>
<artifactId>bcprov-jdk15</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15</artifactId>
<version>1.46</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.directory.server</groupId>
<artifactId>apacheds-server-integ</artifactId>
<version>${directory-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.fusesource.joram-jms-tests</groupId>
<artifactId>joram-jms-tests</artifactId>
<version>1.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>3.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.fusesource.mqtt-client</groupId>
<artifactId>mqtt-client</artifactId>
<version>1.10</version>
<scope>test</scope>
</dependency>
<!-- artemis modules -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-commons</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-openwire-protocol</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.rat</groupId>
<artifactId>apache-rat-plugin</artifactId>
<version>0.11</version>
<configuration>
<reportFile>${activemq.basedir}/ratReport.txt</reportFile>
<skip>${skipLicenseCheck}</skip>
<excludes>
<exclude>**/*.data</exclude>
<exclude>**/*.bin</exclude>
<exclude>**/*.log</exclude>
<exclude>**/*.redo</exclude>
<exclude>**/src/test/resources/keystore</exclude>
<exclude>**/META-INF/services/*</exclude>
<exclude>**/*/*.txt</exclude>
<exclude>**/*.md</exclude>
</excludes>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.12</version>
<configuration>
<skip>true</skip>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.5.3</version>
<inherited>true</inherited>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-Activator>org.apache.activemq.util.osgi.Activator</Bundle-Activator>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>${skipActiveMQ5Tests}</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

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

View File

@ -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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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<Integer> extraConnectors = new HashSet<Integer>();
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<TransportConnector> 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<NetworkConnector> 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<TransportConnector> 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<String, String> getTransportConnectorURIsAsMap()
{
return null;
}
public void setSslContext(SslContext sslContext)
{
}
public void setPersistenceFactory(PersistenceAdapterFactory persistenceFactory)
{
}
protected TransportConnector createTransportConnector(URI brokerURI) throws Exception
{
return null;
}
}

View File

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

View File

@ -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<ActiveMQDestination, Destination> 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<Destination> 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<ActiveMQDestination, Destination> 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<ActiveMQDestination> 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<String, AddressSettings>());
}
protected final ActiveMQServer createServer(final boolean realFiles,
final Configuration configuration, final int pageSize,
final int maxAddressSize,
final Map<String, AddressSettings> 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<String, AddressSettings> settings) {
ActiveMQServer server = ActiveMQServers.newActiveMQServer(configuration,
realFiles);
if (settings != null) {
for (Map.Entry<String, AddressSettings> 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<String, Object>(),
INVM_ACCEPTOR_FACTORY, NETTY_ACCEPTOR_FACTORY);
} else {
return createDefaultConfig(new HashMap<String, Object>(),
INVM_ACCEPTOR_FACTORY);
}
}
protected Configuration createDefaultConfig(
final Map<String, Object> 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();
}
}

View File

@ -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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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<String, SimpleString> testQueues = new HashMap<String, SimpleString>();
public ArtemisBrokerWrapper(BrokerService brokerService)
{
this.bservice = brokerService;
}
@Override
public void start() throws Exception
{
testDir = temporaryFolder.getRoot().getAbsolutePath();
clearDataRecreateServerDirs();
server = createServer(realStore, false);
HashMap<String, Object> params = new HashMap<String, Object>();
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<TransportConfiguration> acceptors0 = serverConfig.getAcceptorConfigurations();
Iterator<TransportConfiguration> iter0 = acceptors0.iterator();
while (iter0.hasNext())
{
System.out.println("===>: " + iter0.next());
}
Map<String, AddressSettings> 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<String, Object>();
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<String, Object>();
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<String, Set<Role>> settings = server.getConfiguration().getSecurityRoles();
if (settings == null)
{
settings = new HashMap<String, Set<Role>>();
server.getConfiguration().setSecurityRoles(settings);
}
Set<Role> anySet = settings.get("#");
if (anySet == null)
{
anySet = new HashSet<Role>();
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<TransportConfiguration> acceptors = serverConfig.getAcceptorConfigurations();
Iterator<TransportConfiguration> 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
}
}
}
}
}

View File

@ -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 <a href="mailto:ovidiu@feodorov.com">Ovidiu Feodorov</a>
* @version <tt>$Revision: 2868 $</tt>
*
*/
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 -------------------------------------------------
}

View File

@ -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<String, Object> map;
protected NameParser parser = new InVMNameParser();
private String nameInNamespace = "";
// Constructors --------------------------------------------------
public InVMNamingContext()
{
map = Collections.synchronizedMap(new HashMap<String, Object>());
}
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<NameClassPair> list(final Name name) throws NamingException
{
throw new UnsupportedOperationException();
}
public NamingEnumeration<NameClassPair> list(final String name) throws NamingException
{
throw new UnsupportedOperationException();
}
public NamingEnumeration<Binding> listBindings(final Name name) throws NamingException
{
throw new UnsupportedOperationException();
}
public NamingEnumeration<Binding> 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<Binding> l = new ArrayList<Binding>();
for (Object element : map.keySet())
{
String name = (String)element;
Object object = map.get(name);
l.add(new Binding(name, object));
}
return new NamingEnumerationImpl<Binding>(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<String, String> getEnvironment() throws NamingException
{
Hashtable<String, String> env = new Hashtable<String, String>();
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<T> implements NamingEnumeration<T>
{
private final Iterator<T> iterator;
NamingEnumerationImpl(final Iterator<T> 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();
}
}
}

View File

@ -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 <a href="ataylor@redhat.com">Andy Taylor</a>
*/
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<String, Object> getWrapperMap()
{
return NonSerializableFactory.wrapperMap;
}
private static Map<String, Object> wrapperMap = Collections.synchronizedMap(new HashMap<String, Object>());
}

View File

@ -0,0 +1,2 @@
org.apache.activemq.artemis.core.protocol.openwire.OpenWireProtocolManagerFactory

View File

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

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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: xbean -->
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
<bean id="config" class="java.lang.String">
<constructor-arg><value>
<![CDATA[
{
"by_client_id":{
"client1":{"ids":["broker1"]},
"client2":{"ids":["broker1","broker2"]}
},
"brokers":{
"broker1":"tcp://localhost:61616",
"broker2":"tcp://localhost:61616"
}
}
]]>
</value></constructor-arg>
</bean>
<broker useJmx="false" xmlns="http://activemq.apache.org/schema/core" persistent="false">
<plugins>
<partitionBrokerPlugin minTransferCount="5" configAsJson="#config"/>
</plugins>
<transportConnectors>
<transportConnector uri="tcp://localhost:61616"/>
</transportConnectors>
</broker>
</beans>
<!-- END SNIPPET: xbean -->

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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: xbean -->
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
<broker useJmx="false" xmlns="http://activemq.apache.org/schema/core" persistent="false">
<transportConnectors>
<transportConnector uri="nio://localhost:61616?wireFormat.maxFrameSize=1048576" />
</transportConnectors>
</broker>
</beans>
<!-- END SNIPPET: xbean -->

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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<String> list = new ArrayList<String>();
for (int i = 0; i < count; i++) {
String id = idGen.generateId();
list.add(id);
assertFalse(audit.isDuplicate(id));
}
List<String> 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<MessageReference> list = new ArrayList<MessageReference>();
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<MessageReference> 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<String> list = new ArrayList<String>();
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<MessageReference> list = new ArrayList<MessageReference>();
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();
}
}

View File

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

View File

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

View File

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

View File

@ -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: <code>
* public void initCombosForTestFoo() {
* addCombinationValues( "age", new Object[]{ new Integer(21), new Integer(30) } );
* addCombinationValues( "color", new Object[]{"blue", "green"} );
* }
* </code>
* 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: <code>
* public static Test suite() {
* return suite(FooTest.class);
* }
* </code>
*
*
*/
public abstract class CombinationTestSupport extends AutoFailTestSupport {
private static final Logger LOG = LoggerFactory.getLogger(CombinationTestSupport.class);
private final HashMap<String, ComboOption> comboOptions = new HashMap<String, ComboOption>();
private boolean combosEvaluated;
private Map<String, Object> 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<Object> values = new LinkedHashSet<Object>();
public ComboOption(String attribute, Collection<Object> options) {
this.attribute = attribute;
this.values.addAll(options);
}
}
public CombinationTestSupport() {
basedir = basedir(getClass());
}
public void addCombinationValues(String attribute, Object[] options) {
ComboOption co = this.comboOptions.get(attribute);
if (co == null) {
this.comboOptions.put(attribute, new ComboOption(attribute, Arrays.asList(options)));
} else {
co.values.addAll(Arrays.asList(options));
}
}
@Override
public void runBare() throws Throwable {
if (combosEvaluated) {
super.runBare();
} else {
CombinationTestSupport[] combinations = getCombinations();
for (int i = 0; i < combinations.length; i++) {
CombinationTestSupport test = combinations[i];
if (getName() == null || getName().equals(test.getName())) {
test.runBare();
}
}
}
}
private void setOptions(Map<String, Object> options) throws NoSuchFieldException, IllegalAccessException {
this.options = options;
for (Iterator<String> iterator = options.keySet().iterator(); iterator.hasNext();) {
String attribute = iterator.next();
Object value = options.get(attribute);
try {
Field field = getClass().getField(attribute);
field.set(this, value);
} catch (Throwable e) {
try {
boolean found = false;
String setterName = "set" + attribute.substring(0, 1).toUpperCase() +
attribute.substring(1);
for(Method method : getClass().getMethods()) {
if (method.getName().equals(setterName)) {
method.invoke(this, value);
found = true;
break;
}
}
if (!found) {
throw new NoSuchMethodError("No setter found for field: " + attribute);
}
} catch(Throwable ex) {
LOG.info("Could not set field '" + attribute + "' to value '" + value +
"', make sure the field exists and is public or has a setter.");
}
}
}
}
private CombinationTestSupport[] getCombinations() {
try {
Method method = getClass().getMethod("initCombos", (Class[])null);
method.invoke(this, (Object[])null);
} catch (Throwable e) {
}
String name = getName().split(" ")[0];
String comboSetupMethodName = "initCombosFor" + Character.toUpperCase(name.charAt(0)) + name.substring(1);
try {
Method method = getClass().getMethod(comboSetupMethodName, (Class[])null);
method.invoke(this, (Object[])null);
} catch (Throwable e) {
}
try {
ArrayList<HashMap<String, Object>> expandedOptions = new ArrayList<HashMap<String, Object>>();
expandCombinations(new ArrayList<ComboOption>(comboOptions.values()), expandedOptions);
if (expandedOptions.isEmpty()) {
combosEvaluated = true;
return new CombinationTestSupport[] {this};
} else {
ArrayList<CombinationTestSupport> result = new ArrayList<CombinationTestSupport>();
// Run the test case for each possible combination
for (Iterator<HashMap<String, Object>> iter = expandedOptions.iterator(); iter.hasNext();) {
CombinationTestSupport combo = (CombinationTestSupport)TestSuite.createTest(getClass(), name);
combo.combosEvaluated = true;
combo.setOptions(iter.next());
result.add(combo);
}
CombinationTestSupport rc[] = new CombinationTestSupport[result.size()];
result.toArray(rc);
return rc;
}
} catch (Throwable e) {
combosEvaluated = true;
return new CombinationTestSupport[] {this};
}
}
private void expandCombinations(List<ComboOption> optionsLeft, List<HashMap<String, Object>> expandedCombos) {
if (!optionsLeft.isEmpty()) {
HashMap<String, Object> map;
if (comboOptions.size() == optionsLeft.size()) {
map = new HashMap<String, Object>();
expandedCombos.add(map);
} else {
map = expandedCombos.get(expandedCombos.size() - 1);
}
LinkedList<ComboOption> l = new LinkedList<ComboOption>(optionsLeft);
ComboOption comboOption = l.removeLast();
int i = 0;
if (comboOption.values.isEmpty() && !l.isEmpty()) {
expandCombinations(l, expandedCombos);
} else {
for (Iterator<Object> iter = comboOption.values.iterator(); iter.hasNext();) {
Object value = iter.next();
if (i != 0) {
map = new HashMap<String, Object>(map);
expandedCombos.add(map);
}
map.put(comboOption.attribute, value);
expandCombinations(l, expandedCombos);
i++;
}
}
}
}
public static Test suite(Class<? extends CombinationTestSupport> clazz) {
TestSuite suite = new TestSuite();
ArrayList<String> names = new ArrayList<String>();
Method[] methods = clazz.getMethods();
for (int i = 0; i < methods.length; i++) {
String name = methods[i].getName();
if (names.contains(name) || !isPublicTestMethod(methods[i])) {
continue;
}
names.add(name);
Test test = TestSuite.createTest(clazz, name);
if (test instanceof CombinationTestSupport) {
CombinationTestSupport[] combinations = ((CombinationTestSupport)test).getCombinations();
for (int j = 0; j < combinations.length; j++) {
suite.addTest(combinations[j]);
}
} else {
suite.addTest(test);
}
}
return suite;
}
private static boolean isPublicTestMethod(Method m) {
return isTestMethod(m) && Modifier.isPublic(m.getModifiers());
}
private static boolean isTestMethod(Method m) {
String name = m.getName();
Class<?>[] parameters = m.getParameterTypes();
Class<?> returnType = m.getReturnType();
return parameters.length == 0 && name.startsWith("test") && returnType.equals(Void.TYPE);
}
@Override
public String getName() {
return getName(false);
}
public String getName(boolean original) {
if (options != null && !original) {
return super.getName() + " " + options;
}
return super.getName();
}
}

View File

@ -0,0 +1,69 @@
/**
* 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 javax.jms.JMSException;
import javax.jms.Session;
import junit.framework.TestCase;
/**
*
*/
public class ConnectionCleanupTest extends TestCase {
private ActiveMQConnection connection;
protected void setUp() throws Exception {
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://localhost");
connection = (ActiveMQConnection)factory.createConnection();
}
/**
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
connection.close();
}
/**
* @throws JMSException
*/
public void testChangeClientID() throws JMSException {
connection.setClientID("test");
connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
try {
connection.setClientID("test");
// fail("Should have received JMSException");
} catch (JMSException e) {
}
connection.cleanup();
connection.setClientID("test");
connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
try {
connection.setClientID("test");
// fail("Should have received JMSException");
} catch (JMSException e) {
}
}
}

View File

@ -0,0 +1,96 @@
/**
* 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.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import javax.jms.JMSException;
import javax.jms.Session;
import junit.framework.TestCase;
/**
*
*/
public class ConnectionCloseMultipleTimesConcurrentTest extends TestCase {
private ActiveMQConnection connection;
private ExecutorService executor;
private int size = 200;
protected void setUp() throws Exception {
executor = Executors.newFixedThreadPool(20);
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://localhost");
connection = (ActiveMQConnection)factory.createConnection();
connection.start();
}
/**
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
if (connection.isStarted()) {
connection.stop();
}
if (executor != null) {
executor.shutdownNow();
}
}
/**
* @throws javax.jms.JMSException
*/
public void testCloseMultipleTimes() throws Exception {
connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
assertTrue(connection.isStarted());
assertFalse(connection.isClosed());
final CountDownLatch latch = new CountDownLatch(size);
for (int i = 0; i < size; i++) {
executor.submit(new Runnable() {
@Override
public void run() {
try {
connection.close();
assertFalse(connection.isStarted());
assertTrue(connection.isClosed());
latch.countDown();
} catch (JMSException e) {
// ignore
}
}
});
}
boolean zero = latch.await(20, TimeUnit.SECONDS);
assertTrue("Should complete all", zero);
// should not fail calling again
connection.close();
assertFalse(connection.isStarted());
assertTrue(connection.isClosed());
}
}

View File

@ -0,0 +1,67 @@
/**
* 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 javax.jms.JMSException;
import javax.jms.Session;
import junit.framework.TestCase;
/**
*
*/
public class ConnectionCloseMultipleTimesTest extends TestCase {
private ActiveMQConnection connection;
protected void setUp() throws Exception {
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://localhost");
connection = (ActiveMQConnection)factory.createConnection();
connection.start();
}
/**
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
if (connection.isStarted()) {
connection.stop();
}
}
/**
* @throws javax.jms.JMSException
*/
public void testCloseMultipleTimes() throws JMSException {
connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
assertTrue(connection.isStarted());
assertFalse(connection.isClosed());
connection.close();
assertFalse(connection.isStarted());
assertTrue(connection.isClosed());
// should not fail calling again
connection.close();
assertFalse(connection.isStarted());
assertTrue(connection.isClosed());
}
}

View File

@ -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.
*/
package org.apache.activemq;
import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
/**
*
*/
public class ConsumerReceiveWithTimeoutTest extends TestSupport {
private Connection connection;
protected void setUp() throws Exception {
super.setUp();
connection = createConnection();
}
/**
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
if (connection != null) {
connection.close();
connection = null;
}
super.tearDown();
}
/**
* Test to check if consumer thread wakes up inside a receive(timeout) after
* a message is dispatched to the consumer
*
* @throws javax.jms.JMSException
*/
public void testConsumerReceiveBeforeMessageDispatched() throws JMSException {
connection.start();
final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
final Queue queue = session.createQueue("test");
Thread t = new Thread() {
public void run() {
try {
// wait for 10 seconds to allow consumer.receive to be run
// first
Thread.sleep(10000);
MessageProducer producer = session.createProducer(queue);
producer.send(session.createTextMessage("Hello"));
} catch (Exception e) {
e.printStackTrace();
}
}
};
t.start();
// Consume the message...
MessageConsumer consumer = session.createConsumer(queue);
Message msg = consumer.receive(60000);
assertNotNull(msg);
session.close();
}
}

View File

@ -0,0 +1,43 @@
/**
* 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 javax.jms.JMSException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
*/
public class CreateConsumerButDontStartConnectionWarningTest extends JmsQueueSendReceiveTest {
private static final transient Logger LOG = LoggerFactory.getLogger(CreateConsumerButDontStartConnectionWarningTest.class);
@Override
protected void startConnection() throws JMSException {
// don't start the connection
}
@Override
protected void assertMessagesAreReceived() throws JMSException {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
LOG.warn("Caught: " + e, e);
}
}
}

View File

@ -0,0 +1,44 @@
/**
* 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 javax.jms.Connection;
/**
* A base class for a test case which creates an embedded broker and uses a connection and session
*
*
*/
public abstract class EmbeddedBrokerAndConnectionTestSupport extends EmbeddedBrokerTestSupport {
protected Connection connection;
@Override
protected void setUp() throws Exception {
super.setUp();
connection = createConnection();
connection.start();
}
@Override
protected void tearDown() throws Exception {
if (connection != null) {
connection.close();
}
super.tearDown();
}
}

View File

@ -0,0 +1,143 @@
/**
* 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 org.apache.activemq.broker.BrokerService;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
import org.springframework.jms.core.JmsTemplate;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
/**
* A useful base class which creates and closes an embedded broker
*
*
*/
public abstract class EmbeddedBrokerTestSupport extends CombinationTestSupport {
protected BrokerService broker;
// protected String bindAddress = "tcp://localhost:61616";
protected String bindAddress = "vm://localhost";
protected ConnectionFactory connectionFactory;
protected boolean useTopic;
protected ActiveMQDestination destination;
protected JmsTemplate template;
protected void setUp() throws Exception {
if (broker == null) {
broker = createBroker();
}
startBroker();
connectionFactory = createConnectionFactory();
destination = createDestination();
template = createJmsTemplate();
template.setDefaultDestination(destination);
template.setPubSubDomain(useTopic);
template.afterPropertiesSet();
}
protected void tearDown() throws Exception {
if (broker != null) {
try {
broker.stop();
} catch (Exception e) {
}
}
}
/**
* Factory method to create a new {@link JmsTemplate}
*
* @return a newly created JmsTemplate
*/
protected JmsTemplate createJmsTemplate() {
return new JmsTemplate(connectionFactory);
}
/**
* Factory method to create a new {@link Destination}
*
* @return newly created Destinaiton
*/
protected ActiveMQDestination createDestination() {
return createDestination(getDestinationString());
}
/**
* Factory method to create the destination in either the queue or topic
* space based on the value of the {@link #useTopic} field
*/
protected ActiveMQDestination createDestination(String subject) {
if (useTopic) {
return new ActiveMQTopic(subject);
} else {
return new ActiveMQQueue(subject);
}
}
/**
* Returns the name of the destination used in this test case
*/
protected String getDestinationString() {
return getClass().getName() + "." + getName();
}
/**
* Factory method to create a new {@link ConnectionFactory} instance
*
* @return a newly created connection factory
*/
protected ConnectionFactory createConnectionFactory() throws Exception {
return new ActiveMQConnectionFactory(bindAddress);
}
/**
* Factory method to create a new broker
*
* @throws Exception
*/
protected BrokerService createBroker() throws Exception {
BrokerService answer = new BrokerService();
answer.setPersistent(isPersistent());
answer.addConnector(bindAddress);
return answer;
}
protected void startBroker() throws Exception {
broker.start();
}
/**
* @return whether or not persistence should be used
*/
protected boolean isPersistent() {
return false;
}
/**
* Factory method to create a new connection
*/
protected Connection createConnection() throws Exception {
return connectionFactory.createConnection();
}
}

View File

@ -0,0 +1,203 @@
/**
* 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 javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.broker.region.policy.PolicyEntry;
import org.apache.activemq.broker.region.policy.PolicyMap;
import org.apache.activemq.command.ActiveMQQueue;
public class ExclusiveConsumerStartupDestinationTest extends EmbeddedBrokerTestSupport{
private static final String VM_BROKER_URL = "vm://localhost";
@Override
protected BrokerService createBroker() throws Exception {
BrokerService answer = new BrokerService();
answer.setPersistent(false);
PolicyMap map = new PolicyMap();
PolicyEntry entry = new PolicyEntry();
entry.setAllConsumersExclusiveByDefault(true);
map.setDefaultEntry(entry);
answer.setDestinationPolicy(map);
return answer;
}
protected String getBrokerConfigUri() {
return "org/apache/activemq/broker/exclusive-consumer-startup-destination.xml";
}
private Connection createConnection(final boolean start) throws JMSException {
ConnectionFactory cf = new ActiveMQConnectionFactory(VM_BROKER_URL);
Connection conn = cf.createConnection();
if (start) {
conn.start();
}
return conn;
}
public void testExclusiveConsumerSelectedCreatedFirst() throws JMSException, InterruptedException {
Connection conn = createConnection(true);
Session exclusiveSession = null;
Session fallbackSession = null;
Session senderSession = null;
try {
exclusiveSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
fallbackSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
senderSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
ActiveMQQueue exclusiveQueue = new ActiveMQQueue("TEST.QUEUE1");
MessageConsumer exclusiveConsumer = exclusiveSession.createConsumer(exclusiveQueue);
ActiveMQQueue fallbackQueue = new ActiveMQQueue("TEST.QUEUE1");
MessageConsumer fallbackConsumer = fallbackSession.createConsumer(fallbackQueue);
ActiveMQQueue senderQueue = new ActiveMQQueue("TEST.QUEUE1");
MessageProducer producer = senderSession.createProducer(senderQueue);
Message msg = senderSession.createTextMessage("test");
producer.send(msg);
// TODO need two send a 2nd message - bug AMQ-1024
// producer.send(msg);
Thread.sleep(100);
// Verify exclusive consumer receives the message.
assertNotNull(exclusiveConsumer.receive(100));
assertNull(fallbackConsumer.receive(100));
} finally {
fallbackSession.close();
senderSession.close();
conn.close();
}
}
public void testFailoverToAnotherExclusiveConsumerCreatedFirst() throws JMSException,
InterruptedException {
Connection conn = createConnection(true);
Session exclusiveSession1 = null;
Session exclusiveSession2 = null;
Session fallbackSession = null;
Session senderSession = null;
try {
exclusiveSession1 = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
exclusiveSession2 = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
fallbackSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
senderSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
// This creates the exclusive consumer first which avoids AMQ-1024
// bug.
ActiveMQQueue exclusiveQueue = new ActiveMQQueue("TEST.QUEUE2");
MessageConsumer exclusiveConsumer1 = exclusiveSession1.createConsumer(exclusiveQueue);
MessageConsumer exclusiveConsumer2 = exclusiveSession2.createConsumer(exclusiveQueue);
ActiveMQQueue fallbackQueue = new ActiveMQQueue("TEST.QUEUE2");
MessageConsumer fallbackConsumer = fallbackSession.createConsumer(fallbackQueue);
ActiveMQQueue senderQueue = new ActiveMQQueue("TEST.QUEUE2");
MessageProducer producer = senderSession.createProducer(senderQueue);
Message msg = senderSession.createTextMessage("test");
producer.send(msg);
Thread.sleep(100);
// Verify exclusive consumer receives the message.
assertNotNull(exclusiveConsumer1.receive(100));
assertNull(exclusiveConsumer2.receive(100));
assertNull(fallbackConsumer.receive(100));
// Close the exclusive consumer to verify the non-exclusive consumer
// takes over
exclusiveConsumer1.close();
producer.send(msg);
producer.send(msg);
assertNotNull("Should have received a message", exclusiveConsumer2.receive(100));
assertNull("Should not have received a message", fallbackConsumer.receive(100));
} finally {
fallbackSession.close();
senderSession.close();
conn.close();
}
}
public void testFailoverToNonExclusiveConsumer() throws JMSException, InterruptedException {
Connection conn = createConnection(true);
Session exclusiveSession = null;
Session fallbackSession = null;
Session senderSession = null;
try {
exclusiveSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
fallbackSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
senderSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
// This creates the exclusive consumer first which avoids AMQ-1024
// bug.
ActiveMQQueue exclusiveQueue = new ActiveMQQueue("TEST.QUEUE3");
MessageConsumer exclusiveConsumer = exclusiveSession.createConsumer(exclusiveQueue);
ActiveMQQueue fallbackQueue = new ActiveMQQueue("TEST.QUEUE3");
MessageConsumer fallbackConsumer = fallbackSession.createConsumer(fallbackQueue);
ActiveMQQueue senderQueue = new ActiveMQQueue("TEST.QUEUE3");
MessageProducer producer = senderSession.createProducer(senderQueue);
Message msg = senderSession.createTextMessage("test");
producer.send(msg);
Thread.sleep(100);
// Verify exclusive consumer receives the message.
assertNotNull(exclusiveConsumer.receive(100));
assertNull(fallbackConsumer.receive(100));
// Close the exclusive consumer to verify the non-exclusive consumer
// takes over
exclusiveConsumer.close();
producer.send(msg);
assertNotNull(fallbackConsumer.receive(100));
} finally {
fallbackSession.close();
senderSession.close();
conn.close();
}
}
}

View File

@ -0,0 +1,357 @@
/**
* 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 javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import junit.framework.TestCase;
import org.apache.activemq.command.ActiveMQQueue;
public class ExclusiveConsumerTest extends TestCase {
private static final String VM_BROKER_URL = "vm://localhost?broker.persistent=false&broker.useJmx=true";
public ExclusiveConsumerTest(String name) {
super(name);
}
@Override
protected void setUp() throws Exception {
super.setUp();
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
}
private Connection createConnection(final boolean start) throws JMSException {
ConnectionFactory cf = new ActiveMQConnectionFactory(VM_BROKER_URL);
Connection conn = cf.createConnection();
if (start) {
conn.start();
}
return conn;
}
public void testExclusiveConsumerSelectedCreatedFirst() throws JMSException, InterruptedException {
Connection conn = createConnection(true);
Session exclusiveSession = null;
Session fallbackSession = null;
Session senderSession = null;
try {
exclusiveSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
fallbackSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
senderSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
ActiveMQQueue exclusiveQueue = new ActiveMQQueue("TEST.QUEUE1?consumer.exclusive=true");
MessageConsumer exclusiveConsumer = exclusiveSession.createConsumer(exclusiveQueue);
ActiveMQQueue fallbackQueue = new ActiveMQQueue("TEST.QUEUE1");
MessageConsumer fallbackConsumer = fallbackSession.createConsumer(fallbackQueue);
ActiveMQQueue senderQueue = new ActiveMQQueue("TEST.QUEUE1");
MessageProducer producer = senderSession.createProducer(senderQueue);
Message msg = senderSession.createTextMessage("test");
producer.send(msg);
// TODO need two send a 2nd message - bug AMQ-1024
// producer.send(msg);
Thread.sleep(100);
// Verify exclusive consumer receives the message.
assertNotNull(exclusiveConsumer.receive(100));
assertNull(fallbackConsumer.receive(100));
} finally {
fallbackSession.close();
senderSession.close();
conn.close();
}
}
public void testExclusiveConsumerSelectedCreatedAfter() throws JMSException, InterruptedException {
Connection conn = createConnection(true);
Session exclusiveSession = null;
Session fallbackSession = null;
Session senderSession = null;
try {
exclusiveSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
fallbackSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
senderSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
ActiveMQQueue fallbackQueue = new ActiveMQQueue("TEST.QUEUE5");
MessageConsumer fallbackConsumer = fallbackSession.createConsumer(fallbackQueue);
ActiveMQQueue exclusiveQueue = new ActiveMQQueue("TEST.QUEUE5?consumer.exclusive=true");
MessageConsumer exclusiveConsumer = exclusiveSession.createConsumer(exclusiveQueue);
ActiveMQQueue senderQueue = new ActiveMQQueue("TEST.QUEUE5");
MessageProducer producer = senderSession.createProducer(senderQueue);
Message msg = senderSession.createTextMessage("test");
producer.send(msg);
Thread.sleep(100);
// Verify exclusive consumer receives the message.
assertNotNull(exclusiveConsumer.receive(100));
assertNull(fallbackConsumer.receive(100));
} finally {
fallbackSession.close();
senderSession.close();
conn.close();
}
}
public void testFailoverToAnotherExclusiveConsumerCreatedFirst() throws JMSException,
InterruptedException {
Connection conn = createConnection(true);
Session exclusiveSession1 = null;
Session exclusiveSession2 = null;
Session fallbackSession = null;
Session senderSession = null;
try {
exclusiveSession1 = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
exclusiveSession2 = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
fallbackSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
senderSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
// This creates the exclusive consumer first which avoids AMQ-1024
// bug.
ActiveMQQueue exclusiveQueue = new ActiveMQQueue("TEST.QUEUE2?consumer.exclusive=true");
MessageConsumer exclusiveConsumer1 = exclusiveSession1.createConsumer(exclusiveQueue);
MessageConsumer exclusiveConsumer2 = exclusiveSession2.createConsumer(exclusiveQueue);
ActiveMQQueue fallbackQueue = new ActiveMQQueue("TEST.QUEUE2");
MessageConsumer fallbackConsumer = fallbackSession.createConsumer(fallbackQueue);
ActiveMQQueue senderQueue = new ActiveMQQueue("TEST.QUEUE2");
MessageProducer producer = senderSession.createProducer(senderQueue);
Message msg = senderSession.createTextMessage("test");
producer.send(msg);
Thread.sleep(100);
// Verify exclusive consumer receives the message.
assertNotNull(exclusiveConsumer1.receive(100));
assertNull(exclusiveConsumer2.receive(100));
assertNull(fallbackConsumer.receive(100));
// Close the exclusive consumer to verify the non-exclusive consumer
// takes over
exclusiveConsumer1.close();
producer.send(msg);
producer.send(msg);
assertNotNull(exclusiveConsumer2.receive(100));
assertNull(fallbackConsumer.receive(100));
} finally {
fallbackSession.close();
senderSession.close();
conn.close();
}
}
public void testFailoverToAnotherExclusiveConsumerCreatedAfter() throws JMSException,
InterruptedException {
Connection conn = createConnection(true);
Session exclusiveSession1 = null;
Session exclusiveSession2 = null;
Session fallbackSession = null;
Session senderSession = null;
try {
exclusiveSession1 = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
exclusiveSession2 = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
fallbackSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
senderSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
// This creates the exclusive consumer first which avoids AMQ-1024
// bug.
ActiveMQQueue exclusiveQueue = new ActiveMQQueue("TEST.QUEUE6?consumer.exclusive=true");
MessageConsumer exclusiveConsumer1 = exclusiveSession1.createConsumer(exclusiveQueue);
ActiveMQQueue fallbackQueue = new ActiveMQQueue("TEST.QUEUE6");
MessageConsumer fallbackConsumer = fallbackSession.createConsumer(fallbackQueue);
MessageConsumer exclusiveConsumer2 = exclusiveSession2.createConsumer(exclusiveQueue);
ActiveMQQueue senderQueue = new ActiveMQQueue("TEST.QUEUE6");
MessageProducer producer = senderSession.createProducer(senderQueue);
Message msg = senderSession.createTextMessage("test");
producer.send(msg);
Thread.sleep(100);
// Verify exclusive consumer receives the message.
assertNotNull(exclusiveConsumer1.receive(100));
assertNull(exclusiveConsumer2.receive(100));
assertNull(fallbackConsumer.receive(100));
// Close the exclusive consumer to verify the non-exclusive consumer
// takes over
exclusiveConsumer1.close();
producer.send(msg);
producer.send(msg);
assertNotNull(exclusiveConsumer2.receive(1000));
assertNull(fallbackConsumer.receive(100));
} finally {
fallbackSession.close();
senderSession.close();
conn.close();
}
}
public void testFailoverToNonExclusiveConsumer() throws JMSException, InterruptedException {
Connection conn = createConnection(true);
Session exclusiveSession = null;
Session fallbackSession = null;
Session senderSession = null;
try {
exclusiveSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
fallbackSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
senderSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
// This creates the exclusive consumer first which avoids AMQ-1024
// bug.
ActiveMQQueue exclusiveQueue = new ActiveMQQueue("TEST.QUEUE3?consumer.exclusive=true");
MessageConsumer exclusiveConsumer = exclusiveSession.createConsumer(exclusiveQueue);
ActiveMQQueue fallbackQueue = new ActiveMQQueue("TEST.QUEUE3");
MessageConsumer fallbackConsumer = fallbackSession.createConsumer(fallbackQueue);
ActiveMQQueue senderQueue = new ActiveMQQueue("TEST.QUEUE3");
MessageProducer producer = senderSession.createProducer(senderQueue);
Message msg = senderSession.createTextMessage("test");
producer.send(msg);
Thread.sleep(100);
// Verify exclusive consumer receives the message.
assertNotNull(exclusiveConsumer.receive(100));
assertNull(fallbackConsumer.receive(100));
// Close the exclusive consumer to verify the non-exclusive consumer
// takes over
exclusiveConsumer.close();
producer.send(msg);
assertNotNull(fallbackConsumer.receive(100));
} finally {
fallbackSession.close();
senderSession.close();
conn.close();
}
}
public void testFallbackToExclusiveConsumer() throws JMSException, InterruptedException {
Connection conn = createConnection(true);
Session exclusiveSession = null;
Session fallbackSession = null;
Session senderSession = null;
try {
exclusiveSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
fallbackSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
senderSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
// This creates the exclusive consumer first which avoids AMQ-1024
// bug.
ActiveMQQueue exclusiveQueue = new ActiveMQQueue("TEST.QUEUE4?consumer.exclusive=true");
MessageConsumer exclusiveConsumer = exclusiveSession.createConsumer(exclusiveQueue);
ActiveMQQueue fallbackQueue = new ActiveMQQueue("TEST.QUEUE4");
MessageConsumer fallbackConsumer = fallbackSession.createConsumer(fallbackQueue);
ActiveMQQueue senderQueue = new ActiveMQQueue("TEST.QUEUE4");
MessageProducer producer = senderSession.createProducer(senderQueue);
Message msg = senderSession.createTextMessage("test");
producer.send(msg);
Thread.sleep(100);
// Verify exclusive consumer receives the message.
assertNotNull(exclusiveConsumer.receive(100));
assertNull(fallbackConsumer.receive(100));
// Close the exclusive consumer to verify the non-exclusive consumer
// takes over
exclusiveConsumer.close();
producer.send(msg);
// Verify other non-exclusive consumer receices the message.
assertNotNull(fallbackConsumer.receive(100));
// Create exclusive consumer to determine if it will start receiving
// the messages.
exclusiveConsumer = exclusiveSession.createConsumer(exclusiveQueue);
producer.send(msg);
assertNotNull(exclusiveConsumer.receive(100));
assertNull(fallbackConsumer.receive(100));
} finally {
fallbackSession.close();
senderSession.close();
conn.close();
}
}
}

View File

@ -0,0 +1,82 @@
/**
* 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.util.concurrent.TimeUnit;
import javax.jms.ConnectionFactory;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.broker.region.policy.PolicyEntry;
import org.apache.activemq.broker.region.policy.PolicyMap;
import org.apache.activemq.store.kahadb.KahaDBPersistenceAdapter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
/**
* User: gtully
*/
@RunWith(BlockJUnit4ClassRunner.class)
public class ExpiryHogTest extends JmsMultipleClientsTestSupport {
boolean sleep = false;
int numMessages = 4;
@Test(timeout = 2 * 60 * 1000)
public void testImmediateDispatchWhenCacheDisabled() throws Exception {
ConnectionFactory f = createConnectionFactory();
destination = createDestination();
startConsumers(f, destination);
sleep = true;
this.startProducers(f, destination, numMessages);
allMessagesList.assertMessagesReceived(numMessages);
}
protected BrokerService createBroker() throws Exception {
BrokerService bs = new BrokerService();
bs.setDeleteAllMessagesOnStartup(true);
PolicyMap policyMap = new PolicyMap();
PolicyEntry defaultEntry = new PolicyEntry();
defaultEntry.setExpireMessagesPeriod(5000);
defaultEntry.setUseCache(false);
policyMap.setDefaultEntry(defaultEntry);
bs.setDestinationPolicy(policyMap);
KahaDBPersistenceAdapter ad = (KahaDBPersistenceAdapter) bs.getPersistenceAdapter();
ad.setConcurrentStoreAndDispatchQueues(true);
return bs;
}
protected TextMessage createTextMessage(Session session, String initText) throws Exception {
if (sleep) {
TimeUnit.SECONDS.sleep(10);
}
TextMessage msg = super.createTextMessage(session, initText);
msg.setJMSExpiration(4000);
return msg;
}
@Override
@Before
public void setUp() throws Exception {
autoFail = false;
persistent = true;
super.setUp();
}
}

View File

@ -0,0 +1,937 @@
/**
* 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.lang.Thread.UncaughtExceptionHandler;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import javax.jms.BytesMessage;
import javax.jms.DeliveryMode;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.management.ObjectName;
import junit.framework.Test;
import org.apache.activemq.broker.jmx.DestinationViewMBean;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.ActiveMQQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Test cases used to test the JMS message consumer.
*
*
*/
public class JMSConsumerTest extends JmsTestSupport {
private static final Logger LOG = LoggerFactory.getLogger(JMSConsumerTest.class);
public ActiveMQDestination destination;
public int deliveryMode;
public int prefetch;
public int ackMode;
public byte destinationType;
public boolean durableConsumer;
public static Test suite() {
return suite(JMSConsumerTest.class);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(suite());
}
public void initCombosForTestMessageListenerWithConsumerCanBeStopped() {
addCombinationValues("deliveryMode", new Object[] {Integer.valueOf(DeliveryMode.NON_PERSISTENT), Integer.valueOf(DeliveryMode.PERSISTENT)});
addCombinationValues("destinationType", new Object[] {Byte.valueOf(ActiveMQDestination.QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TOPIC_TYPE),
Byte.valueOf(ActiveMQDestination.TEMP_QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TEMP_TOPIC_TYPE)});
}
public void testMessageListenerWithConsumerCanBeStopped() throws Exception {
final AtomicInteger counter = new AtomicInteger(0);
final CountDownLatch done1 = new CountDownLatch(1);
final CountDownLatch done2 = new CountDownLatch(1);
// Receive a message with the JMS API
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = createDestination(session, destinationType);
ActiveMQMessageConsumer consumer = (ActiveMQMessageConsumer)session.createConsumer(destination);
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message m) {
counter.incrementAndGet();
if (counter.get() == 1) {
done1.countDown();
}
if (counter.get() == 2) {
done2.countDown();
}
}
});
// Send a first message to make sure that the consumer dispatcher is
// running
sendMessages(session, destination, 1);
assertTrue(done1.await(1, TimeUnit.SECONDS));
assertEquals(1, counter.get());
// Stop the consumer.
consumer.stop();
// Send a message, but should not get delivered.
sendMessages(session, destination, 1);
assertFalse(done2.await(1, TimeUnit.SECONDS));
assertEquals(1, counter.get());
// Start the consumer, and the message should now get delivered.
consumer.start();
assertTrue(done2.await(1, TimeUnit.SECONDS));
assertEquals(2, counter.get());
}
public void testMessageListenerWithConsumerCanBeStoppedConcurently() throws Exception {
final AtomicInteger counter = new AtomicInteger(0);
final CountDownLatch closeDone = new CountDownLatch(1);
connection.start();
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
destination = createDestination(session, ActiveMQDestination.QUEUE_TYPE);
// preload the queue
sendMessages(session, destination, 2000);
final ActiveMQMessageConsumer consumer = (ActiveMQMessageConsumer)session.createConsumer(destination);
final Map<Thread, Throwable> exceptions =
Collections.synchronizedMap(new HashMap<Thread, Throwable>());
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
LOG.error("Uncaught exception:", e);
exceptions.put(t, e);
}
});
final class AckAndClose implements Runnable {
private final Message message;
public AckAndClose(Message m) {
this.message = m;
}
@Override
public void run() {
try {
int count = counter.incrementAndGet();
if (count == 590) {
// close in a separate thread is ok by jms
consumer.close();
closeDone.countDown();
}
if (count % 200 == 0) {
// ensure there are some outstanding messages
// ack every 200
message.acknowledge();
}
} catch (Exception e) {
LOG.error("Exception on close or ack:", e);
exceptions.put(Thread.currentThread(), e);
}
}
};
final ExecutorService executor = Executors.newCachedThreadPool();
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message m) {
// ack and close eventually in separate thread
executor.execute(new AckAndClose(m));
}
});
assertTrue(closeDone.await(20, TimeUnit.SECONDS));
// await possible exceptions
Thread.sleep(1000);
assertTrue("no exceptions: " + exceptions, exceptions.isEmpty());
}
public void initCombosForTestMutiReceiveWithPrefetch1() {
addCombinationValues("deliveryMode", new Object[] {Integer.valueOf(DeliveryMode.NON_PERSISTENT), Integer.valueOf(DeliveryMode.PERSISTENT)});
addCombinationValues("ackMode", new Object[] {Integer.valueOf(Session.AUTO_ACKNOWLEDGE), Integer.valueOf(Session.DUPS_OK_ACKNOWLEDGE),
Integer.valueOf(Session.CLIENT_ACKNOWLEDGE)});
addCombinationValues("destinationType", new Object[] {Byte.valueOf(ActiveMQDestination.QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TOPIC_TYPE),
Byte.valueOf(ActiveMQDestination.TEMP_QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TEMP_TOPIC_TYPE)});
}
public void testMutiReceiveWithPrefetch1() throws Exception {
// Set prefetch to 1
connection.getPrefetchPolicy().setAll(1);
connection.start();
// Use all the ack modes
Session session = connection.createSession(false, ackMode);
destination = createDestination(session, destinationType);
MessageConsumer consumer = session.createConsumer(destination);
// Send the messages
sendMessages(session, destination, 4);
// Make sure 4 messages were delivered.
Message message = null;
for (int i = 0; i < 4; i++) {
message = consumer.receive(1000);
assertNotNull(message);
}
assertNull(consumer.receiveNoWait());
message.acknowledge();
}
public void initCombosForTestDurableConsumerSelectorChange() {
addCombinationValues("deliveryMode", new Object[] {Integer.valueOf(DeliveryMode.NON_PERSISTENT), Integer.valueOf(DeliveryMode.PERSISTENT)});
addCombinationValues("destinationType", new Object[] {Byte.valueOf(ActiveMQDestination.TOPIC_TYPE)});
}
public void testDurableConsumerSelectorChange() throws Exception {
// Receive a message with the JMS API
connection.setClientID("test");
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = createDestination(session, destinationType);
MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(deliveryMode);
MessageConsumer consumer = session.createDurableSubscriber((Topic)destination, "test", "color='red'", false);
// Send the messages
TextMessage message = session.createTextMessage("1st");
message.setStringProperty("color", "red");
producer.send(message);
Message m = consumer.receive(1000);
assertNotNull(m);
assertEquals("1st", ((TextMessage)m).getText());
// Change the subscription.
consumer.close();
consumer = session.createDurableSubscriber((Topic)destination, "test", "color='blue'", false);
message = session.createTextMessage("2nd");
message.setStringProperty("color", "red");
producer.send(message);
message = session.createTextMessage("3rd");
message.setStringProperty("color", "blue");
producer.send(message);
// Selector should skip the 2nd message.
m = consumer.receive(1000);
assertNotNull(m);
assertEquals("3rd", ((TextMessage)m).getText());
assertNull(consumer.receiveNoWait());
}
public void initCombosForTestSendReceiveBytesMessage() {
addCombinationValues("deliveryMode", new Object[] {Integer.valueOf(DeliveryMode.NON_PERSISTENT), Integer.valueOf(DeliveryMode.PERSISTENT)});
addCombinationValues("destinationType", new Object[] {Byte.valueOf(ActiveMQDestination.QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TOPIC_TYPE),
Byte.valueOf(ActiveMQDestination.TEMP_QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TEMP_TOPIC_TYPE)});
}
public void testSendReceiveBytesMessage() throws Exception {
// Receive a message with the JMS API
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = createDestination(session, destinationType);
MessageConsumer consumer = session.createConsumer(destination);
MessageProducer producer = session.createProducer(destination);
BytesMessage message = session.createBytesMessage();
message.writeBoolean(true);
message.writeBoolean(false);
producer.send(message);
// Make sure only 1 message was delivered.
BytesMessage m = (BytesMessage)consumer.receive(1000);
assertNotNull(m);
assertTrue(m.readBoolean());
assertFalse(m.readBoolean());
assertNull(consumer.receiveNoWait());
}
public void initCombosForTestSetMessageListenerAfterStart() {
addCombinationValues("deliveryMode", new Object[] {Integer.valueOf(DeliveryMode.NON_PERSISTENT), Integer.valueOf(DeliveryMode.PERSISTENT)});
addCombinationValues("destinationType", new Object[] {Byte.valueOf(ActiveMQDestination.QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TOPIC_TYPE),
Byte.valueOf(ActiveMQDestination.TEMP_QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TEMP_TOPIC_TYPE)});
}
public void testSetMessageListenerAfterStart() throws Exception {
final AtomicInteger counter = new AtomicInteger(0);
final CountDownLatch done = new CountDownLatch(1);
// Receive a message with the JMS API
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = createDestination(session, destinationType);
MessageConsumer consumer = session.createConsumer(destination);
// Send the messages
sendMessages(session, destination, 4);
// See if the message get sent to the listener
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message m) {
counter.incrementAndGet();
if (counter.get() == 4) {
done.countDown();
}
}
});
assertTrue(done.await(1000, TimeUnit.MILLISECONDS));
Thread.sleep(200);
// Make sure only 4 messages were delivered.
assertEquals(4, counter.get());
}
public void initCombosForTestPassMessageListenerIntoCreateConsumer() {
addCombinationValues("destinationType", new Object[] {Byte.valueOf(ActiveMQDestination.QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TOPIC_TYPE)});
}
public void testPassMessageListenerIntoCreateConsumer() throws Exception {
final AtomicInteger counter = new AtomicInteger(0);
final CountDownLatch done = new CountDownLatch(1);
// Receive a message with the JMS API
connection.start();
ActiveMQSession session = (ActiveMQSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = createDestination(session, destinationType);
MessageConsumer consumer = session.createConsumer(destination, new MessageListener() {
@Override
public void onMessage(Message m) {
counter.incrementAndGet();
if (counter.get() == 4) {
done.countDown();
}
}
});
assertNotNull(consumer);
// Send the messages
sendMessages(session, destination, 4);
assertTrue(done.await(1000, TimeUnit.MILLISECONDS));
Thread.sleep(200);
// Make sure only 4 messages were delivered.
assertEquals(4, counter.get());
}
public void initCombosForTestMessageListenerOnMessageCloseUnackedWithPrefetch1StayInQueue() {
addCombinationValues("deliveryMode", new Object[] {Integer.valueOf(DeliveryMode.NON_PERSISTENT), Integer.valueOf(DeliveryMode.PERSISTENT)});
addCombinationValues("ackMode", new Object[] {Integer.valueOf(Session.CLIENT_ACKNOWLEDGE)});
addCombinationValues("destinationType", new Object[] {Byte.valueOf(ActiveMQDestination.QUEUE_TYPE)});
}
public void testMessageListenerOnMessageCloseUnackedWithPrefetch1StayInQueue() throws Exception {
final AtomicInteger counter = new AtomicInteger(0);
final CountDownLatch sendDone = new CountDownLatch(1);
final CountDownLatch got2Done = new CountDownLatch(1);
// Set prefetch to 1
connection.getPrefetchPolicy().setAll(1);
// This test case does not work if optimized message dispatch is used as
// the main thread send block until the consumer receives the
// message. This test depends on thread decoupling so that the main
// thread can stop the consumer thread.
connection.setOptimizedMessageDispatch(false);
connection.start();
// Use all the ack modes
Session session = connection.createSession(false, ackMode);
destination = createDestination(session, destinationType);
MessageConsumer consumer = session.createConsumer(destination);
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message m) {
try {
TextMessage tm = (TextMessage)m;
LOG.info("Got in first listener: " + tm.getText());
assertEquals("" + counter.get(), tm.getText());
counter.incrementAndGet();
if (counter.get() == 2) {
sendDone.await();
connection.close();
got2Done.countDown();
}
tm.acknowledge();
} catch (Throwable e) {
e.printStackTrace();
}
}
});
// Send the messages
sendMessages(session, destination, 4);
sendDone.countDown();
// Wait for first 2 messages to arrive.
assertTrue(got2Done.await(100000, TimeUnit.MILLISECONDS));
// Re-start connection.
connection = (ActiveMQConnection)factory.createConnection();
connections.add(connection);
connection.getPrefetchPolicy().setAll(1);
connection.start();
// Pickup the remaining messages.
final CountDownLatch done2 = new CountDownLatch(1);
session = connection.createSession(false, ackMode);
consumer = session.createConsumer(destination);
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message m) {
try {
TextMessage tm = (TextMessage)m;
LOG.info("Got in second listener: " + tm.getText());
// order is not guaranteed as the connection is started before the listener is set.
// assertEquals("" + counter.get(), tm.getText());
counter.incrementAndGet();
if (counter.get() == 4) {
done2.countDown();
}
} catch (Throwable e) {
LOG.error("unexpected ex onMessage: ", e);
}
}
});
assertTrue(done2.await(1000, TimeUnit.MILLISECONDS));
Thread.sleep(200);
// assert msg 2 was redelivered as close() from onMessages() will only ack in auto_ack and dups_ok mode
assertEquals(5, counter.get());
}
public void initCombosForTestMessageListenerAutoAckOnCloseWithPrefetch1() {
addCombinationValues("deliveryMode", new Object[] {Integer.valueOf(DeliveryMode.NON_PERSISTENT), Integer.valueOf(DeliveryMode.PERSISTENT)});
addCombinationValues("ackMode", new Object[] {Integer.valueOf(Session.AUTO_ACKNOWLEDGE), Integer.valueOf(Session.CLIENT_ACKNOWLEDGE)});
addCombinationValues("destinationType", new Object[] {Byte.valueOf(ActiveMQDestination.QUEUE_TYPE)});
}
public void testMessageListenerAutoAckOnCloseWithPrefetch1() throws Exception {
final AtomicInteger counter = new AtomicInteger(0);
final CountDownLatch sendDone = new CountDownLatch(1);
final CountDownLatch got2Done = new CountDownLatch(1);
// Set prefetch to 1
connection.getPrefetchPolicy().setAll(1);
// This test case does not work if optimized message dispatch is used as
// the main thread send block until the consumer receives the
// message. This test depends on thread decoupling so that the main
// thread can stop the consumer thread.
connection.setOptimizedMessageDispatch(false);
connection.start();
// Use all the ack modes
Session session = connection.createSession(false, ackMode);
destination = createDestination(session, destinationType);
MessageConsumer consumer = session.createConsumer(destination);
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message m) {
try {
TextMessage tm = (TextMessage)m;
LOG.info("Got in first listener: " + tm.getText());
assertEquals("" + counter.get(), tm.getText());
counter.incrementAndGet();
m.acknowledge();
if (counter.get() == 2) {
sendDone.await();
connection.close();
got2Done.countDown();
}
} catch (Throwable e) {
e.printStackTrace();
}
}
});
// Send the messages
sendMessages(session, destination, 4);
sendDone.countDown();
// Wait for first 2 messages to arrive.
assertTrue(got2Done.await(100000, TimeUnit.MILLISECONDS));
// Re-start connection.
connection = (ActiveMQConnection)factory.createConnection();
connections.add(connection);
connection.getPrefetchPolicy().setAll(1);
connection.start();
// Pickup the remaining messages.
final CountDownLatch done2 = new CountDownLatch(1);
session = connection.createSession(false, ackMode);
consumer = session.createConsumer(destination);
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message m) {
try {
TextMessage tm = (TextMessage)m;
LOG.info("Got in second listener: " + tm.getText());
counter.incrementAndGet();
if (counter.get() == 4) {
done2.countDown();
}
} catch (Throwable e) {
LOG.error("unexpected ex onMessage: ", e);
}
}
});
assertTrue(done2.await(1000, TimeUnit.MILLISECONDS));
Thread.sleep(200);
// close from onMessage with Auto_ack will ack
// Make sure only 4 messages were delivered.
assertEquals(4, counter.get());
}
public void initCombosForTestMessageListenerWithConsumerWithPrefetch1() {
addCombinationValues("deliveryMode", new Object[] {Integer.valueOf(DeliveryMode.NON_PERSISTENT), Integer.valueOf(DeliveryMode.PERSISTENT)});
addCombinationValues("destinationType", new Object[] {Byte.valueOf(ActiveMQDestination.QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TOPIC_TYPE),
Byte.valueOf(ActiveMQDestination.TEMP_QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TEMP_TOPIC_TYPE)});
}
public void testMessageListenerWithConsumerWithPrefetch1() throws Exception {
final AtomicInteger counter = new AtomicInteger(0);
final CountDownLatch done = new CountDownLatch(1);
// Receive a message with the JMS API
connection.getPrefetchPolicy().setAll(1);
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = createDestination(session, destinationType);
MessageConsumer consumer = session.createConsumer(destination);
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message m) {
counter.incrementAndGet();
if (counter.get() == 4) {
done.countDown();
}
}
});
// Send the messages
sendMessages(session, destination, 4);
assertTrue(done.await(1000, TimeUnit.MILLISECONDS));
Thread.sleep(200);
// Make sure only 4 messages were delivered.
assertEquals(4, counter.get());
}
public void initCombosForTestMessageListenerWithConsumer() {
addCombinationValues("deliveryMode", new Object[] {Integer.valueOf(DeliveryMode.NON_PERSISTENT), Integer.valueOf(DeliveryMode.PERSISTENT)});
addCombinationValues("destinationType", new Object[] {Byte.valueOf(ActiveMQDestination.QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TOPIC_TYPE),
Byte.valueOf(ActiveMQDestination.TEMP_QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TEMP_TOPIC_TYPE)});
}
public void testMessageListenerWithConsumer() throws Exception {
final AtomicInteger counter = new AtomicInteger(0);
final CountDownLatch done = new CountDownLatch(1);
// Receive a message with the JMS API
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = createDestination(session, destinationType);
MessageConsumer consumer = session.createConsumer(destination);
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message m) {
counter.incrementAndGet();
if (counter.get() == 4) {
done.countDown();
}
}
});
// Send the messages
sendMessages(session, destination, 4);
assertTrue(done.await(1000, TimeUnit.MILLISECONDS));
Thread.sleep(200);
// Make sure only 4 messages were delivered.
assertEquals(4, counter.get());
}
public void initCombosForTestUnackedWithPrefetch1StayInQueue() {
addCombinationValues("deliveryMode", new Object[] {Integer.valueOf(DeliveryMode.NON_PERSISTENT), Integer.valueOf(DeliveryMode.PERSISTENT)});
addCombinationValues("ackMode", new Object[] {Integer.valueOf(Session.AUTO_ACKNOWLEDGE), Integer.valueOf(Session.DUPS_OK_ACKNOWLEDGE),
Integer.valueOf(Session.CLIENT_ACKNOWLEDGE)});
addCombinationValues("destinationType", new Object[] {Byte.valueOf(ActiveMQDestination.QUEUE_TYPE)});
}
public void testUnackedWithPrefetch1StayInQueue() throws Exception {
// Set prefetch to 1
connection.getPrefetchPolicy().setAll(1);
connection.start();
// Use all the ack modes
Session session = connection.createSession(false, ackMode);
destination = createDestination(session, destinationType);
MessageConsumer consumer = session.createConsumer(destination);
// Send the messages
sendMessages(session, destination, 4);
// Only pick up the first 2 messages.
Message message = null;
for (int i = 0; i < 2; i++) {
message = consumer.receive(1000);
assertNotNull(message);
}
message.acknowledge();
connection.close();
connection = (ActiveMQConnection)factory.createConnection();
connections.add(connection);
connection.getPrefetchPolicy().setAll(1);
connection.start();
// Use all the ack modes
session = connection.createSession(false, ackMode);
consumer = session.createConsumer(destination);
// Pickup the rest of the messages.
for (int i = 0; i < 2; i++) {
message = consumer.receive(1000);
assertNotNull(message);
}
message.acknowledge();
assertNull(consumer.receiveNoWait());
}
public void initCombosForTestPrefetch1MessageNotDispatched() {
addCombinationValues("deliveryMode", new Object[] {Integer.valueOf(DeliveryMode.NON_PERSISTENT), Integer.valueOf(DeliveryMode.PERSISTENT)});
}
public void testPrefetch1MessageNotDispatched() throws Exception {
// Set prefetch to 1
connection.getPrefetchPolicy().setAll(1);
connection.start();
Session session = connection.createSession(true, 0);
destination = new ActiveMQQueue("TEST");
MessageConsumer consumer = session.createConsumer(destination);
// Send 2 messages to the destination.
sendMessages(session, destination, 2);
session.commit();
// The prefetch should fill up with 1 message.
// Since prefetch is still full, the 2nd message should get dispatched
// to another consumer.. lets create the 2nd consumer test that it does
// make sure it does.
ActiveMQConnection connection2 = (ActiveMQConnection)factory.createConnection();
connection2.start();
connections.add(connection2);
Session session2 = connection2.createSession(true, 0);
MessageConsumer consumer2 = session2.createConsumer(destination);
// Pick up the first message.
Message message1 = consumer.receive(1000);
assertNotNull(message1);
// Pick up the 2nd messages.
Message message2 = consumer2.receive(5000);
assertNotNull(message2);
session.commit();
session2.commit();
assertNull(consumer.receiveNoWait());
}
public void initCombosForTestDontStart() {
addCombinationValues("deliveryMode", new Object[] {Integer.valueOf(DeliveryMode.NON_PERSISTENT)});
addCombinationValues("destinationType", new Object[] {Byte.valueOf(ActiveMQDestination.QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TOPIC_TYPE)});
}
public void testDontStart() throws Exception {
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = createDestination(session, destinationType);
MessageConsumer consumer = session.createConsumer(destination);
// Send the messages
sendMessages(session, destination, 1);
// Make sure no messages were delivered.
assertNull(consumer.receive(1000));
}
public void initCombosForTestStartAfterSend() {
addCombinationValues("deliveryMode", new Object[] {Integer.valueOf(DeliveryMode.NON_PERSISTENT)});
addCombinationValues("destinationType", new Object[] {Byte.valueOf(ActiveMQDestination.QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TOPIC_TYPE)});
}
public void testStartAfterSend() throws Exception {
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = createDestination(session, destinationType);
MessageConsumer consumer = session.createConsumer(destination);
// Send the messages
sendMessages(session, destination, 1);
// Start the conncection after the message was sent.
connection.start();
// Make sure only 1 message was delivered.
assertNotNull(consumer.receive(1000));
assertNull(consumer.receiveNoWait());
}
public void initCombosForTestReceiveMessageWithConsumer() {
addCombinationValues("deliveryMode", new Object[] {Integer.valueOf(DeliveryMode.NON_PERSISTENT), Integer.valueOf(DeliveryMode.PERSISTENT)});
addCombinationValues("destinationType", new Object[] {Byte.valueOf(ActiveMQDestination.QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TOPIC_TYPE),
Byte.valueOf(ActiveMQDestination.TEMP_QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TEMP_TOPIC_TYPE)});
}
public void testReceiveMessageWithConsumer() throws Exception {
// Receive a message with the JMS API
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = createDestination(session, destinationType);
MessageConsumer consumer = session.createConsumer(destination);
// Send the messages
sendMessages(session, destination, 1);
// Make sure only 1 message was delivered.
Message m = consumer.receive(1000);
assertNotNull(m);
assertEquals("0", ((TextMessage)m).getText());
assertNull(consumer.receiveNoWait());
}
public void testDupsOkConsumer() throws Exception {
// Receive a message with the JMS API
connection.start();
Session session = connection.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);
destination = createDestination(session, ActiveMQDestination.QUEUE_TYPE);
MessageConsumer consumer = session.createConsumer(destination);
// Send the messages
sendMessages(session, destination, 4);
// Make sure only 4 message are delivered.
for( int i=0; i < 4; i++){
Message m = consumer.receive(1000);
assertNotNull(m);
}
assertNull(consumer.receive(1000));
// Close out the consumer.. no other messages should be left on the queue.
consumer.close();
consumer = session.createConsumer(destination);
assertNull(consumer.receive(1000));
}
public void testRedispatchOfUncommittedTx() throws Exception {
connection.start();
Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
destination = createDestination(session, ActiveMQDestination.QUEUE_TYPE);
sendMessages(connection, destination, 2);
MessageConsumer consumer = session.createConsumer(destination);
assertNotNull(consumer.receive(1000));
assertNotNull(consumer.receive(1000));
// install another consumer while message dispatch is unacked/uncommitted
Session redispatchSession = connection.createSession(true, Session.SESSION_TRANSACTED);
MessageConsumer redispatchConsumer = redispatchSession.createConsumer(destination);
// no commit so will auto rollback and get re-dispatched to redisptachConsumer
session.close();
Message msg = redispatchConsumer.receive(1000);
assertNotNull(msg);
assertTrue("redelivered flag set", msg.getJMSRedelivered());
assertEquals(2, msg.getLongProperty("JMSXDeliveryCount"));
msg = redispatchConsumer.receive(1000);
assertNotNull(msg);
assertTrue(msg.getJMSRedelivered());
assertEquals(2, msg.getLongProperty("JMSXDeliveryCount"));
redispatchSession.commit();
assertNull(redispatchConsumer.receive(500));
redispatchSession.close();
}
public void testRedispatchOfRolledbackTx() throws Exception {
connection.start();
Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
destination = createDestination(session, ActiveMQDestination.QUEUE_TYPE);
sendMessages(connection, destination, 2);
MessageConsumer consumer = session.createConsumer(destination);
assertNotNull(consumer.receive(1000));
assertNotNull(consumer.receive(1000));
// install another consumer while message dispatch is unacked/uncommitted
Session redispatchSession = connection.createSession(true, Session.SESSION_TRANSACTED);
MessageConsumer redispatchConsumer = redispatchSession.createConsumer(destination);
session.rollback();
session.close();
Message msg = redispatchConsumer.receive(1000);
assertNotNull(msg);
assertTrue(msg.getJMSRedelivered());
assertEquals(2, msg.getLongProperty("JMSXDeliveryCount"));
msg = redispatchConsumer.receive(1000);
assertNotNull(msg);
assertTrue(msg.getJMSRedelivered());
assertEquals(2, msg.getLongProperty("JMSXDeliveryCount"));
redispatchSession.commit();
assertNull(redispatchConsumer.receive(500));
redispatchSession.close();
}
public void initCombosForTestAckOfExpired() {
addCombinationValues("destinationType",
new Object[] {Byte.valueOf(ActiveMQDestination.QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TOPIC_TYPE)});
}
public void testAckOfExpired() throws Exception {
ActiveMQConnectionFactory fact = new ActiveMQConnectionFactory("vm://localhost?jms.prefetchPolicy.all=4&jms.sendAcksAsync=false");
connection = fact.createActiveMQConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = (ActiveMQDestination) (destinationType == ActiveMQDestination.QUEUE_TYPE ?
session.createQueue("test") : session.createTopic("test"));
MessageConsumer consumer = session.createConsumer(destination);
connection.setStatsEnabled(true);
Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = sendSession.createProducer(destination);
producer.setTimeToLive(1000);
final int count = 4;
for (int i = 0; i < count; i++) {
TextMessage message = sendSession.createTextMessage("" + i);
producer.send(message);
}
// let first bunch in queue expire
Thread.sleep(2000);
producer.setTimeToLive(0);
for (int i = 0; i < count; i++) {
TextMessage message = sendSession.createTextMessage("no expiry" + i);
producer.send(message);
}
ActiveMQMessageConsumer amqConsumer = (ActiveMQMessageConsumer) consumer;
for(int i=0; i<count; i++) {
TextMessage msg = (TextMessage) amqConsumer.receive();
assertNotNull(msg);
assertTrue("message has \"no expiry\" text: " + msg.getText(), msg.getText().contains("no expiry"));
// force an ack when there are expired messages
amqConsumer.acknowledge();
}
assertEquals("consumer has expiredMessages", count, amqConsumer.getConsumerStats().getExpiredMessageCount().getCount());
DestinationViewMBean view = createView(destination);
assertEquals("Wrong inFlightCount: " + view.getInFlightCount(), 0, view.getInFlightCount());
assertEquals("Wrong dispatch count: " + view.getDispatchCount(), 8, view.getDispatchCount());
assertEquals("Wrong dequeue count: " + view.getDequeueCount(), 8, view.getDequeueCount());
assertEquals("Wrong expired count: " + view.getExpiredCount(), 4, view.getExpiredCount());
}
protected DestinationViewMBean createView(ActiveMQDestination destination) throws Exception {
String domain = "org.apache.activemq";
ObjectName name;
if (destination.isQueue()) {
name = new ObjectName(domain + ":type=Broker,brokerName=localhost,destinationType=Queue,destinationName=test");
} else {
name = new ObjectName(domain + ":type=Broker,brokerName=localhost,destinationType=Topic,destinationName=test");
}
return (DestinationViewMBean)broker.getManagementContext().newProxyInstance(name, DestinationViewMBean.class, true);
}
}

View File

@ -0,0 +1,80 @@
/**
* 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 javax.jms.Message;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
*/
public class JMSDurableTopicRedeliverTest extends JmsTopicRedeliverTest {
private static final Logger LOG = LoggerFactory.getLogger(JMSDurableTopicRedeliverTest.class);
protected void setUp() throws Exception {
durable = true;
super.setUp();
}
/**
* Sends and consumes the messages.
*
* @throws Exception
*/
public void testRedeliverNewSession() throws Exception {
String text = "TEST: " + System.currentTimeMillis();
Message sendMessage = session.createTextMessage(text);
if (verbose) {
LOG.info("About to send a message: " + sendMessage + " with text: " + text);
}
producer.send(producerDestination, sendMessage);
// receive but don't acknowledge
Message unackMessage = consumer.receive(1000);
assertNotNull(unackMessage);
String unackId = unackMessage.getJMSMessageID();
assertEquals(((TextMessage)unackMessage).getText(), text);
assertFalse(unackMessage.getJMSRedelivered());
assertEquals(unackMessage.getIntProperty("JMSXDeliveryCount"), 1);
consumeSession.close();
consumer.close();
// receive then acknowledge
consumeSession = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
consumer = createConsumer();
Message ackMessage = consumer.receive(1000);
assertNotNull(ackMessage);
ackMessage.acknowledge();
String ackId = ackMessage.getJMSMessageID();
assertEquals(((TextMessage)ackMessage).getText(), text);
assertTrue(ackMessage.getJMSRedelivered());
assertEquals(ackMessage.getIntProperty("JMSXDeliveryCount"), 2);
assertEquals(unackId, ackId);
consumeSession.close();
consumer.close();
consumeSession = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
consumer = createConsumer();
assertNull(consumer.receive(1000));
}
}

View File

@ -0,0 +1,152 @@
/**
* 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 javax.jms.DeliveryMode;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import junit.framework.Test;
import org.apache.activemq.command.ActiveMQQueue;
/**
* Test cases used to test the JMS message exclusive consumers.
*
*
*/
public class JMSExclusiveConsumerTest extends JmsTestSupport {
public int deliveryMode;
public static Test suite() {
return suite(JMSExclusiveConsumerTest.class);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(suite());
}
public void initCombosForTestRoundRobinDispatchOnNonExclusive() {
addCombinationValues("deliveryMode", new Object[] {Integer.valueOf(DeliveryMode.NON_PERSISTENT), Integer.valueOf(DeliveryMode.PERSISTENT)});
}
/**
* Shows that by default messages are round robined across a set of
* consumers.
*
* @throws Exception
*/
public void testRoundRobinDispatchOnNonExclusive() throws Exception {
// Receive a message with the JMS API
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
ActiveMQQueue destination = new ActiveMQQueue("TEST");
MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(deliveryMode);
MessageConsumer consumer1 = session.createConsumer(destination);
MessageConsumer consumer2 = session.createConsumer(destination);
// Send the messages
producer.send(session.createTextMessage("1st"));
producer.send(session.createTextMessage("2nd"));
Message m;
m = consumer2.receive(1000);
assertNotNull(m);
m = consumer1.receive(1000);
assertNotNull(m);
assertNull(consumer1.receiveNoWait());
assertNull(consumer2.receiveNoWait());
}
public void initCombosForTestDispatchExclusive() {
addCombinationValues("deliveryMode", new Object[] {Integer.valueOf(DeliveryMode.NON_PERSISTENT), Integer.valueOf(DeliveryMode.PERSISTENT)});
}
/**
* Shows that if the "?consumer.exclusive=true" option is added to
* destination, then all messages are routed to 1 consumer.
*
* @throws Exception
*/
public void testDispatchExclusive() throws Exception {
// Receive a message with the JMS API
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
ActiveMQQueue destination = new ActiveMQQueue("TEST?consumer.exclusive=true");
MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(deliveryMode);
MessageConsumer consumer1 = session.createConsumer(destination);
MessageConsumer consumer2 = session.createConsumer(destination);
// Send the messages
producer.send(session.createTextMessage("1st"));
producer.send(session.createTextMessage("2nd"));
producer.send(session.createTextMessage("3nd"));
Message m;
m = consumer2.receive(1000);
if (m != null) {
// Consumer 2 should get all the messages.
for (int i = 0; i < 2; i++) {
m = consumer2.receive(1000);
assertNotNull(m);
}
} else {
// Consumer 1 should get all the messages.
for (int i = 0; i < 3; i++) {
m = consumer1.receive(1000);
assertNotNull(m);
}
}
assertNull(consumer1.receiveNoWait());
assertNull(consumer2.receiveNoWait());
}
public void testMixExclusiveWithNonExclusive() throws Exception {
ActiveMQQueue exclusiveQueue = new ActiveMQQueue("TEST.FOO?consumer.exclusive=true");
ActiveMQQueue nonExclusiveQueue = new ActiveMQQueue("TEST.FOO?consumer.exclusive=false");
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer nonExCon = session.createConsumer(nonExclusiveQueue);
MessageConsumer exCon = session.createConsumer(exclusiveQueue);
MessageProducer prod = session.createProducer(exclusiveQueue);
prod.send(session.createMessage());
prod.send(session.createMessage());
prod.send(session.createMessage());
Message m;
for (int i = 0; i < 3; i++) {
m = exCon.receive(1000);
assertNotNull(m);
m = nonExCon.receive(1000);
assertNull(m);
}
}
}

View File

@ -0,0 +1,161 @@
/**
* 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 javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
/**
*
*/
public class JMSIndividualAckTest extends TestSupport {
private Connection connection;
@Override
protected void setUp() throws Exception {
super.setUp();
connection = createConnection();
}
/**
* @see junit.framework.TestCase#tearDown()
*/
@Override
protected void tearDown() throws Exception {
if (connection != null) {
connection.close();
connection = null;
}
super.tearDown();
}
/**
* Tests if acknowledged messages are being consumed.
*
* @throws JMSException
*/
public void testAckedMessageAreConsumed() throws JMSException {
connection.start();
Session session = connection.createSession(false, ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE);
Queue queue = session.createQueue(getQueueName());
MessageProducer producer = session.createProducer(queue);
producer.send(session.createTextMessage("Hello"));
// Consume the message...
MessageConsumer consumer = session.createConsumer(queue);
Message msg = consumer.receive(1000);
assertNotNull(msg);
msg.acknowledge();
// Reset the session.
session.close();
session = connection.createSession(false, ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE);
// Attempt to Consume the message...
consumer = session.createConsumer(queue);
msg = consumer.receive(1000);
assertNull(msg);
session.close();
}
/**
* Tests if acknowledged messages are being consumed.
*
* @throws JMSException
*/
public void testLastMessageAcked() throws JMSException {
connection.start();
Session session = connection.createSession(false, ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE);
Queue queue = session.createQueue(getQueueName());
MessageProducer producer = session.createProducer(queue);
TextMessage msg1 = session.createTextMessage("msg1");
TextMessage msg2 = session.createTextMessage("msg2");
TextMessage msg3 = session.createTextMessage("msg3");
producer.send(msg1);
producer.send(msg2);
producer.send(msg3);
// Consume the message...
MessageConsumer consumer = session.createConsumer(queue);
Message msg = consumer.receive(1000);
assertNotNull(msg);
msg = consumer.receive(1000);
assertNotNull(msg);
msg = consumer.receive(1000);
assertNotNull(msg);
msg.acknowledge();
// Reset the session.
session.close();
session = connection.createSession(false, ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE);
// Attempt to Consume the message...
consumer = session.createConsumer(queue);
msg = consumer.receive(1000);
assertNotNull(msg);
assertEquals(msg1,msg);
msg = consumer.receive(1000);
assertNotNull(msg);
assertEquals(msg2,msg);
msg = consumer.receive(1000);
assertNull(msg);
session.close();
}
/**
* Tests if unacknowledged messages are being re-delivered when the consumer connects again.
*
* @throws JMSException
*/
public void testUnAckedMessageAreNotConsumedOnSessionClose() throws JMSException {
connection.start();
Session session = connection.createSession(false, ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE);
Queue queue = session.createQueue(getQueueName());
MessageProducer producer = session.createProducer(queue);
producer.send(session.createTextMessage("Hello"));
// Consume the message...
MessageConsumer consumer = session.createConsumer(queue);
Message msg = consumer.receive(1000);
assertNotNull(msg);
// Don't ack the message.
// Reset the session. This should cause the unacknowledged message to be re-delivered.
session.close();
session = connection.createSession(false, ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE);
// Attempt to Consume the message...
consumer = session.createConsumer(queue);
msg = consumer.receive(2000);
assertNotNull(msg);
msg.acknowledge();
session.close();
}
protected String getQueueName() {
return getClass().getName() + "." + getName();
}
}

View File

@ -0,0 +1,547 @@
/**
* 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.net.URISyntaxException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Vector;
import javax.jms.BytesMessage;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.MessageConsumer;
import javax.jms.MessageEOFException;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.StreamMessage;
import javax.jms.TextMessage;
import junit.framework.Test;
import org.apache.activemq.command.ActiveMQDestination;
/**
* Test cases used to test the JMS message consumer.
*
*
*/
public class JMSMessageTest extends JmsTestSupport {
public ActiveMQDestination destination;
public int deliveryMode = DeliveryMode.NON_PERSISTENT;
public int prefetch;
public int ackMode;
public byte destinationType = ActiveMQDestination.QUEUE_TYPE;
public boolean durableConsumer;
public String connectURL = "vm://localhost?marshal=false";
/**
* Run all these tests in both marshaling and non-marshaling mode.
*/
public void initCombos() {
addCombinationValues("connectURL", new Object[] {"vm://localhost?marshal=false",
"vm://localhost?marshal=true"});
addCombinationValues("deliveryMode", new Object[] {Integer.valueOf(DeliveryMode.NON_PERSISTENT),
Integer.valueOf(DeliveryMode.PERSISTENT)});
addCombinationValues("destinationType", new Object[] {Byte.valueOf(ActiveMQDestination.QUEUE_TYPE)});
}
public void testTextMessage() throws Exception {
// Receive a message with the JMS API
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = createDestination(session, destinationType);
MessageConsumer consumer = session.createConsumer(destination);
MessageProducer producer = session.createProducer(destination);
// Send the message.
{
TextMessage message = session.createTextMessage();
message.setText("Hi");
producer.send(message);
}
// Check the Message
{
TextMessage message = (TextMessage)consumer.receive(1000);
assertNotNull(message);
assertEquals("Hi", message.getText());
}
assertNull(consumer.receiveNoWait());
}
public static Test suite() {
return suite(JMSMessageTest.class);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(suite());
}
@Override
protected ConnectionFactory createConnectionFactory() throws URISyntaxException {
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(connectURL);
return factory;
}
public void testBytesMessageLength() throws Exception {
// Receive a message with the JMS API
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = createDestination(session, destinationType);
MessageConsumer consumer = session.createConsumer(destination);
MessageProducer producer = session.createProducer(destination);
// Send the message
{
BytesMessage message = session.createBytesMessage();
message.writeInt(1);
message.writeInt(2);
message.writeInt(3);
message.writeInt(4);
producer.send(message);
}
// Check the message.
{
BytesMessage message = (BytesMessage)consumer.receive(1000);
assertNotNull(message);
assertEquals(16, message.getBodyLength());
}
assertNull(consumer.receiveNoWait());
}
public void testObjectMessage() throws Exception {
// Receive a message with the JMS API
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = createDestination(session, destinationType);
MessageConsumer consumer = session.createConsumer(destination);
MessageProducer producer = session.createProducer(destination);
// send the message.
{
ObjectMessage message = session.createObjectMessage();
message.setObject("Hi");
producer.send(message);
}
// Check the message
{
ObjectMessage message = (ObjectMessage)consumer.receive(1000);
assertNotNull(message);
assertEquals("Hi", message.getObject());
}
assertNull(consumer.receiveNoWait());
}
public void testBytesMessage() throws Exception {
// Receive a message with the JMS API
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = createDestination(session, destinationType);
MessageConsumer consumer = session.createConsumer(destination);
MessageProducer producer = session.createProducer(destination);
// Send the message
{
BytesMessage message = session.createBytesMessage();
message.writeBoolean(true);
producer.send(message);
}
// Check the message
{
BytesMessage message = (BytesMessage)consumer.receive(1000);
assertNotNull(message);
assertTrue(message.readBoolean());
try {
message.readByte();
fail("Expected exception not thrown.");
} catch (MessageEOFException e) {
}
}
assertNull(consumer.receiveNoWait());
}
public void testStreamMessage() throws Exception {
// Receive a message with the JMS API
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = createDestination(session, destinationType);
MessageConsumer consumer = session.createConsumer(destination);
MessageProducer producer = session.createProducer(destination);
// Send the message.
{
StreamMessage message = session.createStreamMessage();
message.writeString("This is a test to see how it works.");
producer.send(message);
}
// Check the message.
{
StreamMessage message = (StreamMessage)consumer.receive(1000);
assertNotNull(message);
// Invalid conversion should throw exception and not move the stream
// position.
try {
message.readByte();
fail("Should have received NumberFormatException");
} catch (NumberFormatException e) {
}
assertEquals("This is a test to see how it works.", message.readString());
// Invalid conversion should throw exception and not move the stream
// position.
try {
message.readByte();
fail("Should have received MessageEOFException");
} catch (MessageEOFException e) {
}
}
assertNull(consumer.receiveNoWait());
}
public void testMapMessage() throws Exception {
// Receive a message with the JMS API
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = createDestination(session, destinationType);
MessageConsumer consumer = session.createConsumer(destination);
MessageProducer producer = session.createProducer(destination);
// send the message.
{
MapMessage message = session.createMapMessage();
message.setBoolean("boolKey", true);
producer.send(message);
}
// get the message.
{
MapMessage message = (MapMessage)consumer.receive(1000);
assertNotNull(message);
assertTrue(message.getBoolean("boolKey"));
}
assertNull(consumer.receiveNoWait());
}
static class ForeignMessage implements TextMessage {
public int deliveryMode;
private String messageId;
private long timestamp;
private String correlationId;
private Destination replyTo;
private Destination destination;
private boolean redelivered;
private String type;
private long expiration;
private int priority;
private String text;
private final HashMap<String, Object> props = new HashMap<String, Object>();
@Override
public String getJMSMessageID() throws JMSException {
return messageId;
}
@Override
public void setJMSMessageID(String arg0) throws JMSException {
messageId = arg0;
}
@Override
public long getJMSTimestamp() throws JMSException {
return timestamp;
}
@Override
public void setJMSTimestamp(long arg0) throws JMSException {
timestamp = arg0;
}
@Override
public byte[] getJMSCorrelationIDAsBytes() throws JMSException {
return null;
}
@Override
public void setJMSCorrelationIDAsBytes(byte[] arg0) throws JMSException {
}
@Override
public void setJMSCorrelationID(String arg0) throws JMSException {
correlationId = arg0;
}
@Override
public String getJMSCorrelationID() throws JMSException {
return correlationId;
}
@Override
public Destination getJMSReplyTo() throws JMSException {
return replyTo;
}
@Override
public void setJMSReplyTo(Destination arg0) throws JMSException {
replyTo = arg0;
}
@Override
public Destination getJMSDestination() throws JMSException {
return destination;
}
@Override
public void setJMSDestination(Destination arg0) throws JMSException {
destination = arg0;
}
@Override
public int getJMSDeliveryMode() throws JMSException {
return deliveryMode;
}
@Override
public void setJMSDeliveryMode(int arg0) throws JMSException {
deliveryMode = arg0;
}
@Override
public boolean getJMSRedelivered() throws JMSException {
return redelivered;
}
@Override
public void setJMSRedelivered(boolean arg0) throws JMSException {
redelivered = arg0;
}
@Override
public String getJMSType() throws JMSException {
return type;
}
@Override
public void setJMSType(String arg0) throws JMSException {
type = arg0;
}
@Override
public long getJMSExpiration() throws JMSException {
return expiration;
}
@Override
public void setJMSExpiration(long arg0) throws JMSException {
expiration = arg0;
}
@Override
public int getJMSPriority() throws JMSException {
return priority;
}
@Override
public void setJMSPriority(int arg0) throws JMSException {
priority = arg0;
}
@Override
public void clearProperties() throws JMSException {
}
@Override
public boolean propertyExists(String arg0) throws JMSException {
return false;
}
@Override
public boolean getBooleanProperty(String arg0) throws JMSException {
return false;
}
@Override
public byte getByteProperty(String arg0) throws JMSException {
return 0;
}
@Override
public short getShortProperty(String arg0) throws JMSException {
return 0;
}
@Override
public int getIntProperty(String arg0) throws JMSException {
return 0;
}
@Override
public long getLongProperty(String arg0) throws JMSException {
return 0;
}
@Override
public float getFloatProperty(String arg0) throws JMSException {
return 0;
}
@Override
public double getDoubleProperty(String arg0) throws JMSException {
return 0;
}
@Override
public String getStringProperty(String arg0) throws JMSException {
return (String)props.get(arg0);
}
@Override
public Object getObjectProperty(String arg0) throws JMSException {
return props.get(arg0);
}
@Override
public Enumeration<?> getPropertyNames() throws JMSException {
return new Vector<String>(props.keySet()).elements();
}
@Override
public void setBooleanProperty(String arg0, boolean arg1) throws JMSException {
}
@Override
public void setByteProperty(String arg0, byte arg1) throws JMSException {
}
@Override
public void setShortProperty(String arg0, short arg1) throws JMSException {
}
@Override
public void setIntProperty(String arg0, int arg1) throws JMSException {
}
@Override
public void setLongProperty(String arg0, long arg1) throws JMSException {
}
@Override
public void setFloatProperty(String arg0, float arg1) throws JMSException {
}
@Override
public void setDoubleProperty(String arg0, double arg1) throws JMSException {
}
@Override
public void setStringProperty(String arg0, String arg1) throws JMSException {
props.put(arg0, arg1);
}
@Override
public void setObjectProperty(String arg0, Object arg1) throws JMSException {
props.put(arg0, arg1);
}
@Override
public void acknowledge() throws JMSException {
}
@Override
public void clearBody() throws JMSException {
}
@Override
public void setText(String arg0) throws JMSException {
text = arg0;
}
@Override
public String getText() throws JMSException {
return text;
}
}
public void testForeignMessage() throws Exception {
// Receive a message with the JMS API
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = createDestination(session, destinationType);
MessageConsumer consumer = session.createConsumer(destination);
MessageProducer producer = session.createProducer(destination);
// Send the message.
{
ForeignMessage message = new ForeignMessage();
message.text = "Hello";
message.setStringProperty("test", "value");
long timeToLive = 10000L;
long start = System.currentTimeMillis();
producer.send(message, Session.AUTO_ACKNOWLEDGE, 7, timeToLive);
long end = System.currentTimeMillis();
//validate jms spec 1.1 section 3.4.11 table 3.1
// JMSDestination, JMSDeliveryMode, JMSExpiration, JMSPriority, JMSMessageID, and JMSTimestamp
//must be set by sending a message.
assertNotNull(message.getJMSDestination());
assertEquals(Session.AUTO_ACKNOWLEDGE, message.getJMSDeliveryMode());
assertTrue(start + timeToLive <= message.getJMSExpiration());
assertTrue(end + timeToLive >= message.getJMSExpiration());
assertEquals(7, message.getJMSPriority());
assertNotNull(message.getJMSMessageID());
assertTrue(start <= message.getJMSTimestamp());
assertTrue(end >= message.getJMSTimestamp());
}
// Validate message is OK.
{
TextMessage message = (TextMessage)consumer.receive(1000);
assertNotNull(message);
assertEquals("Hello", message.getText());
assertEquals("value", message.getStringProperty("test"));
}
assertNull(consumer.receiveNoWait());
}
}

View File

@ -0,0 +1,27 @@
/**
* 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;
/**
*
*/
public class JMSQueueRedeliverTest extends JmsTopicRedeliverTest {
protected void setUp() throws Exception {
topic = false;
super.setUp();
}
}

View File

@ -0,0 +1,141 @@
/**
* 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.util.Enumeration;
import javax.jms.DeliveryMode;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueBrowser;
import javax.jms.Session;
import javax.jms.TextMessage;
import junit.framework.Test;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.ActiveMQMessage;
public class JMSUsecaseTest extends JmsTestSupport {
public ActiveMQDestination destination;
public int deliveryMode;
public int prefetch;
public byte destinationType;
public boolean durableConsumer;
public static Test suite() {
return suite(JMSUsecaseTest.class);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(suite());
}
public void initCombosForTestQueueBrowser() {
addCombinationValues("deliveryMode", new Object[] {Integer.valueOf(DeliveryMode.NON_PERSISTENT), Integer.valueOf(DeliveryMode.PERSISTENT)});
addCombinationValues("destinationType", new Object[] {Byte.valueOf(ActiveMQDestination.QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TEMP_QUEUE_TYPE)});
}
public void testQueueBrowser() throws Exception {
// Send a message to the broker.
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = createDestination(session, destinationType);
MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(this.deliveryMode);
sendMessages(session, producer, 5);
producer.close();
QueueBrowser browser = session.createBrowser((Queue)destination);
Enumeration<?> enumeration = browser.getEnumeration();
for (int i = 0; i < 5; i++) {
Thread.sleep(100);
assertTrue(enumeration.hasMoreElements());
Message m = (Message)enumeration.nextElement();
assertNotNull(m);
assertEquals("" + i, ((TextMessage)m).getText());
}
assertFalse(enumeration.hasMoreElements());
}
public void initCombosForTestSendReceive() {
addCombinationValues("deliveryMode", new Object[] {Integer.valueOf(DeliveryMode.NON_PERSISTENT), Integer.valueOf(DeliveryMode.PERSISTENT)});
addCombinationValues("destinationType", new Object[] {Byte.valueOf(ActiveMQDestination.QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TOPIC_TYPE),
Byte.valueOf(ActiveMQDestination.TEMP_QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TEMP_TOPIC_TYPE)});
}
public void testSendReceive() throws Exception {
// Send a message to the broker.
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = createDestination(session, destinationType);
MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(this.deliveryMode);
MessageConsumer consumer = session.createConsumer(destination);
ActiveMQMessage message = new ActiveMQMessage();
producer.send(message);
// Make sure only 1 message was delivered.
assertNotNull(consumer.receive(1000));
assertNull(consumer.receiveNoWait());
}
public void initCombosForTestSendReceiveTransacted() {
addCombinationValues("deliveryMode", new Object[] {Integer.valueOf(DeliveryMode.NON_PERSISTENT), Integer.valueOf(DeliveryMode.PERSISTENT)});
addCombinationValues("destinationType", new Object[] {Byte.valueOf(ActiveMQDestination.QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TOPIC_TYPE),
Byte.valueOf(ActiveMQDestination.TEMP_QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TEMP_TOPIC_TYPE)});
}
public void testSendReceiveTransacted() throws Exception {
// Send a message to the broker.
connection.start();
Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
destination = createDestination(session, destinationType);
MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(this.deliveryMode);
MessageConsumer consumer = session.createConsumer(destination);
producer.send(session.createTextMessage("test"));
// Message should not be delivered until commit.
assertNull(consumer.receiveNoWait());
session.commit();
// Make sure only 1 message was delivered.
Message message = consumer.receive(1000);
assertNotNull(message);
assertFalse(message.getJMSRedelivered());
assertNull(consumer.receiveNoWait());
// Message should be redelivered is rollback is used.
session.rollback();
// Make sure only 1 message was delivered.
message = consumer.receive(2000);
assertNotNull(message);
assertTrue(message.getJMSRedelivered());
assertNull(consumer.receiveNoWait());
// If we commit now, the message should not be redelivered.
session.commit();
assertNull(consumer.receiveNoWait());
}
}

View File

@ -0,0 +1,50 @@
/**
* 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 javax.jms.ConnectionFactory;
import junit.framework.Test;
/*
* allow an XA session to be used as an auto ack session when no XA transaction
* https://issues.apache.org/activemq/browse/AMQ-2659
*/
public class JMSXAConsumerTest extends JMSConsumerTest {
public static Test suite() {
return suite(JMSXAConsumerTest.class);
}
@Override
protected ConnectionFactory createConnectionFactory() throws Exception {
return new ActiveMQXAConnectionFactory("vm://localhost");
}
// some tests use transactions, these will not work unless an XA transaction is in place
// slip these
public void testPrefetch1MessageNotDispatched() throws Exception {
}
public void testRedispatchOfUncommittedTx() throws Exception {
}
public void testRedispatchOfRolledbackTx() throws Exception {
}
public void testMessageListenerOnMessageCloseUnackedWithPrefetch1StayInQueue() throws Exception {
}
}

View File

@ -0,0 +1,80 @@
/**
* 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 javax.jms.Connection;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
/**
*
*/
public class JmsAutoAckListenerTest extends TestSupport implements MessageListener {
private Connection connection;
protected void setUp() throws Exception {
super.setUp();
connection = createConnection();
}
/**
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
if (connection != null) {
connection.close();
connection = null;
}
super.tearDown();
}
/**
* Tests if acknowleged messages are being consumed.
*
* @throws javax.jms.JMSException
*/
public void testAckedMessageAreConsumed() throws Exception {
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue("test");
MessageProducer producer = session.createProducer(queue);
producer.send(session.createTextMessage("Hello"));
// Consume the message...
MessageConsumer consumer = session.createConsumer(queue);
consumer.setMessageListener(this);
Thread.sleep(10000);
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Attempt to Consume the message...check if message was acknowledge
consumer = session.createConsumer(queue);
Message msg = consumer.receive(1000);
assertNull(msg);
session.close();
}
public void onMessage(Message message) {
assertNotNull(message);
}
}

View File

@ -0,0 +1,80 @@
/**
* 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 javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
/**
*
*/
public class JmsAutoAckTest extends TestSupport {
private Connection connection;
protected void setUp() throws Exception {
super.setUp();
connection = createConnection();
}
/**
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
if (connection != null) {
connection.close();
connection = null;
}
super.tearDown();
}
/**
* Tests if acknowleged messages are being consumed.
*
* @throws javax.jms.JMSException
*/
public void testAckedMessageAreConsumed() throws JMSException {
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue("test");
MessageProducer producer = session.createProducer(queue);
producer.send(session.createTextMessage("Hello"));
// Consume the message...
MessageConsumer consumer = session.createConsumer(queue);
Message msg = consumer.receive(1000);
assertNotNull(msg);
// Reset the session.
session.close();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Attempt to Consume the message...
consumer = session.createConsumer(queue);
msg = consumer.receive(1000);
assertNull(msg);
session.close();
}
}

View File

@ -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;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import javax.jms.BytesMessage;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
import junit.framework.Test;
import org.apache.activemq.broker.BrokerFactory;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.ActiveMQQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Benchmarks the broker by starting many consumer and producers against the
* same destination. Make sure you run with jvm option -server (makes a big
* difference). The tests simulate storing 1000 1k jms messages to see the rate
* of processing msg/sec.
*
*
*/
public class JmsBenchmark extends JmsTestSupport {
private static final transient Logger LOG = LoggerFactory.getLogger(JmsBenchmark.class);
private static final long SAMPLE_DELAY = Integer.parseInt(System.getProperty("SAMPLE_DELAY", "" + 1000 * 5));
private static final long SAMPLES = Integer.parseInt(System.getProperty("SAMPLES", "10"));
private static final long SAMPLE_DURATION = Integer.parseInt(System.getProperty("SAMPLES_DURATION", "" + 1000 * 60));
private static final int PRODUCER_COUNT = Integer.parseInt(System.getProperty("PRODUCER_COUNT", "10"));
private static final int CONSUMER_COUNT = Integer.parseInt(System.getProperty("CONSUMER_COUNT", "10"));
public ActiveMQDestination destination;
public static Test suite() {
return suite(JmsBenchmark.class);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(JmsBenchmark.class);
}
public void initCombos() {
addCombinationValues("destination", new Object[] {new ActiveMQQueue("TEST")});
}
@Override
protected BrokerService createBroker() throws Exception {
return BrokerFactory.createBroker(new URI("broker://(tcp://localhost:0)?persistent=false"));
}
@Override
protected ConnectionFactory createConnectionFactory() throws URISyntaxException, IOException {
return new ActiveMQConnectionFactory(broker.getTransportConnectors().get(0).getServer().getConnectURI());
}
/**
* @throws Throwable
*/
public void testConcurrentSendReceive() throws Throwable {
final Semaphore connectionsEstablished = new Semaphore(1 - (CONSUMER_COUNT + PRODUCER_COUNT));
final Semaphore workerDone = new Semaphore(1 - (CONSUMER_COUNT + PRODUCER_COUNT));
final CountDownLatch sampleTimeDone = new CountDownLatch(1);
final AtomicInteger producedMessages = new AtomicInteger(0);
final AtomicInteger receivedMessages = new AtomicInteger(0);
final Callable<Object> producer = new Callable<Object>() {
@Override
public Object call() throws JMSException, InterruptedException {
Connection connection = factory.createConnection();
connections.add(connection);
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
BytesMessage message = session.createBytesMessage();
message.writeBytes(new byte[1024]);
connection.start();
connectionsEstablished.release();
while (!sampleTimeDone.await(0, TimeUnit.MILLISECONDS)) {
producer.send(message);
producedMessages.incrementAndGet();
}
connection.close();
workerDone.release();
return null;
}
};
final Callable<Object> consumer = new Callable<Object>() {
@Override
public Object call() throws JMSException, InterruptedException {
Connection connection = factory.createConnection();
connections.add(connection);
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer consumer = session.createConsumer(destination);
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message msg) {
receivedMessages.incrementAndGet();
}
});
connection.start();
connectionsEstablished.release();
sampleTimeDone.await();
connection.close();
workerDone.release();
return null;
}
};
final Throwable workerError[] = new Throwable[1];
for (int i = 0; i < PRODUCER_COUNT; i++) {
new Thread("Producer:" + i) {
@Override
public void run() {
try {
producer.call();
} catch (Throwable e) {
e.printStackTrace();
workerError[0] = e;
}
}
}.start();
}
for (int i = 0; i < CONSUMER_COUNT; i++) {
new Thread("Consumer:" + i) {
@Override
public void run() {
try {
consumer.call();
} catch (Throwable e) {
e.printStackTrace();
workerError[0] = e;
}
}
}.start();
}
LOG.info(getName() + ": Waiting for Producers and Consumers to startup.");
connectionsEstablished.acquire();
LOG.info("Producers and Consumers are now running. Waiting for system to reach steady state: " + (SAMPLE_DELAY / 1000.0f) + " seconds");
Thread.sleep(1000 * 10);
LOG.info("Starting sample: " + SAMPLES + " each lasting " + (SAMPLE_DURATION / 1000.0f) + " seconds");
for (int i = 0; i < SAMPLES; i++) {
long start = System.currentTimeMillis();
producedMessages.set(0);
receivedMessages.set(0);
Thread.sleep(SAMPLE_DURATION);
long end = System.currentTimeMillis();
int r = receivedMessages.get();
int p = producedMessages.get();
LOG.info("published: " + p + " msgs at " + (p * 1000f / (end - start)) + " msgs/sec, " + "consumed: " + r + " msgs at " + (r * 1000f / (end - start)) + " msgs/sec");
}
LOG.info("Sample done.");
sampleTimeDone.countDown();
workerDone.acquire();
if (workerError[0] != null) {
throw workerError[0];
}
}
}

View File

@ -0,0 +1,130 @@
/**
* 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 javax.jms.Connection;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
/**
*
*/
public class JmsClientAckListenerTest extends TestSupport implements MessageListener {
private Connection connection;
private boolean dontAck;
protected void setUp() throws Exception {
super.setUp();
connection = createConnection();
}
/**
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
if (connection != null) {
connection.close();
connection = null;
}
super.tearDown();
}
/**
* Tests if acknowleged messages are being consumed.
*
* @throws javax.jms.JMSException
*/
public void testAckedMessageAreConsumed() throws Exception {
connection.start();
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
Queue queue = session.createQueue("test");
MessageProducer producer = session.createProducer(queue);
producer.send(session.createTextMessage("Hello"));
// Consume the message...
MessageConsumer consumer = session.createConsumer(queue);
consumer.setMessageListener(this);
Thread.sleep(10000);
// Reset the session.
session.close();
session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
// Attempt to Consume the message...
consumer = session.createConsumer(queue);
Message msg = consumer.receive(1000);
assertNull(msg);
session.close();
}
/**
* Tests if unacknowleged messages are being redelivered when the consumer
* connects again.
*
* @throws javax.jms.JMSException
*/
public void testUnAckedMessageAreNotConsumedOnSessionClose() throws Exception {
connection.start();
// don't aknowledge message on onMessage() call
dontAck = true;
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
Queue queue = session.createQueue("test");
MessageProducer producer = session.createProducer(queue);
producer.send(session.createTextMessage("Hello"));
// Consume the message...
MessageConsumer consumer = session.createConsumer(queue);
consumer.setMessageListener(this);
// Don't ack the message.
// Reset the session. This should cause the Unacked message to be
// redelivered.
session.close();
Thread.sleep(10000);
session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
// Attempt to Consume the message...
consumer = session.createConsumer(queue);
Message msg = consumer.receive(2000);
assertNotNull(msg);
msg.acknowledge();
session.close();
}
public void onMessage(Message message) {
assertNotNull(message);
if (!dontAck) {
try {
message.acknowledge();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

View File

@ -0,0 +1,151 @@
/**
* 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 javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
/**
*
*/
public class JmsClientAckTest extends TestSupport {
private Connection connection;
protected void setUp() throws Exception {
super.setUp();
connection = createConnection();
}
/**
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
if (connection != null) {
connection.close();
connection = null;
}
super.tearDown();
}
/**
* Tests if acknowledged messages are being consumed.
*
* @throws JMSException
*/
public void testAckedMessageAreConsumed() throws JMSException {
connection.start();
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
Queue queue = session.createQueue(getQueueName());
MessageProducer producer = session.createProducer(queue);
producer.send(session.createTextMessage("Hello"));
// Consume the message...
MessageConsumer consumer = session.createConsumer(queue);
Message msg = consumer.receive(1000);
assertNotNull(msg);
msg.acknowledge();
// Reset the session.
session.close();
session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
// Attempt to Consume the message...
consumer = session.createConsumer(queue);
msg = consumer.receive(1000);
assertNull(msg);
session.close();
}
/**
* Tests if acknowledged messages are being consumed.
*
* @throws JMSException
*/
public void testLastMessageAcked() throws JMSException {
connection.start();
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
Queue queue = session.createQueue(getQueueName());
MessageProducer producer = session.createProducer(queue);
producer.send(session.createTextMessage("Hello"));
producer.send(session.createTextMessage("Hello2"));
producer.send(session.createTextMessage("Hello3"));
// Consume the message...
MessageConsumer consumer = session.createConsumer(queue);
Message msg = consumer.receive(1000);
assertNotNull(msg);
msg = consumer.receive(1000);
assertNotNull(msg);
msg = consumer.receive(1000);
assertNotNull(msg);
msg.acknowledge();
// Reset the session.
session.close();
session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
// Attempt to Consume the message...
consumer = session.createConsumer(queue);
msg = consumer.receive(1000);
assertNull(msg);
session.close();
}
/**
* Tests if unacknowledged messages are being re-delivered when the consumer connects again.
*
* @throws JMSException
*/
public void testUnAckedMessageAreNotConsumedOnSessionClose() throws JMSException {
connection.start();
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
Queue queue = session.createQueue(getQueueName());
MessageProducer producer = session.createProducer(queue);
producer.send(session.createTextMessage("Hello"));
// Consume the message...
MessageConsumer consumer = session.createConsumer(queue);
Message msg = consumer.receive(1000);
assertNotNull(msg);
// Don't ack the message.
// Reset the session. This should cause the unacknowledged message to be re-delivered.
session.close();
session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
// Attempt to Consume the message...
consumer = session.createConsumer(queue);
msg = consumer.receive(2000);
assertNotNull(msg);
msg.acknowledge();
session.close();
}
protected String getQueueName() {
return getClass().getName() + "." + getName();
}
}

View File

@ -0,0 +1,158 @@
/**
* 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.util.Random;
import java.util.Vector;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
/**
*
*/
public class JmsConnectionStartStopTest extends TestSupport {
private static final org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory
.getLog(JmsConnectionStartStopTest.class);
private Connection startedConnection;
private Connection stoppedConnection;
/**
* @see junit.framework.TestCase#setUp()
*/
@Override
protected void setUp() throws Exception {
LOG.info(getClass().getClassLoader().getResource("log4j.properties"));
ActiveMQConnectionFactory factory = createConnectionFactory();
startedConnection = factory.createConnection();
startedConnection.start();
stoppedConnection = factory.createConnection();
}
/**
* @see junit.framework.TestCase#tearDown()
*/
@Override
protected void tearDown() throws Exception {
stoppedConnection.close();
startedConnection.close();
}
/**
* Tests if the consumer receives the messages that were sent before the
* connection was started.
*
* @throws JMSException
*/
public void testStoppedConsumerHoldsMessagesTillStarted() throws JMSException {
Session startedSession = startedConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Session stoppedSession = stoppedConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Setup the consumers.
Topic topic = startedSession.createTopic("test");
MessageConsumer startedConsumer = startedSession.createConsumer(topic);
MessageConsumer stoppedConsumer = stoppedSession.createConsumer(topic);
// Send the message.
MessageProducer producer = startedSession.createProducer(topic);
TextMessage message = startedSession.createTextMessage("Hello");
producer.send(message);
// Test the assertions.
Message m = startedConsumer.receive(1000);
assertNotNull(m);
m = stoppedConsumer.receive(1000);
assertNull(m);
stoppedConnection.start();
m = stoppedConsumer.receive(5000);
assertNotNull(m);
startedSession.close();
stoppedSession.close();
}
/**
* Tests if the consumer is able to receive messages eveb when the
* connecction restarts multiple times.
*
* @throws Exception
*/
public void testMultipleConnectionStops() throws Exception {
testStoppedConsumerHoldsMessagesTillStarted();
stoppedConnection.stop();
testStoppedConsumerHoldsMessagesTillStarted();
stoppedConnection.stop();
testStoppedConsumerHoldsMessagesTillStarted();
}
public void testConcurrentSessionCreateWithStart() throws Exception {
ThreadPoolExecutor executor = new ThreadPoolExecutor(50, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
final Vector<Throwable> exceptions = new Vector<Throwable>();
final Random rand = new Random();
Runnable createSessionTask = new Runnable() {
@Override
public void run() {
try {
TimeUnit.MILLISECONDS.sleep(rand.nextInt(10));
stoppedConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
} catch (Exception e) {
exceptions.add(e);
}
}
};
Runnable startStopTask = new Runnable() {
@Override
public void run() {
try {
TimeUnit.MILLISECONDS.sleep(rand.nextInt(10));
stoppedConnection.start();
stoppedConnection.stop();
} catch (Exception e) {
exceptions.add(e);
}
}
};
for (int i=0; i<1000; i++) {
executor.execute(createSessionTask);
executor.execute(startStopTask);
}
executor.shutdown();
assertTrue("executor terminated", executor.awaitTermination(30, TimeUnit.SECONDS));
assertTrue("no exceptions: " + exceptions, exceptions.isEmpty());
}
}

View File

@ -0,0 +1,151 @@
/**
* 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.util.Vector;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import junit.framework.TestCase;
public class JmsConsumerResetActiveListenerTest extends TestCase {
private Connection connection;
private ActiveMQConnectionFactory factory;
protected void setUp() throws Exception {
factory = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false");
connection = factory.createConnection();
}
protected void tearDown() throws Exception {
if (connection != null) {
connection.close();
connection = null;
}
}
/**
* verify the (undefined by spec) behaviour of setting a listener while receiving a message.
*
* @throws Exception
*/
public void testSetListenerFromListener() throws Exception {
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
Destination dest = session.createQueue("Queue-" + getName());
final MessageConsumer consumer = session.createConsumer(dest);
final CountDownLatch latch = new CountDownLatch(2);
final AtomicBoolean first = new AtomicBoolean(true);
final Vector<Object> results = new Vector<Object>();
consumer.setMessageListener(new MessageListener() {
public void onMessage(Message message) {
if (first.compareAndSet(true, false)) {
try {
consumer.setMessageListener(this);
results.add(message);
} catch (JMSException e) {
results.add(e);
}
} else {
results.add(message);
}
latch.countDown();
}
});
connection.start();
MessageProducer producer = session.createProducer(dest);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
producer.send(session.createTextMessage("First"));
producer.send(session.createTextMessage("Second"));
assertTrue("we did not timeout", latch.await(5, TimeUnit.SECONDS));
assertEquals("we have a result", 2, results.size());
Object result = results.get(0);
assertTrue(result instanceof TextMessage);
assertEquals("result is first", "First", ((TextMessage)result).getText());
result = results.get(1);
assertTrue(result instanceof TextMessage);
assertEquals("result is first", "Second", ((TextMessage)result).getText());
}
/**
* and a listener on a new consumer, just in case.
*
* @throws Exception
*/
public void testNewConsumerSetListenerFromListener() throws Exception {
final Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
final Destination dest = session.createQueue("Queue-" + getName());
final MessageConsumer consumer = session.createConsumer(dest);
final CountDownLatch latch = new CountDownLatch(2);
final AtomicBoolean first = new AtomicBoolean(true);
final Vector<Object> results = new Vector<Object>();
consumer.setMessageListener(new MessageListener() {
public void onMessage(Message message) {
if (first.compareAndSet(true, false)) {
try {
MessageConsumer anotherConsumer = session.createConsumer(dest);
anotherConsumer.setMessageListener(this);
results.add(message);
} catch (JMSException e) {
results.add(e);
}
} else {
results.add(message);
}
latch.countDown();
}
});
connection.start();
MessageProducer producer = session.createProducer(dest);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
producer.send(session.createTextMessage("First"));
producer.send(session.createTextMessage("Second"));
assertTrue("we did not timeout", latch.await(5, TimeUnit.SECONDS));
assertEquals("we have a result", 2, results.size());
Object result = results.get(0);
assertTrue(result instanceof TextMessage);
assertEquals("result is first", "First", ((TextMessage)result).getText());
result = results.get(1);
assertTrue(result instanceof TextMessage);
assertEquals("result is first", "Second", ((TextMessage)result).getText());
}
}

View File

@ -0,0 +1,99 @@
/**
* 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 javax.jms.Connection;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.Topic;
/**
*
*/
public class JmsCreateConsumerInOnMessageTest extends TestSupport implements MessageListener {
private Connection connection;
private Session publisherSession;
private Session consumerSession;
private MessageConsumer consumer;
private MessageConsumer testConsumer;
private MessageProducer producer;
private Topic topic;
private Object lock = new Object();
/*
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
super.setUp();
super.topic = true;
connection = createConnection();
connection.setClientID("connection:" + getSubject());
publisherSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
consumerSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
topic = (Topic)super.createDestination("Test.Topic");
consumer = consumerSession.createConsumer(topic);
consumer.setMessageListener(this);
producer = publisherSession.createProducer(topic);
connection.start();
}
/*
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
super.tearDown();
connection.close();
}
/**
* Tests if a consumer can be created asynchronusly
*
* @throws Exception
*/
public void testCreateConsumer() throws Exception {
Message msg = super.createMessage();
producer.send(msg);
if (testConsumer == null) {
synchronized (lock) {
lock.wait(3000);
}
}
assertTrue(testConsumer != null);
}
/**
* Use the asynchronous subscription mechanism
*
* @param message
*/
public void onMessage(Message message) {
try {
testConsumer = consumerSession.createConsumer(topic);
consumerSession.createProducer(topic);
synchronized (lock) {
lock.notify();
}
} catch (Exception ex) {
ex.printStackTrace();
assertTrue(false);
}
}
}

View File

@ -0,0 +1,52 @@
/**
* 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 javax.jms.DeliveryMode;
import org.apache.activemq.test.JmsTopicSendReceiveTest;
/**
*
*/
public class JmsDurableQueueWildcardSendReceiveTest extends JmsTopicSendReceiveTest {
/**
* Set up the test with a queue and persistent delivery mode.
*
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
topic = false;
deliveryMode = DeliveryMode.PERSISTENT;
super.setUp();
}
/**
* Returns the consumer subject.
*/
protected String getConsumerSubject() {
return "FOO.>";
}
/**
* Returns the producer subject.
*/
protected String getProducerSubject() {
return "FOO.BAR.HUMBUG";
}
}

View File

@ -0,0 +1,27 @@
/**
* 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;
/**
*
*/
public class JmsDurableTopicSelectorTest extends JmsTopicSelectorTest {
public void setUp() throws Exception {
durable = true;
super.setUp();
}
}

View File

@ -0,0 +1,90 @@
/**
* 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 javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import org.apache.activemq.test.JmsTopicSendReceiveTest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
*/
public class JmsDurableTopicSendReceiveTest extends JmsTopicSendReceiveTest {
private static final Logger LOG = LoggerFactory.getLogger(JmsDurableTopicSendReceiveTest.class);
protected Connection connection2;
protected Session session2;
protected Session consumeSession2;
protected MessageConsumer consumer2;
protected MessageProducer producer2;
protected Destination consumerDestination2;
protected Destination producerDestination2;
/**
* Set up a durable suscriber test.
*
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
this.durable = true;
super.setUp();
}
/**
* Test if all the messages sent are being received.
*
* @throws Exception
*/
public void testSendWhileClosed() throws Exception {
connection2 = createConnection();
connection2.setClientID("test");
connection2.start();
session2 = connection2.createSession(false, Session.AUTO_ACKNOWLEDGE);
producer2 = session2.createProducer(null);
producer2.setDeliveryMode(deliveryMode);
producerDestination2 = session2.createTopic(getProducerSubject() + "2");
Thread.sleep(1000);
consumeSession2 = connection2.createSession(false, Session.AUTO_ACKNOWLEDGE);
consumerDestination2 = session2.createTopic(getConsumerSubject() + "2");
consumer2 = consumeSession2.createDurableSubscriber((Topic)consumerDestination2, getName());
Thread.sleep(1000);
consumer2.close();
TextMessage message = session2.createTextMessage("test");
message.setStringProperty("test", "test");
message.setJMSType("test");
producer2.send(producerDestination2, message);
LOG.info("Creating durable consumer");
consumer2 = consumeSession2.createDurableSubscriber((Topic)consumerDestination2, getName());
Message msg = consumer2.receive(1000);
assertNotNull(msg);
assertEquals(((TextMessage)msg).getText(), "test");
assertEquals(msg.getJMSType(), "test");
assertEquals(msg.getStringProperty("test"), "test");
connection2.stop();
connection2.close();
}
}

View File

@ -0,0 +1,40 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq;
import javax.jms.DeliveryMode;
import org.apache.activemq.test.JmsResourceProvider;
/**
*
*/
public class JmsDurableTopicTransactionTest extends JmsTopicTransactionTest {
/**
* @see JmsTransactionTestSupport#getJmsResourceProvider()
*/
protected JmsResourceProvider getJmsResourceProvider() {
JmsResourceProvider provider = new JmsResourceProvider();
provider.setTopic(true);
provider.setDeliveryMode(DeliveryMode.PERSISTENT);
provider.setClientID(getClass().getName());
provider.setDurableName(getName());
return provider;
}
}

View File

@ -0,0 +1,54 @@
/**
* 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 javax.jms.DeliveryMode;
import org.apache.activemq.test.JmsTopicSendReceiveTest;
/**
*
*/
public class JmsDurableTopicWildcardSendReceiveTest extends JmsTopicSendReceiveTest {
/**
* Sets up a test with a topic destination, durable suscriber and persistent
* delivery mode.
*
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
topic = true;
durable = true;
deliveryMode = DeliveryMode.PERSISTENT;
super.setUp();
}
/**
* Returns the consumer subject.
*/
protected String getConsumerSubject() {
return "FOO.>";
}
/**
* Returns the producer subject.
*/
protected String getProducerSubject() {
return "FOO.BAR.HUMBUG";
}
}

View File

@ -0,0 +1,170 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
import org.apache.activemq.broker.BrokerService;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
public class JmsMessageConsumerTest {
private BrokerService brokerService;
private String brokerURI;
@Rule public TestName name = new TestName();
@Before
public void startBroker() throws Exception {
brokerService = new BrokerService();
brokerService.setPersistent(false);
brokerService.setUseJmx(false);
brokerService.start();
brokerService.waitUntilStarted();
brokerURI = "vm://localhost?create=false";
}
@After
public void stopBroker() throws Exception {
if (brokerService != null) {
brokerService.stop();
}
}
@Test
public void testSyncReceiveWithExpirationChecks() throws Exception {
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(brokerURI);
Connection connection = factory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue(name.getMethodName());
MessageConsumer consumer = session.createConsumer(destination);
MessageProducer producer = session.createProducer(destination);
producer.setTimeToLive(TimeUnit.SECONDS.toMillis(2));
connection.start();
producer.send(session.createTextMessage("test"));
// Allow message to expire in the prefetch buffer
TimeUnit.SECONDS.sleep(4);
assertNull(consumer.receive(1000));
connection.close();
}
@Test
public void testSyncReceiveWithIgnoreExpirationChecks() throws Exception {
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(brokerURI);
factory.setConsumerExpiryCheckEnabled(false);
Connection connection = factory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue(name.getMethodName());
MessageConsumer consumer = session.createConsumer(destination);
MessageProducer producer = session.createProducer(destination);
producer.setTimeToLive(TimeUnit.SECONDS.toMillis(2));
connection.start();
producer.send(session.createTextMessage("test"));
// Allow message to expire in the prefetch buffer
TimeUnit.SECONDS.sleep(4);
assertNotNull(consumer.receive(1000));
connection.close();
}
@Test
public void testAsyncReceiveWithExpirationChecks() throws Exception {
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(brokerURI);
final CountDownLatch received = new CountDownLatch(1);
Connection connection = factory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue(name.getMethodName());
MessageConsumer consumer = session.createConsumer(destination);
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
received.countDown();
}
});
MessageProducer producer = session.createProducer(destination);
producer.setTimeToLive(TimeUnit.SECONDS.toMillis(2));
producer.send(session.createTextMessage("test"));
// Allow message to expire in the prefetch buffer
TimeUnit.SECONDS.sleep(4);
connection.start();
assertFalse(received.await(1, TimeUnit.SECONDS));
connection.close();
}
@Test
public void testAsyncReceiveWithoutExpirationChecks() throws Exception {
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(brokerURI);
factory.setConsumerExpiryCheckEnabled(false);
final CountDownLatch received = new CountDownLatch(1);
Connection connection = factory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue(name.getMethodName());
MessageConsumer consumer = session.createConsumer(destination);
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
received.countDown();
}
});
MessageProducer producer = session.createProducer(destination);
producer.setTimeToLive(TimeUnit.SECONDS.toMillis(2));
producer.send(session.createTextMessage("test"));
// Allow message to expire in the prefetch buffer
TimeUnit.SECONDS.sleep(4);
connection.start();
assertTrue(received.await(5, TimeUnit.SECONDS));
connection.close();
}
}

View File

@ -0,0 +1,641 @@
/**
* 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.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueBrowser;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import org.apache.activemq.advisory.ConsumerEvent;
import org.apache.activemq.advisory.ConsumerEventSource;
import org.apache.activemq.advisory.ConsumerListener;
import org.apache.activemq.broker.BrokerFactory;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.broker.TransportConnector;
import org.apache.activemq.broker.region.RegionBroker;
import org.apache.activemq.broker.region.TopicRegion;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
import org.apache.activemq.command.BrokerInfo;
import org.apache.activemq.network.DiscoveryNetworkConnector;
import org.apache.activemq.network.NetworkBridge;
import org.apache.activemq.network.NetworkConnector;
import org.apache.activemq.util.IdGenerator;
import org.apache.activemq.util.MessageIdList;
import org.apache.activemq.util.Wait;
import org.apache.activemq.xbean.BrokerFactoryBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
/**
* Test case support that allows the easy management and connection of several
* brokers.
*
*
*/
public class JmsMultipleBrokersTestSupport extends CombinationTestSupport {
private static final Logger LOG = LoggerFactory.getLogger(JmsMultipleBrokersTestSupport.class);
public static final String AUTO_ASSIGN_TRANSPORT = "tcp://localhost:0";
public static int maxSetupTime = 5000;
protected Map<String, BrokerItem> brokers;
protected Map<String, Destination> destinations;
protected int messageSize = 1;
protected boolean persistentDelivery = true;
protected boolean verbose;
protected NetworkConnector bridgeBrokers(String localBrokerName, String remoteBrokerName) throws Exception {
return bridgeBrokers(localBrokerName, remoteBrokerName, false, 1, true);
}
protected NetworkConnector bridgeBrokers(String localBrokerName, String remoteBrokerName, boolean dynamicOnly) throws Exception {
BrokerService localBroker = brokers.get(localBrokerName).broker;
BrokerService remoteBroker = brokers.get(remoteBrokerName).broker;
return bridgeBrokers(localBroker, remoteBroker, dynamicOnly, 1, true, false);
}
protected NetworkConnector bridgeBrokers(String localBrokerName, String remoteBrokerName, boolean dynamicOnly, int networkTTL, boolean conduit) throws Exception {
BrokerService localBroker = brokers.get(localBrokerName).broker;
BrokerService remoteBroker = brokers.get(remoteBrokerName).broker;
return bridgeBrokers(localBroker, remoteBroker, dynamicOnly, networkTTL, conduit, false);
}
// Overwrite this method to specify how you want to bridge the two brokers
// By default, bridge them using add network connector of the local broker
// and the first connector of the remote broker
protected NetworkConnector bridgeBrokers(BrokerService localBroker, BrokerService remoteBroker, boolean dynamicOnly, int networkTTL, boolean conduit, boolean failover) throws Exception {
List<TransportConnector> transportConnectors = remoteBroker.getTransportConnectors();
URI remoteURI;
if (!transportConnectors.isEmpty()) {
remoteURI = transportConnectors.get(0).getConnectUri();
String uri = "static:(" + remoteURI + ")";
if (failover) {
uri = "static:(failover:(" + remoteURI + "))";
}
NetworkConnector connector = new DiscoveryNetworkConnector(new URI(uri));
connector.setName("to-" + remoteBroker.getBrokerName());
connector.setDynamicOnly(dynamicOnly);
connector.setNetworkTTL(networkTTL);
connector.setConduitSubscriptions(conduit);
localBroker.addNetworkConnector(connector);
maxSetupTime = 2000;
return connector;
} else {
throw new Exception("Remote broker has no registered connectors.");
}
}
// This will interconnect all brokers using multicast
protected void bridgeAllBrokers() throws Exception {
bridgeAllBrokers("default", 1, false, false);
}
protected void bridgeAllBrokers(String groupName, int ttl, boolean suppressduplicateQueueSubs) throws Exception {
bridgeAllBrokers(groupName, ttl, suppressduplicateQueueSubs, false);
}
protected void bridgeAllBrokers(String groupName, int ttl, boolean suppressduplicateQueueSubs, boolean decreasePriority) throws Exception {
Collection<BrokerItem> brokerList = brokers.values();
for (Iterator<BrokerItem> i = brokerList.iterator(); i.hasNext();) {
BrokerService broker = i.next().broker;
List<TransportConnector> transportConnectors = broker.getTransportConnectors();
if (transportConnectors.isEmpty()) {
broker.addConnector(new URI(AUTO_ASSIGN_TRANSPORT));
transportConnectors = broker.getTransportConnectors();
}
TransportConnector transport = transportConnectors.get(0);
transport.setDiscoveryUri(new URI("multicast://default?group=" + groupName));
NetworkConnector nc = broker.addNetworkConnector("multicast://default?group=" + groupName);
nc.setNetworkTTL(ttl);
nc.setSuppressDuplicateQueueSubscriptions(suppressduplicateQueueSubs);
nc.setDecreaseNetworkConsumerPriority(decreasePriority);
}
// Multicasting may take longer to setup
maxSetupTime = 8000;
}
protected void waitForBridgeFormation(final int min) throws Exception {
for (BrokerItem brokerItem : brokers.values()) {
final BrokerService broker = brokerItem.broker;
waitForBridgeFormation(broker, min, 0);
}
}
public boolean waitForBridgeFormation(final BrokerService broker, final int min, final int bridgeIndex) throws Exception {
return waitForBridgeFormation(broker, min, bridgeIndex, Wait.MAX_WAIT_MILLIS*2);
}
public boolean waitForBridgeFormation(final BrokerService broker, final int min, final int bridgeIndex, long wait) throws Exception {
boolean result = false;
if (!broker.getNetworkConnectors().isEmpty()) {
result = Wait.waitFor(new Wait.Condition() {
public boolean isSatisified() throws Exception {
int activeCount = 0;
for (NetworkBridge bridge : broker.getNetworkConnectors().get(bridgeIndex).activeBridges()) {
if (bridge.getRemoteBrokerName() != null) {
LOG.info("found bridge[" + bridge + "] to " + bridge.getRemoteBrokerName() + " on broker :" + broker.getBrokerName());
activeCount++;
}
}
return activeCount >= min;
}}, wait);
}
return result;
}
protected void waitForMinTopicRegionConsumerCount(final String name, final int count) throws Exception {
final BrokerService broker = brokers.get(name).broker;
final TopicRegion topicRegion = (TopicRegion) ((RegionBroker) broker.getRegionBroker()).getTopicRegion();
assertTrue("found expected consumers in topic region of" + name, Wait.waitFor(new Wait.Condition() {
@Override
public boolean isSatisified() throws Exception {
LOG.info("topic consumers: " + name +", " + topicRegion.getSubscriptions().toString());
return topicRegion.getSubscriptions().size() >= count;
}
}));
}
/**
* Timed wait for {@link #hasBridge(String, String)}.
*
* @see #hasBridge(String, String)
*
* @param localBrokerName
* - the name of the broker on the "local" side of the bridge
* @param remoteBrokerName
* - the name of the broker on the "remote" side of the bridge
* @param time
* - the maximum time to wait for the bridge to be established
* @param units
* - the units for <param>time</param>
* @throws InterruptedException
* - if the calling thread is interrupted
* @throws TimeoutException
* - if the bridge is not established within the time limit
* @throws Exception
* - some other unknown error occurs
*/
protected void waitForBridge(final String localBrokerName,
final String remoteBrokerName, long time, TimeUnit units)
throws InterruptedException, TimeoutException, Exception {
if (!Wait.waitFor(new Wait.Condition() {
public boolean isSatisified() {
return hasBridge(localBrokerName, remoteBrokerName);
}
}, units.toMillis(time))) {
throw new TimeoutException("Bridge not established from broker "
+ localBrokerName + " to " + remoteBrokerName + " within "
+ units.toMillis(time) + " milliseconds.");
}
}
/**
* Determines whether a bridge has been established between the specified
* brokers.Establishment means that connections have been created and broker
* info has been exchanged. Due to the asynchronous nature of the
* connections, there is still a possibility that the bridge may fail
* shortly after establishment.
*
* @param localBrokerName
* - the name of the broker on the "local" side of the bridge
* @param remoteBrokerName
* - the name of the broker on the "remote" side of the bridge
*/
protected boolean hasBridge(String localBrokerName, String remoteBrokerName) {
final BrokerItem fromBroker = brokers.get(localBrokerName);
if (fromBroker == null) {
throw new IllegalArgumentException("Unknown broker: "
+ localBrokerName);
}
for (BrokerInfo peerInfo : fromBroker.broker.getRegionBroker()
.getPeerBrokerInfos()) {
if (peerInfo.getBrokerName().equals(remoteBrokerName)) {
return true;
}
}
return false;
}
protected void waitForBridgeFormation() throws Exception {
waitForBridgeFormation(1);
}
protected void startAllBrokers() throws Exception {
Collection<BrokerItem> brokerList = brokers.values();
for (Iterator<BrokerItem> i = brokerList.iterator(); i.hasNext();) {
BrokerService broker = i.next().broker;
broker.start();
broker.waitUntilStarted();
}
Thread.sleep(maxSetupTime);
}
protected BrokerService createBroker(String brokerName) throws Exception {
BrokerService broker = new BrokerService();
broker.setBrokerName(brokerName);
brokers.put(brokerName, new BrokerItem(broker));
return broker;
}
protected BrokerService createBroker(URI brokerUri) throws Exception {
BrokerService broker = BrokerFactory.createBroker(brokerUri);
configureBroker(broker);
brokers.put(broker.getBrokerName(), new BrokerItem(broker));
return broker;
}
protected void configureBroker(BrokerService broker) {
}
protected BrokerService createBroker(Resource configFile) throws Exception {
BrokerFactoryBean brokerFactory = new BrokerFactoryBean(configFile);
brokerFactory.afterPropertiesSet();
BrokerService broker = brokerFactory.getBroker();
brokers.put(broker.getBrokerName(), new BrokerItem(broker));
return broker;
}
protected ConnectionFactory getConnectionFactory(String brokerName) throws Exception {
BrokerItem brokerItem = brokers.get(brokerName);
if (brokerItem != null) {
return brokerItem.factory;
}
return null;
}
protected Connection createConnection(String brokerName) throws Exception {
BrokerItem brokerItem = brokers.get(brokerName);
if (brokerItem != null) {
return brokerItem.createConnection();
}
return null;
}
protected MessageConsumer createSyncConsumer(String brokerName, Destination dest) throws Exception {
BrokerItem brokerItem = brokers.get(brokerName);
if (brokerItem != null) {
Connection con = brokerItem.createConnection();
con.start();
Session sess = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer consumer = sess.createConsumer(dest);
return consumer;
}
return null;
}
protected MessageConsumer createConsumer(String brokerName, Destination dest) throws Exception {
return createConsumer(brokerName, dest, null, null);
}
protected MessageConsumer createConsumer(String brokerName, Destination dest, String messageSelector) throws Exception {
return createConsumer(brokerName, dest, null, messageSelector);
}
protected MessageConsumer createConsumer(String brokerName, Destination dest, CountDownLatch latch) throws Exception {
return createConsumer(brokerName, dest, latch, null);
}
protected MessageConsumer createConsumer(String brokerName, Destination dest, CountDownLatch latch, String messageSelector) throws Exception {
BrokerItem brokerItem = brokers.get(brokerName);
if (brokerItem != null) {
return brokerItem.createConsumer(dest, latch, messageSelector);
}
return null;
}
protected QueueBrowser createBrowser(String brokerName, Destination dest) throws Exception {
BrokerItem brokerItem = brokers.get(brokerName);
if (brokerItem != null) {
return brokerItem.createBrowser(dest);
}
return null;
}
protected MessageConsumer createDurableSubscriber(String brokerName, Topic dest, String name) throws Exception {
BrokerItem brokerItem = brokers.get(brokerName);
if (brokerItem != null) {
return brokerItem.createDurableSubscriber(dest, name);
}
return null;
}
protected MessageIdList getBrokerMessages(String brokerName) {
BrokerItem brokerItem = brokers.get(brokerName);
if (brokerItem != null) {
return brokerItem.getAllMessages();
}
return null;
}
protected MessageIdList getConsumerMessages(String brokerName, MessageConsumer consumer) {
BrokerItem brokerItem = brokers.get(brokerName);
if (brokerItem != null) {
return brokerItem.getConsumerMessages(consumer);
}
return null;
}
protected void assertConsumersConnect(String brokerName, Destination destination, final int count, long timeout) throws Exception {
BrokerItem brokerItem = brokers.get(brokerName);
Connection conn = brokerItem.createConnection();
conn.start();
ConsumerEventSource ces = new ConsumerEventSource(conn, destination);
try {
final AtomicInteger actualConnected = new AtomicInteger();
final CountDownLatch latch = new CountDownLatch(1);
ces.setConsumerListener(new ConsumerListener(){
public void onConsumerEvent(ConsumerEvent event) {
if( actualConnected.get() < count ) {
actualConnected.set(event.getConsumerCount());
}
if( event.getConsumerCount() >= count ) {
latch.countDown();
}
}
});
ces.start();
latch.await(timeout, TimeUnit.MILLISECONDS);
assertTrue("Expected at least "+count+" consumers to connect, but only "+actualConnected.get()+" connectect within "+timeout+" ms", actualConnected.get() >= count);
} finally {
ces.stop();
conn.close();
brokerItem.connections.remove(conn);
}
}
protected void sendMessages(String brokerName, Destination destination, int count) throws Exception {
sendMessages(brokerName, destination, count, null);
}
protected void sendMessages(String brokerName, Destination destination, int count, HashMap<String, Object>properties) throws Exception {
BrokerItem brokerItem = brokers.get(brokerName);
Connection conn = brokerItem.createConnection();
conn.start();
Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = brokerItem.createProducer(destination, sess);
producer.setDeliveryMode(persistentDelivery ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
for (int i = 0; i < count; i++) {
TextMessage msg = createTextMessage(sess, conn.getClientID() + ": Message-" + i);
if (properties != null) {
for (String propertyName : properties.keySet()) {
msg.setObjectProperty(propertyName, properties.get(propertyName));
}
}
producer.send(msg);
onSend(i, msg);
}
producer.close();
sess.close();
conn.close();
brokerItem.connections.remove(conn);
}
protected void onSend(int i, TextMessage msg) {
}
protected TextMessage createTextMessage(Session session, String initText) throws Exception {
TextMessage msg = session.createTextMessage();
// Pad message text
if (initText.length() < messageSize) {
char[] data = new char[messageSize - initText.length()];
Arrays.fill(data, '*');
String str = new String(data);
msg.setText(initText + str);
// Do not pad message text
} else {
msg.setText(initText);
}
return msg;
}
protected ActiveMQDestination createDestination(String name, boolean topic) throws JMSException {
Destination dest;
if (topic) {
dest = new ActiveMQTopic(name);
destinations.put(name, dest);
return (ActiveMQDestination)dest;
} else {
dest = new ActiveMQQueue(name);
destinations.put(name, dest);
return (ActiveMQDestination)dest;
}
}
protected void setUp() throws Exception {
super.setUp();
brokers = new HashMap<String, BrokerItem>();
destinations = new HashMap<String, Destination>();
}
protected void tearDown() throws Exception {
destroyAllBrokers();
super.tearDown();
}
protected void destroyBroker(String brokerName) throws Exception {
BrokerItem brokerItem = brokers.remove(brokerName);
if (brokerItem != null) {
brokerItem.destroy();
}
}
protected void destroyAllBrokers() throws Exception {
for (Iterator<BrokerItem> i = brokers.values().iterator(); i.hasNext();) {
BrokerItem brokerItem = i.next();
brokerItem.destroy();
}
brokers.clear();
}
// Class to group broker components together
public class BrokerItem {
public BrokerService broker;
public ActiveMQConnectionFactory factory;
public List<Connection> connections;
public Map<MessageConsumer, MessageIdList> consumers;
public MessageIdList allMessages = new MessageIdList();
public boolean persistent;
private IdGenerator id;
public BrokerItem(BrokerService broker) throws Exception {
this.broker = broker;
factory = new ActiveMQConnectionFactory(broker.getVmConnectorURI());
factory.setConnectionIDPrefix(broker.getBrokerName());
consumers = Collections.synchronizedMap(new HashMap<MessageConsumer, MessageIdList>());
connections = Collections.synchronizedList(new ArrayList<Connection>());
allMessages.setVerbose(verbose);
id = new IdGenerator(broker.getBrokerName() + ":");
}
public Connection createConnection() throws Exception {
Connection conn = factory.createConnection();
conn.setClientID(id.generateId());
connections.add(conn);
return conn;
}
public MessageConsumer createConsumer(Destination dest) throws Exception {
return createConsumer(dest, null, null);
}
public MessageConsumer createConsumer(Destination dest, String messageSelector) throws Exception {
return createConsumer(dest, null, messageSelector);
}
public MessageConsumer createConsumer(Destination dest, CountDownLatch latch, String messageSelector) throws Exception {
Connection c = createConnection();
c.start();
Session s = c.createSession(false, Session.AUTO_ACKNOWLEDGE);
return createConsumerWithSession(dest, s, latch, messageSelector);
}
public MessageConsumer createConsumerWithSession(Destination dest, Session sess) throws Exception {
return createConsumerWithSession(dest, sess, null, null);
}
public MessageConsumer createConsumerWithSession(Destination dest, Session sess, CountDownLatch latch, String messageSelector) throws Exception {
MessageConsumer client = sess.createConsumer(dest, messageSelector);
MessageIdList messageIdList = new MessageIdList();
messageIdList.setCountDownLatch(latch);
messageIdList.setParent(allMessages);
client.setMessageListener(messageIdList);
consumers.put(client, messageIdList);
return client;
}
public QueueBrowser createBrowser(Destination dest) throws Exception {
Connection c = createConnection();
c.start();
Session s = c.createSession(false, Session.AUTO_ACKNOWLEDGE);
return s.createBrowser((Queue)dest);
}
public MessageConsumer createDurableSubscriber(Topic dest, String name) throws Exception {
Connection c = createConnection();
c.start();
Session s = c.createSession(false, Session.AUTO_ACKNOWLEDGE);
return createDurableSubscriber(dest, s, name);
}
public MessageConsumer createDurableSubscriber(Topic dest, Session sess, String name) throws Exception {
MessageConsumer client = sess.createDurableSubscriber((Topic)dest, name);
MessageIdList messageIdList = new MessageIdList();
messageIdList.setParent(allMessages);
client.setMessageListener(messageIdList);
consumers.put(client, messageIdList);
return client;
}
public MessageIdList getAllMessages() {
return allMessages;
}
public MessageIdList getConsumerMessages(MessageConsumer consumer) {
return consumers.get(consumer);
}
public MessageProducer createProducer(Destination dest) throws Exception {
Connection c = createConnection();
c.start();
Session s = c.createSession(false, Session.AUTO_ACKNOWLEDGE);
return createProducer(dest, s);
}
public MessageProducer createProducer(Destination dest, Session sess) throws Exception {
MessageProducer client = sess.createProducer(dest);
client.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
return client;
}
public void destroy() throws Exception {
while (!connections.isEmpty()) {
Connection c = connections.remove(0);
try {
c.close();
} catch (ConnectionClosedException e) {
} catch (JMSException e) {
}
}
broker.stop();
broker.waitUntilStopped();
consumers.clear();
broker = null;
connections = null;
consumers = null;
factory = null;
}
}
}

View File

@ -0,0 +1,335 @@
/**
* 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.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.TopicSubscriber;
import org.apache.activemq.broker.BrokerFactory;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
import org.apache.activemq.util.MessageIdList;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.rules.TestName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.junit.Assert.*;
/**
* Test case support used to test multiple message comsumers and message
* producers connecting to a single broker.
*
*
*/
public class JmsMultipleClientsTestSupport {
@Rule
public TestName testName = new TestName();
protected static final Logger LOG = LoggerFactory.getLogger(JmsMultipleClientsTestSupport.class);
protected Map<MessageConsumer, MessageIdList> consumers = new HashMap<MessageConsumer, MessageIdList>(); // Map of consumer with messages
// received
protected int consumerCount = 1;
protected int producerCount = 1;
protected int messageSize = 1024;
protected boolean useConcurrentSend = true;
protected boolean autoFail = true;
protected boolean durable;
public boolean topic;
protected boolean persistent;
protected BrokerService broker;
protected Destination destination;
protected List<Connection> connections = Collections.synchronizedList(new ArrayList<Connection>());
protected MessageIdList allMessagesList = new MessageIdList();
private AtomicInteger producerLock;
protected void startProducers(Destination dest, int msgCount) throws Exception {
startProducers(createConnectionFactory(), dest, msgCount);
}
protected void startProducers(final ConnectionFactory factory, final Destination dest, final int msgCount) throws Exception {
// Use concurrent send
if (useConcurrentSend) {
producerLock = new AtomicInteger(producerCount);
for (int i = 0; i < producerCount; i++) {
Thread t = new Thread(new Runnable() {
public void run() {
try {
sendMessages(factory.createConnection(), dest, msgCount);
} catch (Exception e) {
e.printStackTrace();
}
synchronized (producerLock) {
producerLock.decrementAndGet();
producerLock.notifyAll();
}
}
});
t.start();
}
// Wait for all producers to finish sending
synchronized (producerLock) {
while (producerLock.get() != 0) {
producerLock.wait(2000);
}
}
// Use serialized send
} else {
for (int i = 0; i < producerCount; i++) {
sendMessages(factory.createConnection(), dest, msgCount);
}
}
}
protected void sendMessages(Connection connection, Destination destination, int count) throws Exception {
connections.add(connection);
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
for (int i = 0; i < count; i++) {
TextMessage msg = createTextMessage(session, "" + i);
producer.send(msg);
}
producer.close();
session.close();
connection.close();
}
protected TextMessage createTextMessage(Session session, String initText) throws Exception {
TextMessage msg = session.createTextMessage();
// Pad message text
if (initText.length() < messageSize) {
char[] data = new char[messageSize - initText.length()];
Arrays.fill(data, '*');
String str = new String(data);
msg.setText(initText + str);
// Do not pad message text
} else {
msg.setText(initText);
}
return msg;
}
protected void startConsumers(Destination dest) throws Exception {
startConsumers(createConnectionFactory(), dest);
}
protected void startConsumers(ConnectionFactory factory, Destination dest) throws Exception {
MessageConsumer consumer;
for (int i = 0; i < consumerCount; i++) {
if (durable && topic) {
consumer = createDurableSubscriber(factory.createConnection(), dest, "consumer" + (i + 1));
} else {
consumer = createMessageConsumer(factory.createConnection(), dest);
}
MessageIdList list = new MessageIdList();
list.setParent(allMessagesList);
consumer.setMessageListener(list);
consumers.put(consumer, list);
}
}
protected MessageConsumer createMessageConsumer(Connection conn, Destination dest) throws Exception {
connections.add(conn);
Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
final MessageConsumer consumer = sess.createConsumer(dest);
conn.start();
return consumer;
}
protected TopicSubscriber createDurableSubscriber(Connection conn, Destination dest, String name) throws Exception {
conn.setClientID(name);
connections.add(conn);
conn.start();
Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
final TopicSubscriber consumer = sess.createDurableSubscriber((javax.jms.Topic)dest, name);
return consumer;
}
protected void waitForAllMessagesToBeReceived(int messageCount) throws Exception {
allMessagesList.waitForMessagesToArrive(messageCount);
}
protected ActiveMQDestination createDestination() throws JMSException {
String name = "." + getClass().getName() + "." + getName();
// ensure not inadvertently composite because of combos
name = name.replace(' ','_');
name = name.replace(',','&');
if (topic) {
destination = new ActiveMQTopic("Topic" + name);
return (ActiveMQDestination)destination;
} else {
destination = new ActiveMQQueue("Queue" + name);
return (ActiveMQDestination)destination;
}
}
protected ConnectionFactory createConnectionFactory() throws Exception {
return new ActiveMQConnectionFactory("vm://localhost");
}
protected BrokerService createBroker() throws Exception {
return BrokerFactory.createBroker(new URI("broker://()/localhost?persistent=false&useJmx=true"));
}
@Before
public void setUp() throws Exception {
broker = createBroker();
broker.start();
}
@After
public void tearDown() throws Exception {
for (Iterator<Connection> iter = connections.iterator(); iter.hasNext();) {
Connection conn = iter.next();
try {
conn.close();
} catch (Throwable e) {
}
}
if (broker !=null ) { // FIXME remove
broker.stop();
allMessagesList.flushMessages();
consumers.clear();
}
}
/*
* Some helpful assertions for multiple consumers.
*/
protected void assertConsumerReceivedAtLeastXMessages(MessageConsumer consumer, int msgCount) {
MessageIdList messageIdList = consumers.get(consumer);
messageIdList.assertAtLeastMessagesReceived(msgCount);
}
protected void assertConsumerReceivedAtMostXMessages(MessageConsumer consumer, int msgCount) {
MessageIdList messageIdList = consumers.get(consumer);
messageIdList.assertAtMostMessagesReceived(msgCount);
}
protected void assertConsumerReceivedXMessages(MessageConsumer consumer, int msgCount) {
MessageIdList messageIdList = consumers.get(consumer);
messageIdList.assertMessagesReceivedNoWait(msgCount);
}
protected void assertEachConsumerReceivedAtLeastXMessages(int msgCount) {
for (Iterator<MessageConsumer> i = consumers.keySet().iterator(); i.hasNext();) {
assertConsumerReceivedAtLeastXMessages(i.next(), msgCount);
}
}
protected void assertEachConsumerReceivedAtMostXMessages(int msgCount) {
for (Iterator<MessageConsumer> i = consumers.keySet().iterator(); i.hasNext();) {
assertConsumerReceivedAtMostXMessages(i.next(), msgCount);
}
}
protected void assertEachConsumerReceivedXMessages(int msgCount) {
for (Iterator<MessageConsumer> i = consumers.keySet().iterator(); i.hasNext();) {
assertConsumerReceivedXMessages(i.next(), msgCount);
}
}
protected void assertTotalMessagesReceived(int msgCount) {
allMessagesList.assertMessagesReceivedNoWait(msgCount);
// now lets count the individual messages received
int totalMsg = 0;
for (Iterator<MessageConsumer> i = consumers.keySet().iterator(); i.hasNext();) {
MessageIdList messageIdList = consumers.get(i.next());
totalMsg += messageIdList.getMessageCount();
}
assertEquals("Total of consumers message count", msgCount, totalMsg);
}
public String getName() {
return getName(false);
}
public String getName(boolean original) {
String currentTestName = testName.getMethodName();
currentTestName = currentTestName.replace("[","");
currentTestName = currentTestName.replace("]","");
return currentTestName;
}
public void assertDestinationMemoryUsageGoesToZero() throws Exception {
assertEquals("destination memory is back to 0", 0,
TestSupport.getDestination(broker, ActiveMQDestination.transform(destination)).getMemoryUsage().getPercentUsage());
}
/*
* This is copied from AutoFailTestSupport. We may want to move it to someplace where more
* tests can use it.
*/
public static void dumpAllThreads(String prefix) {
Map<Thread, StackTraceElement[]> stacks = Thread.getAllStackTraces();
for (Map.Entry<Thread, StackTraceElement[]> stackEntry : stacks.entrySet()) {
System.err.println(prefix + " " + stackEntry.getKey());
for(StackTraceElement element : stackEntry.getValue()) {
System.err.println(" " + element);
}
}
}
}

View File

@ -0,0 +1,448 @@
/**
* 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.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.QueueBrowser;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.management.ObjectName;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.TabularData;
import junit.framework.Test;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.broker.jmx.QueueViewMBean;
import org.apache.activemq.broker.region.BaseDestination;
import org.apache.activemq.broker.region.policy.PolicyEntry;
import org.apache.activemq.broker.region.policy.PolicyMap;
import org.apache.activemq.command.ActiveMQQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class JmsQueueBrowserTest extends JmsTestSupport {
private static final Logger LOG = LoggerFactory.getLogger(ActiveMQXAConnectionFactoryTest.class);
public boolean isUseCache = false;
public static Test suite() throws Exception {
return suite(JmsQueueBrowserTest.class);
}
/**
* Tests the queue browser. Browses the messages then the consumer tries to receive them. The messages should still
* be in the queue even when it was browsed.
*
* @throws Exception
*/
public void testReceiveBrowseReceive() throws Exception {
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
ActiveMQQueue destination = new ActiveMQQueue("TEST");
MessageProducer producer = session.createProducer(destination);
MessageConsumer consumer = session.createConsumer(destination);
connection.start();
Message[] outbound = new Message[]{session.createTextMessage("First Message"),
session.createTextMessage("Second Message"),
session.createTextMessage("Third Message")};
// lets consume any outstanding messages from previous test runs
while (consumer.receive(1000) != null) {
}
producer.send(outbound[0]);
producer.send(outbound[1]);
producer.send(outbound[2]);
// Get the first.
assertEquals(outbound[0], consumer.receive(1000));
consumer.close();
QueueBrowser browser = session.createBrowser(destination);
Enumeration<?> enumeration = browser.getEnumeration();
// browse the second
assertTrue("should have received the second message", enumeration.hasMoreElements());
assertEquals(outbound[1], enumeration.nextElement());
// browse the third.
assertTrue("Should have received the third message", enumeration.hasMoreElements());
assertEquals(outbound[2], enumeration.nextElement());
// There should be no more.
boolean tooMany = false;
while (enumeration.hasMoreElements()) {
LOG.info("Got extra message: " + ((TextMessage) enumeration.nextElement()).getText());
tooMany = true;
}
assertFalse(tooMany);
browser.close();
// Re-open the consumer.
consumer = session.createConsumer(destination);
// Receive the second.
assertEquals(outbound[1], consumer.receive(1000));
// Receive the third.
assertEquals(outbound[2], consumer.receive(1000));
consumer.close();
}
public void initCombosForTestBatchSendBrowseReceive() {
addCombinationValues("isUseCache", new Boolean[]{Boolean.TRUE, Boolean.FALSE});
}
public void testBatchSendBrowseReceive() throws Exception {
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
ActiveMQQueue destination = new ActiveMQQueue("TEST");
MessageProducer producer = session.createProducer(destination);
MessageConsumer consumer = session.createConsumer(destination);
connection.start();
TextMessage[] outbound = new TextMessage[10];
for (int i=0; i<10; i++) {
outbound[i] = session.createTextMessage( i + " Message");
};
// lets consume any outstanding messages from previous test runs
while (consumer.receive(1000) != null) {
}
consumer.close();
for (int i=0;i<outbound.length; i++) {
producer.send(outbound[i]);
}
QueueBrowser browser = session.createBrowser(destination);
Enumeration<?> enumeration = browser.getEnumeration();
for (int i=0; i<outbound.length; i++) {
assertTrue("should have a", enumeration.hasMoreElements());
assertEquals(outbound[i], enumeration.nextElement());
}
browser.close();
for (int i=0;i<outbound.length; i++) {
producer.send(outbound[i]);
}
// verify second batch is visible to browse
browser = session.createBrowser(destination);
enumeration = browser.getEnumeration();
for (int j=0; j<2;j++) {
for (int i=0; i<outbound.length; i++) {
assertTrue("should have a", enumeration.hasMoreElements());
assertEquals("j=" + j + ", i=" + i, outbound[i].getText(), ((TextMessage) enumeration.nextElement()).getText());
}
}
browser.close();
consumer = session.createConsumer(destination);
for (int i=0; i<outbound.length * 2; i++) {
assertNotNull("Got message: " + i, consumer.receive(2000));
}
consumer.close();
}
public void initCombosForTestBatchSendJmxBrowseReceive() {
addCombinationValues("isUseCache", new Boolean[]{Boolean.TRUE, Boolean.FALSE});
}
public void testBatchSendJmxBrowseReceive() throws Exception {
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
ActiveMQQueue destination = new ActiveMQQueue("TEST");
MessageProducer producer = session.createProducer(destination);
MessageConsumer consumer = session.createConsumer(destination);
connection.start();
TextMessage[] outbound = new TextMessage[10];
for (int i=0; i<10; i++) {
outbound[i] = session.createTextMessage( i + " Message");
};
// lets consume any outstanding messages from previous test runs
while (consumer.receive(1000) != null) {
}
consumer.close();
for (int i=0;i<outbound.length; i++) {
producer.send(outbound[i]);
}
ObjectName queueViewMBeanName = new ObjectName("org.apache.activemq:type=Broker,brokerName=localhost,destinationType=Queue,destinationName=TEST");
LOG.info("Create QueueView MBean...");
QueueViewMBean proxy = (QueueViewMBean) broker.getManagementContext().newProxyInstance(queueViewMBeanName, QueueViewMBean.class, true);
long concount = proxy.getConsumerCount();
LOG.info("Consumer Count :" + concount);
long messcount = proxy.getQueueSize();
LOG.info("current number of messages in the queue :" + messcount);
// lets browse
CompositeData[] compdatalist = proxy.browse();
if (compdatalist.length == 0) {
fail("There is no message in the queue:");
}
String[] messageIDs = new String[compdatalist.length];
for (int i = 0; i < compdatalist.length; i++) {
CompositeData cdata = compdatalist[i];
if (i == 0) {
LOG.info("Columns: " + cdata.getCompositeType().keySet());
}
messageIDs[i] = (String)cdata.get("JMSMessageID");
LOG.info("message " + i + " : " + cdata.values());
}
TabularData table = proxy.browseAsTable();
LOG.info("Found tabular data: " + table);
assertTrue("Table should not be empty!", table.size() > 0);
assertEquals("Queue size", outbound.length, proxy.getQueueSize());
assertEquals("Queue size", outbound.length, compdatalist.length);
assertEquals("Queue size", outbound.length, table.size());
LOG.info("Send another 10");
for (int i=0;i<outbound.length; i++) {
producer.send(outbound[i]);
}
LOG.info("Browse again");
messcount = proxy.getQueueSize();
LOG.info("current number of messages in the queue :" + messcount);
compdatalist = proxy.browse();
if (compdatalist.length == 0) {
fail("There is no message in the queue:");
}
messageIDs = new String[compdatalist.length];
for (int i = 0; i < compdatalist.length; i++) {
CompositeData cdata = compdatalist[i];
if (i == 0) {
LOG.info("Columns: " + cdata.getCompositeType().keySet());
}
messageIDs[i] = (String)cdata.get("JMSMessageID");
LOG.info("message " + i + " : " + cdata.values());
}
table = proxy.browseAsTable();
LOG.info("Found tabular data: " + table);
assertTrue("Table should not be empty!", table.size() > 0);
assertEquals("Queue size", outbound.length*2, proxy.getQueueSize());
assertEquals("Queue size", outbound.length*2, compdatalist.length);
assertEquals("Queue size", outbound.length * 2, table.size());
consumer = session.createConsumer(destination);
for (int i=0; i<outbound.length * 2; i++) {
assertNotNull("Got message: " + i, consumer.receive(2000));
}
consumer.close();
}
public void testBrowseReceive() throws Exception {
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
ActiveMQQueue destination = new ActiveMQQueue("TEST");
connection.start();
// create consumer
MessageConsumer consumer = session.createConsumer(destination);
// lets consume any outstanding messages from previous test runs
while (consumer.receive(1000) != null) {
}
Message[] outbound = new Message[]{session.createTextMessage("First Message"),
session.createTextMessage("Second Message"),
session.createTextMessage("Third Message")};
MessageProducer producer = session.createProducer(destination);
producer.send(outbound[0]);
// create browser first
QueueBrowser browser = session.createBrowser(destination);
Enumeration<?> enumeration = browser.getEnumeration();
// browse the first message
assertTrue("should have received the first message", enumeration.hasMoreElements());
assertEquals(outbound[0], enumeration.nextElement());
// Receive the first message.
assertEquals(outbound[0], consumer.receive(1000));
consumer.close();
browser.close();
producer.close();
}
public void testLargeNumberOfMessages() throws Exception {
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
ActiveMQQueue destination = new ActiveMQQueue("TEST");
connection.start();
MessageProducer producer = session.createProducer(destination);
int numberOfMessages = 4096;
for (int i = 0; i < numberOfMessages; i++) {
producer.send(session.createTextMessage("Message: " + i));
}
QueueBrowser browser = session.createBrowser(destination);
Enumeration<?> enumeration = browser.getEnumeration();
assertTrue(enumeration.hasMoreElements());
int numberBrowsed = 0;
while (enumeration.hasMoreElements()) {
Message browsed = (Message) enumeration.nextElement();
if (LOG.isDebugEnabled()) {
LOG.debug("Browsed Message [{}]", browsed.getJMSMessageID());
}
numberBrowsed++;
}
System.out.println("Number browsed: " + numberBrowsed);
assertEquals(numberOfMessages, numberBrowsed);
browser.close();
producer.close();
}
public void testQueueBrowserWith2Consumers() throws Exception {
final int numMessages = 1000;
connection.setAlwaysSyncSend(false);
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
ActiveMQQueue destination = new ActiveMQQueue("TEST");
ActiveMQQueue destinationPrefetch10 = new ActiveMQQueue("TEST?jms.prefetchSize=10");
ActiveMQQueue destinationPrefetch1 = new ActiveMQQueue("TEST?jms.prefetchsize=1");
connection.start();
ActiveMQConnection connection2 = (ActiveMQConnection)factory.createConnection(userName, password);
connection2.start();
connections.add(connection2);
Session session2 = connection2.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(destination);
MessageConsumer consumer = session.createConsumer(destinationPrefetch10);
// lets consume any outstanding messages from previous test runs
while (consumer.receive(1000) != null) {
}
for (int i=0; i<numMessages; i++) {
TextMessage message = session.createTextMessage("Message: " + i);
producer.send(message);
}
QueueBrowser browser = session2.createBrowser(destinationPrefetch1);
@SuppressWarnings("unchecked")
Enumeration<Message> browserView = browser.getEnumeration();
List<Message> messages = new ArrayList<Message>();
for (int i = 0; i < numMessages; i++) {
Message m1 = consumer.receive(5000);
assertNotNull("m1 is null for index: " + i, m1);
messages.add(m1);
}
int i = 0;
for (; i < numMessages && browserView.hasMoreElements(); i++) {
Message m1 = messages.get(i);
Message m2 = browserView.nextElement();
assertNotNull("m2 is null for index: " + i, m2);
assertEquals(m1.getJMSMessageID(), m2.getJMSMessageID());
}
// currently browse max page size is ignored for a queue browser consumer
// only guarantee is a page size - but a snapshot of pagedinpending is
// used so it is most likely more
assertTrue("got at least our expected minimum in the browser: ", i > BaseDestination.MAX_PAGE_SIZE);
assertFalse("nothing left in the browser", browserView.hasMoreElements());
assertNull("consumer finished", consumer.receiveNoWait());
}
public void testBrowseClose() throws Exception {
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
ActiveMQQueue destination = new ActiveMQQueue("TEST");
connection.start();
TextMessage[] outbound = new TextMessage[]{session.createTextMessage("First Message"),
session.createTextMessage("Second Message"),
session.createTextMessage("Third Message")};
// create consumer
MessageConsumer consumer = session.createConsumer(destination);
// lets consume any outstanding messages from previous test runs
while (consumer.receive(1000) != null) {
}
MessageProducer producer = session.createProducer(destination);
producer.send(outbound[0]);
producer.send(outbound[1]);
producer.send(outbound[2]);
// create browser first
QueueBrowser browser = session.createBrowser(destination);
Enumeration<?> enumeration = browser.getEnumeration();
// browse some messages
assertEquals(outbound[0], enumeration.nextElement());
assertEquals(outbound[1], enumeration.nextElement());
//assertEquals(outbound[2], (Message) enumeration.nextElement());
browser.close();
// Receive the first message.
TextMessage msg = (TextMessage)consumer.receive(1000);
assertEquals("Expected " + outbound[0].getText() + " but received " + msg.getText(), outbound[0], msg);
msg = (TextMessage)consumer.receive(1000);
assertEquals("Expected " + outbound[1].getText() + " but received " + msg.getText(), outbound[1], msg);
msg = (TextMessage)consumer.receive(1000);
assertEquals("Expected " + outbound[2].getText() + " but received " + msg.getText(), outbound[2], msg);
consumer.close();
producer.close();
}
@Override
protected BrokerService createBroker() throws Exception {
BrokerService brokerService = super.createBroker();
PolicyMap policyMap = new PolicyMap();
PolicyEntry policyEntry = new PolicyEntry();
policyEntry.setUseCache(isUseCache);
policyEntry.setMaxBrowsePageSize(4096);
policyMap.setDefaultEntry(policyEntry);
brokerService.setDestinationPolicy(policyMap);
return brokerService;
}
}

View File

@ -0,0 +1,119 @@
/**
* 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 javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.Topic;
import org.apache.activemq.broker.BrokerRegistry;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.broker.region.Queue;
import org.apache.activemq.broker.region.RegionBroker;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.test.JmsTopicSendReceiveTest;
import org.apache.activemq.util.Wait;
/**
*
*/
public class JmsQueueCompositeSendReceiveTest extends JmsTopicSendReceiveTest {
private static final org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory
.getLog(JmsQueueCompositeSendReceiveTest.class);
/**
* Sets a test to have a queue destination and non-persistent delivery mode.
*
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
topic = false;
deliveryMode = DeliveryMode.NON_PERSISTENT;
super.setUp();
}
/**
* Returns the consumer subject.
*
* @return String - consumer subject
* @see org.apache.activemq.test.TestSupport#getConsumerSubject()
*/
protected String getConsumerSubject() {
return "FOO.BAR.HUMBUG";
}
/**
* Returns the producer subject.
*
* @return String - producer subject
* @see org.apache.activemq.test.TestSupport#getProducerSubject()
*/
protected String getProducerSubject() {
return "FOO.BAR.HUMBUG,FOO.BAR.HUMBUG2";
}
/**
* Test if all the messages sent are being received.
*
* @throws Exception
*/
public void testSendReceive() throws Exception {
super.testSendReceive();
messages.clear();
Destination consumerDestination = consumeSession.createQueue("FOO.BAR.HUMBUG2");
LOG.info("Created consumer destination: " + consumerDestination + " of type: " + consumerDestination.getClass());
MessageConsumer consumer = null;
if (durable) {
LOG.info("Creating durable consumer");
consumer = consumeSession.createDurableSubscriber((Topic) consumerDestination, getName());
} else {
consumer = consumeSession.createConsumer(consumerDestination);
}
consumer.setMessageListener(this);
assertMessagesAreReceived();
LOG.info("" + data.length + " messages(s) received, closing down connections");
}
public void testDuplicate() throws Exception {
ActiveMQDestination queue = (ActiveMQDestination)session.createQueue("TEST,TEST");
for (int i = 0; i < data.length; i++) {
Message message = createMessage(i);
configureMessage(message);
if (verbose) {
LOG.info("About to send a message: " + message + " with text: " + data[i]);
}
producer.send(queue, message);
}
Thread.sleep(200); // wait for messages to be queued
BrokerService broker = BrokerRegistry.getInstance().lookup("localhost");
final Queue dest = (Queue)((RegionBroker)broker.getRegionBroker()).getQueueRegion().getDestinationMap().get(new ActiveMQQueue("TEST"));
assertTrue("all messages were received", Wait.waitFor(new Wait.Condition(){
public boolean isSatisified() throws Exception {
return data.length == dest.getDestinationStatistics().getMessages().getCount();
}}));
dest.purge();
assertEquals(0, dest.getDestinationStatistics().getMessages().getCount());
}
}

View File

@ -0,0 +1,33 @@
/**
* 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;
/**
*
*/
public class JmsQueueRequestReplyTest extends JmsTopicRequestReplyTest {
/**
* Set up the test with a queue.
*
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
topic = false;
super.setUp();
}
}

View File

@ -0,0 +1,28 @@
/**
* 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;
/**
*
*/
public class JmsQueueSelectorTest extends JmsTopicSelectorTest {
public void setUp() throws Exception {
topic = false;
super.setUp();
}
}

View File

@ -0,0 +1,35 @@
/**
* 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 org.apache.activemq.test.JmsTopicSendReceiveTest;
/**
*
*/
public class JmsQueueSendReceiveTest extends JmsTopicSendReceiveTest {
/**
* Set up the test with a queue.
*
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
topic = false;
super.setUp();
}
}

View File

@ -0,0 +1,86 @@
/**
* 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.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.apache.activemq.broker.BrokerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
*/
public class JmsQueueSendReceiveTwoConnectionsStartBeforeBrokerTest extends JmsQueueSendReceiveTwoConnectionsTest {
private static final Logger LOG = LoggerFactory.getLogger(JmsQueueSendReceiveTwoConnectionsStartBeforeBrokerTest.class);
private Queue<Exception> errors = new ConcurrentLinkedQueue<Exception>();
private int delayBeforeStartingBroker = 1000;
private BrokerService broker;
public void startBroker() {
// Initialize the broker
LOG.info("Lets wait: " + delayBeforeStartingBroker + " millis before creating the broker");
try {
Thread.sleep(delayBeforeStartingBroker);
} catch (InterruptedException e) {
e.printStackTrace();
}
LOG.info("Now starting the broker");
try {
broker = new BrokerService();
broker.setPersistent(false);
broker.addConnector("tcp://localhost:61616");
broker.start();
} catch (Exception e) {
LOG.info("Caught: " + e);
errors.add(e);
}
}
protected ActiveMQConnectionFactory createConnectionFactory() throws Exception {
return new ActiveMQConnectionFactory("failover:(tcp://localhost:61616)?maxReconnectAttempts=10&useExponentialBackOff=false&initialReconnectDelay=200");
}
protected void setUp() throws Exception {
setAutoFail(true);
// now lets asynchronously start a broker
Thread thread = new Thread() {
public void run() {
startBroker();
}
};
thread.start();
super.setUp();
}
protected void tearDown() throws Exception {
super.tearDown();
if (broker != null) {
broker.stop();
}
if (!errors.isEmpty()) {
Exception e = errors.remove();
throw e;
}
}
}

View File

@ -0,0 +1,36 @@
/**
* 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 org.apache.activemq.test.JmsTopicSendReceiveWithTwoConnectionsTest;
/**
*
*/
public class JmsQueueSendReceiveTwoConnectionsTest extends JmsTopicSendReceiveWithTwoConnectionsTest {
/**
* Set up the test with a queue and using two connections.
*
* @see junit.framework.TestCase#setUp()
*/
@Override
protected void setUp() throws Exception {
topic = false;
super.setUp();
}
}

View File

@ -0,0 +1,33 @@
/**
* 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;
/**
*
*/
public class JmsQueueSendReceiveUsingTwoSessionsTest extends JmsQueueSendReceiveTest {
/**
* Set up the test using two sessions.
*
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
useSeparateSession = true;
super.setUp();
}
}

View File

@ -0,0 +1,88 @@
/**
* 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 javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.MessageConsumer;
import javax.jms.Topic;
import org.apache.activemq.test.JmsTopicSendReceiveTest;
/**
*
*/
public class JmsQueueTopicCompositeSendReceiveTest extends JmsTopicSendReceiveTest {
private static final org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory
.getLog(JmsQueueTopicCompositeSendReceiveTest.class);
Destination consumerDestination2;
MessageConsumer consumer2;
/**
* Sets a test to have a queue destination and non-persistent delivery mode.
*
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
deliveryMode = DeliveryMode.NON_PERSISTENT;
topic = false;
super.setUp();
consumerDestination2 = consumeSession.createTopic("FOO.BAR.HUMBUG2");
LOG.info("Created consumer destination: " + consumerDestination2 + " of type: " + consumerDestination2.getClass());
if (durable) {
LOG.info("Creating durable consumer");
consumer2 = consumeSession.createDurableSubscriber((Topic) consumerDestination2, getName());
} else {
consumer2 = consumeSession.createConsumer(consumerDestination2);
}
}
/**
* Returns the consumer subject.
*
* @return String - consumer subject
* @see org.apache.activemq.test.TestSupport#getConsumerSubject()
*/
protected String getConsumerSubject() {
return "FOO.BAR.HUMBUG";
}
/**
* Returns the producer subject.
*
* @return String - producer subject
* @see org.apache.activemq.test.TestSupport#getProducerSubject()
*/
protected String getProducerSubject() {
return "queue://FOO.BAR.HUMBUG,topic://FOO.BAR.HUMBUG2";
}
/**
* Test if all the messages sent are being received.
*
* @throws Exception
*/
public void testSendReceive() throws Exception {
super.testSendReceive();
messages.clear();
consumer2.setMessageListener(this);
assertMessagesAreReceived();
LOG.info("" + data.length + " messages(s) received, closing down connections");
}
}

View File

@ -0,0 +1,174 @@
/**
* 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 javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.test.JmsTopicSendReceiveTest;
/**
*
*/
public class JmsQueueWildcardSendReceiveTest extends JmsTopicSendReceiveTest {
private String destination1String = "TEST.ONE.ONE";
private String destination2String = "TEST.ONE.ONE.ONE";
private String destination3String = "TEST.ONE.TWO";
private String destination4String = "TEST.TWO.ONE";
/**
* Sets a test to have a queue destination and non-persistent delivery mode.
*
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
topic = false;
deliveryMode = DeliveryMode.NON_PERSISTENT;
super.setUp();
}
/**
* Returns the consumer subject.
*
* @return String - consumer subject
* @see org.apache.activemq.test.TestSupport#getConsumerSubject()
*/
protected String getConsumerSubject() {
return "FOO.>";
}
/**
* Returns the producer subject.
*
* @return String - producer subject
* @see org.apache.activemq.test.TestSupport#getProducerSubject()
*/
protected String getProducerSubject() {
return "FOO.BAR.HUMBUG";
}
public void testReceiveWildcardQueueEndAsterisk() throws Exception {
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
ActiveMQDestination destination1 = (ActiveMQDestination)session.createQueue(destination1String);
ActiveMQDestination destination3 = (ActiveMQDestination)session.createQueue(destination3String);
Message m = null;
MessageConsumer consumer = null;
String text = null;
sendMessage(session, destination1, destination1String);
sendMessage(session, destination3, destination3String);
ActiveMQDestination destination6 = (ActiveMQDestination)session.createQueue("TEST.ONE.*");
consumer = session.createConsumer(destination6);
m = consumer.receive(1000);
assertNotNull(m);
text = ((TextMessage)m).getText();
if (!(text.equals(destination1String) || text.equals(destination3String))) {
fail("unexpected message:" + text);
}
m = consumer.receive(1000);
assertNotNull(m);
text = ((TextMessage)m).getText();
if (!(text.equals(destination1String) || text.equals(destination3String))) {
fail("unexpected message:" + text);
}
assertNull(consumer.receiveNoWait());
}
public void testReceiveWildcardQueueEndGreaterThan() throws Exception {
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
ActiveMQDestination destination1 = (ActiveMQDestination)session.createQueue(destination1String);
ActiveMQDestination destination2 = (ActiveMQDestination)session.createQueue(destination2String);
ActiveMQDestination destination3 = (ActiveMQDestination)session.createQueue(destination3String);
Message m = null;
MessageConsumer consumer = null;
String text = null;
sendMessage(session, destination1, destination1String);
sendMessage(session, destination2, destination2String);
sendMessage(session, destination3, destination3String);
ActiveMQDestination destination7 = (ActiveMQDestination)session.createQueue("TEST.ONE.>");
consumer = session.createConsumer(destination7);
m = consumer.receive(1000);
assertNotNull(m);
text = ((TextMessage)m).getText();
if (!(text.equals(destination1String) || text.equals(destination2String) || text.equals(destination3String))) {
fail("unexpected message:" + text);
}
m = consumer.receive(1000);
assertNotNull(m);
if (!(text.equals(destination1String) || text.equals(destination2String) || text.equals(destination3String))) {
fail("unexpected message:" + text);
}
m = consumer.receive(1000);
assertNotNull(m);
if (!(text.equals(destination1String) || text.equals(destination2String) || text.equals(destination3String))) {
fail("unexpected message:" + text);
}
assertNull(consumer.receiveNoWait());
}
public void testReceiveWildcardQueueMidAsterisk() throws Exception {
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
ActiveMQDestination destination1 = (ActiveMQDestination)session.createQueue(destination1String);
ActiveMQDestination destination4 = (ActiveMQDestination)session.createQueue(destination4String);
Message m = null;
MessageConsumer consumer = null;
String text = null;
sendMessage(session, destination1, destination1String);
sendMessage(session, destination4, destination4String);
ActiveMQDestination destination8 = (ActiveMQDestination)session.createQueue("TEST.*.ONE");
consumer = session.createConsumer(destination8);
m = consumer.receive(1000);
assertNotNull(m);
text = ((TextMessage)m).getText();
if (!(text.equals(destination1String) || text.equals(destination4String))) {
fail("unexpected message:" + text);
}
m = consumer.receive(1000);
assertNotNull(m);
text = ((TextMessage)m).getText();
if (!(text.equals(destination1String) || text.equals(destination4String))) {
fail("unexpected message:" + text);
}
assertNull(consumer.receiveNoWait());
}
private void sendMessage(Session session, Destination destination, String text) throws JMSException {
MessageProducer producer = session.createProducer(destination);
producer.send(session.createTextMessage(text));
producer.close();
}
}

View File

@ -0,0 +1,562 @@
/**
* 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.util.concurrent.TimeUnit;
import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.apache.activemq.transport.vm.VMTransport;
import org.apache.activemq.util.Wait;
/**
*
*/
public class JmsRedeliveredTest extends TestCase {
private Connection connection;
/*
* (non-Javadoc)
*
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
connection = createConnection();
}
/**
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
if (connection != null) {
connection.close();
connection = null;
}
}
/**
* Creates a connection.
*
* @return connection
* @throws Exception
*/
protected Connection createConnection() throws Exception {
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(
"vm://localhost?broker.persistent=false");
return factory.createConnection();
}
/**
* Tests if a message unacknowledged message gets to be resent when the
* session is closed and then a new consumer session is created.
*
*/
public void testQueueSessionCloseMarksMessageRedelivered() throws JMSException {
connection.start();
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
Queue queue = session.createQueue("queue-" + getName());
MessageProducer producer = createProducer(session, queue);
producer.send(createTextMessage(session));
// Consume the message...
MessageConsumer consumer = session.createConsumer(queue);
Message msg = consumer.receive(1000);
assertNotNull(msg);
assertFalse("Message should not be redelivered.", msg.getJMSRedelivered());
// Don't ack the message.
// Reset the session. This should cause the Unacked message to be
// redelivered.
session.close();
session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
// Attempt to Consume the message...
consumer = session.createConsumer(queue);
msg = consumer.receive(2000);
assertNotNull(msg);
assertTrue("Message should be redelivered.", msg.getJMSRedelivered());
msg.acknowledge();
session.close();
}
public void testQueueSessionCloseMarksUnAckedMessageRedelivered() throws JMSException {
connection.start();
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
Queue queue = session.createQueue("queue-" + getName());
MessageProducer producer = createProducer(session, queue);
producer.send(createTextMessage(session, "1"));
producer.send(createTextMessage(session, "2"));
// Consume the message...
MessageConsumer consumer = session.createConsumer(queue);
Message msg = consumer.receive(1000);
assertNotNull(msg);
assertFalse("Message should not be redelivered.", msg.getJMSRedelivered());
assertEquals("1", ((TextMessage)msg).getText());
msg.acknowledge();
// Don't ack the message.
msg = consumer.receive(1000);
assertNotNull(msg);
assertFalse("Message should not be redelivered.", msg.getJMSRedelivered());
assertEquals("2", ((TextMessage)msg).getText());
// Reset the session. This should cause the Unacked message to be
// redelivered.
session.close();
session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
// Attempt to Consume the message...
consumer = session.createConsumer(queue);
msg = consumer.receive(2000);
assertNotNull(msg);
assertEquals("2", ((TextMessage)msg).getText());
assertTrue("Message should be redelivered.", msg.getJMSRedelivered());
msg.acknowledge();
session.close();
}
/**
* Tests session recovery and that the redelivered message is marked as
* such. Session uses client acknowledgement, the destination is a queue.
*
* @throws JMSException
*/
public void testQueueRecoverMarksMessageRedelivered() throws JMSException {
connection.start();
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
Queue queue = session.createQueue("queue-" + getName());
MessageProducer producer = createProducer(session, queue);
producer.send(createTextMessage(session));
// Consume the message...
MessageConsumer consumer = session.createConsumer(queue);
Message msg = consumer.receive(1000);
assertNotNull(msg);
assertFalse("Message should not be redelivered.", msg.getJMSRedelivered());
// Don't ack the message.
// Reset the session. This should cause the Unacked message to be
// redelivered.
session.recover();
// Attempt to Consume the message...
msg = consumer.receive(2000);
assertNotNull(msg);
assertTrue("Message should be redelivered.", msg.getJMSRedelivered());
msg.acknowledge();
session.close();
}
/**
* Tests rollback message to be marked as redelivered. Session uses client
* acknowledgement and the destination is a queue.
*
* @throws JMSException
*/
public void testQueueRollbackMarksMessageRedelivered() throws JMSException {
connection.start();
Session session = connection.createSession(true, Session.CLIENT_ACKNOWLEDGE);
Queue queue = session.createQueue("queue-" + getName());
MessageProducer producer = createProducer(session, queue);
producer.send(createTextMessage(session));
session.commit();
// Get the message... Should not be redelivered.
MessageConsumer consumer = session.createConsumer(queue);
Message msg = consumer.receive(1000);
assertNotNull(msg);
assertFalse("Message should not be redelivered.", msg.getJMSRedelivered());
// Rollback.. should cause redelivery.
session.rollback();
// Attempt to Consume the message...
msg = consumer.receive(2000);
assertNotNull(msg);
assertTrue("Message should be redelivered.", msg.getJMSRedelivered());
session.commit();
session.close();
}
/**
* Tests if the message gets to be re-delivered when the session closes and
* that the re-delivered message is marked as such. Session uses client
* acknowledgment, the destination is a topic and the consumer is a durable
* subscriber.
*
* @throws JMSException
*/
public void testDurableTopicSessionCloseMarksMessageRedelivered() throws JMSException {
connection.setClientID(getName());
connection.start();
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
Topic topic = session.createTopic("topic-" + getName());
MessageConsumer consumer = session.createDurableSubscriber(topic, "sub1");
// This case only works with persistent messages since transient
// messages
// are dropped when the consumer goes offline.
MessageProducer producer = session.createProducer(topic);
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
producer.send(createTextMessage(session));
// Consume the message...
Message msg = consumer.receive(1000);
assertNotNull(msg);
assertFalse("Message should not be re-delivered.", msg.getJMSRedelivered());
// Don't ack the message.
// Reset the session. This should cause the Unacked message to be
// re-delivered.
session.close();
session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
// Attempt to Consume the message...
consumer = session.createDurableSubscriber(topic, "sub1");
msg = consumer.receive(2000);
assertNotNull(msg);
assertTrue("Message should be redelivered.", msg.getJMSRedelivered());
msg.acknowledge();
session.close();
}
/**
* Tests session recovery and that the redelivered message is marked as
* such. Session uses client acknowledgement, the destination is a topic and
* the consumer is a durable suscriber.
*
* @throws JMSException
*/
public void testDurableTopicRecoverMarksMessageRedelivered() throws JMSException {
connection.setClientID(getName());
connection.start();
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
Topic topic = session.createTopic("topic-" + getName());
MessageConsumer consumer = session.createDurableSubscriber(topic, "sub1");
MessageProducer producer = createProducer(session, topic);
producer.send(createTextMessage(session));
// Consume the message...
Message msg = consumer.receive(1000);
assertNotNull(msg);
assertFalse("Message should not be redelivered.", msg.getJMSRedelivered());
// Don't ack the message.
// Reset the session. This should cause the Unacked message to be
// redelivered.
session.recover();
// Attempt to Consume the message...
msg = consumer.receive(2000);
assertNotNull(msg);
assertTrue("Message should be redelivered.", msg.getJMSRedelivered());
msg.acknowledge();
session.close();
}
/**
* Tests rollback message to be marked as redelivered. Session uses client
* acknowledgement and the destination is a topic.
*
* @throws JMSException
*/
public void testDurableTopicRollbackMarksMessageRedelivered() throws JMSException {
connection.setClientID(getName());
connection.start();
Session session = connection.createSession(true, Session.CLIENT_ACKNOWLEDGE);
Topic topic = session.createTopic("topic-" + getName());
MessageConsumer consumer = session.createDurableSubscriber(topic, "sub1");
MessageProducer producer = createProducer(session, topic);
producer.send(createTextMessage(session));
session.commit();
// Get the message... Should not be redelivered.
Message msg = consumer.receive(1000);
assertNotNull(msg);
assertFalse("Message should not be redelivered.", msg.getJMSRedelivered());
// Rollback.. should cause redelivery.
session.rollback();
// Attempt to Consume the message...
msg = consumer.receive(2000);
assertNotNull(msg);
assertTrue("Message should be redelivered.", msg.getJMSRedelivered());
session.commit();
session.close();
}
/**
*
*
* @throws JMSException
*/
public void testTopicRecoverMarksMessageRedelivered() throws JMSException {
connection.setClientID(getName());
connection.start();
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
Topic topic = session.createTopic("topic-" + getName());
MessageConsumer consumer = session.createConsumer(topic);
MessageProducer producer = createProducer(session, topic);
producer.send(createTextMessage(session));
// Consume the message...
Message msg = consumer.receive(1000);
assertNotNull(msg);
assertFalse("Message should not be redelivered.", msg.getJMSRedelivered());
// Don't ack the message.
// Reset the session. This should cause the Unacked message to be
// redelivered.
session.recover();
// Attempt to Consume the message...
msg = consumer.receive(2000);
assertNotNull(msg);
assertTrue("Message should be redelivered.", msg.getJMSRedelivered());
msg.acknowledge();
session.close();
}
/**
* Tests rollback message to be marked as redelivered. Session uses client
* acknowledgement and the destination is a topic.
*
* @throws JMSException
*/
public void testTopicRollbackMarksMessageRedelivered() throws JMSException {
connection.setClientID(getName());
connection.start();
Session session = connection.createSession(true, Session.CLIENT_ACKNOWLEDGE);
Topic topic = session.createTopic("topic-" + getName());
MessageConsumer consumer = session.createConsumer(topic);
MessageProducer producer = createProducer(session, topic);
producer.send(createTextMessage(session));
session.commit();
// Get the message... Should not be redelivered.
Message msg = consumer.receive(1000);
assertNotNull(msg);
assertFalse("Message should not be redelivered.", msg.getJMSRedelivered());
// Rollback.. should cause redelivery.
session.rollback();
// Attempt to Consume the message...
msg = consumer.receive(2000);
assertNotNull(msg);
assertTrue("Message should be redelivered.", msg.getJMSRedelivered());
session.commit();
session.close();
}
public void testNoReceiveConsumerDisconnectDoesNotIncrementRedelivery() throws Exception {
connection.setClientID(getName());
connection.start();
Connection keepBrokerAliveConnection = createConnection();
keepBrokerAliveConnection.start();
Session session = connection.createSession(true, Session.CLIENT_ACKNOWLEDGE);
Queue queue = session.createQueue("queue-" + getName());
final MessageConsumer consumer = session.createConsumer(queue);
MessageProducer producer = createProducer(session, queue);
producer.send(createTextMessage(session));
session.commit();
Wait.waitFor(new Wait.Condition() {
@Override
public boolean isSatisified() throws Exception {
return ((ActiveMQMessageConsumer)consumer).getMessageSize() == 1;
}
});
// whack the connection - like a rebalance or tcp drop
((ActiveMQConnection)connection).getTransport().narrow(VMTransport.class).stop();
session = keepBrokerAliveConnection.createSession(true, Session.CLIENT_ACKNOWLEDGE);
MessageConsumer messageConsumer = session.createConsumer(queue);
Message msg = messageConsumer.receive(1000);
assertNotNull(msg);
msg.acknowledge();
assertFalse("Message should not be redelivered.", msg.getJMSRedelivered());
session.close();
keepBrokerAliveConnection.close();
}
public void testNoReceiveConsumerDoesNotIncrementRedelivery() throws Exception {
connection.setClientID(getName());
connection.start();
Session session = connection.createSession(true, Session.CLIENT_ACKNOWLEDGE);
Queue queue = session.createQueue("queue-" + getName());
MessageConsumer consumer = session.createConsumer(queue);
MessageProducer producer = createProducer(session, queue);
producer.send(createTextMessage(session));
session.commit();
TimeUnit.SECONDS.sleep(1);
consumer.close();
consumer = session.createConsumer(queue);
Message msg = consumer.receive(1000);
assertNotNull(msg);
assertFalse("Message should not be redelivered.", msg.getJMSRedelivered());
session.close();
}
public void testNoReceiveDurableConsumerDoesNotIncrementRedelivery() throws Exception {
connection.setClientID(getName());
connection.start();
Session session = connection.createSession(true, Session.CLIENT_ACKNOWLEDGE);
Topic topic = session.createTopic("topic-" + getName());
MessageConsumer consumer = session.createDurableSubscriber(topic, "sub");
MessageProducer producer = createProducer(session, topic);
producer.send(createTextMessage(session));
session.commit();
TimeUnit.SECONDS.sleep(1);
consumer.close();
consumer = session.createDurableSubscriber(topic, "sub");
Message msg = consumer.receive(1000);
assertNotNull(msg);
assertFalse("Message should not be redelivered.", msg.getJMSRedelivered());
session.close();
}
/**
* Creates a text message.
*
* @param session
* @return TextMessage.
* @throws JMSException
*/
private TextMessage createTextMessage(Session session) throws JMSException {
return createTextMessage(session, "Hello");
}
private TextMessage createTextMessage(Session session, String txt) throws JMSException {
return session.createTextMessage(txt);
}
/**
* Creates a producer.
*
* @param session
* @param queue - destination.
* @return MessageProducer
* @throws JMSException
*/
private MessageProducer createProducer(Session session, Destination queue) throws JMSException {
MessageProducer producer = session.createProducer(queue);
producer.setDeliveryMode(getDeliveryMode());
return producer;
}
/**
* Returns delivery mode.
*
* @return int - persistent delivery mode.
*/
protected int getDeliveryMode() {
return DeliveryMode.PERSISTENT;
}
/**
* Run the JmsRedeliverTest with the delivery mode set as persistent.
*/
public static final class PersistentCase extends JmsRedeliveredTest {
/**
* Returns delivery mode.
*
* @return int - persistent delivery mode.
*/
protected int getDeliveryMode() {
return DeliveryMode.PERSISTENT;
}
}
/**
* Run the JmsRedeliverTest with the delivery mode set as non-persistent.
*/
public static final class TransientCase extends JmsRedeliveredTest {
/**
* Returns delivery mode.
*
* @return int - non-persistent delivery mode.
*/
protected int getDeliveryMode() {
return DeliveryMode.NON_PERSISTENT;
}
}
public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTestSuite(PersistentCase.class);
suite.addTestSuite(TransientCase.class);
return suite;
}
}

View File

@ -0,0 +1,358 @@
/**
* 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.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.broker.BrokerService;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.Rule;
import org.junit.rules.TestName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.junit.Assert.*;
public class JmsRollbackRedeliveryTest {
@Rule
public TestName testName = new TestName();
protected static final Logger LOG = LoggerFactory.getLogger(JmsRollbackRedeliveryTest.class);
final int nbMessages = 10;
final String destinationName = "Destination";
final String brokerUrl = "vm://localhost?create=false";
boolean consumerClose = true;
boolean rollback = true;
BrokerService broker;
@Before
public void setUp() throws Exception {
LOG.debug("Starting " + testName.getMethodName());
broker = new BrokerService();
broker.setPersistent(false);
broker.setUseJmx(false);
broker.start();
broker.waitUntilStarted();
}
@After
public void tearDown() throws Exception {
if (broker != null) {
broker.stop();
broker.waitUntilStopped();
}
LOG.debug("Finishing " + testName.getMethodName());
Thread.sleep(100);
}
@Test
public void testRedelivery() throws Exception {
doTestRedelivery(brokerUrl, false);
}
@Test
public void testRedeliveryWithInterleavedProducer() throws Exception {
doTestRedelivery(brokerUrl, true);
}
@Test
public void testRedeliveryWithPrefetch0() throws Exception {
doTestRedelivery(brokerUrl + "?jms.prefetchPolicy.queuePrefetch=0", true);
}
@Test
public void testRedeliveryWithPrefetch1() throws Exception {
doTestRedelivery(brokerUrl + "?jms.prefetchPolicy.queuePrefetch=1", true);
}
public void doTestRedelivery(String brokerUrl, boolean interleaveProducer) throws Exception {
LOG.debug("entering doTestRedelivery interleaveProducer is " + interleaveProducer);
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerUrl);
Connection connection = connectionFactory.createConnection();
connection.start();
if (interleaveProducer) {
populateDestinationWithInterleavedProducer(nbMessages, destinationName, connection);
} else {
populateDestination(nbMessages, destinationName, connection);
}
// Consume messages and rollback transactions
{
AtomicInteger received = new AtomicInteger();
Map<String, Boolean> rolledback = new ConcurrentHashMap<String, Boolean>();
while (received.get() < nbMessages) {
Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue(destinationName);
MessageConsumer consumer = session.createConsumer(destination);
TextMessage msg = (TextMessage) consumer.receive(6000000);
if (msg != null) {
if (msg != null && rolledback.put(msg.getText(), Boolean.TRUE) != null) {
LOG.info("Received message " + msg.getText() + " (" + received.getAndIncrement() + ")" + msg.getJMSMessageID());
assertTrue(msg.getJMSRedelivered());
assertEquals(2, msg.getLongProperty("JMSXDeliveryCount"));
session.commit();
} else {
LOG.info("Rollback message " + msg.getText() + " id: " + msg.getJMSMessageID());
assertFalse("should not have redelivery flag set, id: " + msg.getJMSMessageID(), msg.getJMSRedelivered());
session.rollback();
}
}
consumer.close();
session.close();
}
}
}
@Test
public void testRedeliveryOnSingleConsumer() throws Exception {
ConnectionFactory connectionFactory =
new ActiveMQConnectionFactory(brokerUrl);
Connection connection = connectionFactory.createConnection();
connection.start();
populateDestinationWithInterleavedProducer(nbMessages, destinationName, connection);
// Consume messages and rollback transactions
{
AtomicInteger received = new AtomicInteger();
Map<String, Boolean> rolledback = new ConcurrentHashMap<String, Boolean>();
Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue(destinationName);
MessageConsumer consumer = session.createConsumer(destination);
while (received.get() < nbMessages) {
TextMessage msg = (TextMessage) consumer.receive(6000000);
if (msg != null) {
if (msg != null && rolledback.put(msg.getText(), Boolean.TRUE) != null) {
LOG.info("Received message " + msg.getText() + " (" + received.getAndIncrement() + ")" + msg.getJMSMessageID());
assertTrue(msg.getJMSRedelivered());
session.commit();
} else {
LOG.info("Rollback message " + msg.getText() + " id: " + msg.getJMSMessageID());
session.rollback();
}
}
}
consumer.close();
session.close();
}
}
@Test
public void testRedeliveryOnSingleSession() throws Exception {
ConnectionFactory connectionFactory =
new ActiveMQConnectionFactory(brokerUrl);
Connection connection = connectionFactory.createConnection();
connection.start();
populateDestination(nbMessages, destinationName, connection);
// Consume messages and rollback transactions
{
AtomicInteger received = new AtomicInteger();
Map<String, Boolean> rolledback = new ConcurrentHashMap<String, Boolean>();
Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue(destinationName);
while (received.get() < nbMessages) {
MessageConsumer consumer = session.createConsumer(destination);
TextMessage msg = (TextMessage) consumer.receive(6000000);
if (msg != null) {
if (msg != null && rolledback.put(msg.getText(), Boolean.TRUE) != null) {
LOG.info("Received message " + msg.getText() + " (" + received.getAndIncrement() + ")" + msg.getJMSMessageID());
assertTrue(msg.getJMSRedelivered());
session.commit();
} else {
LOG.info("Rollback message " + msg.getText() + " id: " + msg.getJMSMessageID());
session.rollback();
}
}
consumer.close();
}
session.close();
}
}
// AMQ-1593
@Test
public void testValidateRedeliveryCountOnRollback() throws Exception {
final int numMessages = 1;
ConnectionFactory connectionFactory =
new ActiveMQConnectionFactory(brokerUrl);
Connection connection = connectionFactory.createConnection();
connection.start();
populateDestination(numMessages, destinationName, connection);
{
AtomicInteger received = new AtomicInteger();
final int maxRetries = new RedeliveryPolicy().getMaximumRedeliveries();
while (received.get() < maxRetries) {
Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
Destination destination = session.createQueue(destinationName);
MessageConsumer consumer = session.createConsumer(destination);
TextMessage msg = (TextMessage) consumer.receive(1000);
if (msg != null) {
LOG.info("Received message " + msg.getText() + " (" + received.getAndIncrement() + ")" + msg.getJMSMessageID());
assertEquals("redelivery property matches deliveries", received.get(), msg.getLongProperty("JMSXDeliveryCount"));
session.rollback();
}
session.close();
}
consumeMessage(connection, maxRetries + 1);
}
}
// AMQ-1593
@Test
public void testValidateRedeliveryCountOnRollbackWithPrefetch0() throws Exception {
final int numMessages = 1;
ConnectionFactory connectionFactory =
new ActiveMQConnectionFactory(brokerUrl + "?jms.prefetchPolicy.queuePrefetch=0");
Connection connection = connectionFactory.createConnection();
connection.start();
populateDestination(numMessages, destinationName, connection);
{
AtomicInteger received = new AtomicInteger();
final int maxRetries = new RedeliveryPolicy().getMaximumRedeliveries();
while (received.get() < maxRetries) {
Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
Destination destination = session.createQueue(destinationName);
MessageConsumer consumer = session.createConsumer(destination);
TextMessage msg = (TextMessage) consumer.receive(1000);
if (msg != null) {
LOG.info("Received message " + msg.getText() + " (" + received.getAndIncrement() + ")" + msg.getJMSMessageID());
assertEquals("redelivery property matches deliveries", received.get(), msg.getLongProperty("JMSXDeliveryCount"));
session.rollback();
}
session.close();
}
consumeMessage(connection, maxRetries + 1);
}
}
private void consumeMessage(Connection connection, final int deliveryCount)
throws JMSException {
Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
Destination destination = session.createQueue(destinationName);
MessageConsumer consumer = session.createConsumer(destination);
TextMessage msg = (TextMessage) consumer.receive(1000);
assertNotNull(msg);
assertEquals("redelivery property matches deliveries", deliveryCount, msg.getLongProperty("JMSXDeliveryCount"));
session.commit();
session.close();
}
@Test
public void testRedeliveryPropertyWithNoRollback() throws Exception {
final int numMessages = 1;
ConnectionFactory connectionFactory =
new ActiveMQConnectionFactory(brokerUrl);
Connection connection = connectionFactory.createConnection();
connection.start();
populateDestination(numMessages, destinationName, connection);
connection.close();
{
AtomicInteger received = new AtomicInteger();
final int maxRetries = new RedeliveryPolicy().getMaximumRedeliveries();
while (received.get() < maxRetries) {
connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
Destination destination = session.createQueue(destinationName);
MessageConsumer consumer = session.createConsumer(destination);
TextMessage msg = (TextMessage) consumer.receive(2000);
if (msg != null) {
LOG.info("Received message " + msg.getText() + " (" + received.getAndIncrement() + ")" + msg.getJMSMessageID());
assertEquals("redelivery property matches deliveries", received.get(), msg.getLongProperty("JMSXDeliveryCount"));
}
session.close();
connection.close();
}
connection = connectionFactory.createConnection();
connection.start();
consumeMessage(connection, maxRetries + 1);
}
}
private void populateDestination(final int nbMessages,
final String destinationName, Connection connection)
throws JMSException {
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue(destinationName);
MessageProducer producer = session.createProducer(destination);
for (int i = 1; i <= nbMessages; i++) {
producer.send(session.createTextMessage("<hello id='" + i + "'/>"));
}
producer.close();
session.close();
}
private void populateDestinationWithInterleavedProducer(final int nbMessages,
final String destinationName, Connection connection)
throws JMSException {
Session session1 = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination1 = session1.createQueue(destinationName);
MessageProducer producer1 = session1.createProducer(destination1);
Session session2 = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination2 = session2.createQueue(destinationName);
MessageProducer producer2 = session2.createProducer(destination2);
for (int i = 1; i <= nbMessages; i++) {
if (i%2 == 0) {
producer1.send(session1.createTextMessage("<hello id='" + i + "'/>"));
} else {
producer2.send(session2.createTextMessage("<hello id='" + i + "'/>"));
}
}
producer1.close();
session1.close();
producer2.close();
session2.close();
}
}

View File

@ -0,0 +1,237 @@
/**
* 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.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
*/
public class JmsSendReceiveTestSupport extends TestSupport implements MessageListener {
private static final Logger LOG = LoggerFactory.getLogger(JmsSendReceiveTestSupport.class);
protected int messageCount = 100;
protected String[] data;
protected Session session;
protected MessageConsumer consumer;
protected MessageProducer producer;
protected Destination consumerDestination;
protected Destination producerDestination;
protected List<Message> messages = createConcurrentList();
protected boolean topic = true;
protected boolean durable;
protected int deliveryMode = DeliveryMode.PERSISTENT;
protected final Object lock = new Object();
protected boolean verbose;
/*
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
super.setUp();
String temp = System.getProperty("messageCount");
if (temp != null) {
int i = Integer.parseInt(temp);
if (i > 0) {
messageCount = i;
}
}
LOG.info("Message count for test case is: " + messageCount);
data = new String[messageCount];
for (int i = 0; i < messageCount; i++) {
data[i] = "Text for message: " + i + " at " + new Date();
}
}
/**
* Sends and consumes the messages.
*
* @throws Exception
*/
public void testSendReceive() throws Exception {
messages.clear();
for (int i = 0; i < data.length; i++) {
Message message = session.createTextMessage(data[i]);
message.setStringProperty("stringProperty", data[i]);
message.setIntProperty("intProperty", i);
if (verbose) {
if (LOG.isDebugEnabled()) {
LOG.debug("About to send a message: " + message + " with text: " + data[i]);
}
}
sendToProducer(producer, producerDestination, message);
messageSent();
}
assertMessagesAreReceived();
LOG.info("" + data.length + " messages(s) received, closing down connections");
}
/**
* Sends a message to a destination using the supplied producer
* @param producer
* @param producerDestination
* @param message
* @throws JMSException
*/
protected void sendToProducer(MessageProducer producer,
Destination producerDestination, Message message) throws JMSException {
producer.send(producerDestination, message);
}
/**
* Asserts messages are received.
*
* @throws JMSException
*/
protected void assertMessagesAreReceived() throws JMSException {
waitForMessagesToBeDelivered();
assertMessagesReceivedAreValid(messages);
}
/**
* Tests if the messages received are valid.
*
* @param receivedMessages - list of received messages.
* @throws JMSException
*/
protected void assertMessagesReceivedAreValid(List<Message> receivedMessages) throws JMSException {
List<Object> copyOfMessages = Arrays.asList(receivedMessages.toArray());
int counter = 0;
if (data.length != copyOfMessages.size()) {
for (Iterator<Object> iter = copyOfMessages.iterator(); iter.hasNext();) {
TextMessage message = (TextMessage)iter.next();
if (LOG.isInfoEnabled()) {
LOG.info("<== " + counter++ + " = " + message.getText());
}
}
}
assertEquals("Not enough messages received", data.length, receivedMessages.size());
for (int i = 0; i < data.length; i++) {
TextMessage received = (TextMessage)receivedMessages.get(i);
String text = received.getText();
String stringProperty = received.getStringProperty("stringProperty");
int intProperty = received.getIntProperty("intProperty");
if (verbose) {
if (LOG.isDebugEnabled()) {
LOG.info("Received Text: " + text);
}
}
assertEquals("Message: " + i, data[i], text);
assertEquals(data[i], stringProperty);
assertEquals(i, intProperty);
}
}
/**
* Waits for messages to be delivered.
*/
protected void waitForMessagesToBeDelivered() {
long maxWaitTime = 60000;
long waitTime = maxWaitTime;
long start = (maxWaitTime <= 0) ? 0 : System.currentTimeMillis();
synchronized (lock) {
while (messages.size() < data.length && waitTime >= 0) {
try {
lock.wait(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
waitTime = maxWaitTime - (System.currentTimeMillis() - start);
}
}
}
/*
* (non-Javadoc)
*
* @see javax.jms.MessageListener#onMessage(javax.jms.Message)
*/
public synchronized void onMessage(Message message) {
consumeMessage(message, messages);
}
/**
* Consumes messages.
*
* @param message - message to be consumed.
* @param messageList -list of consumed messages.
*/
protected void consumeMessage(Message message, List<Message> messageList) {
if (verbose) {
if (LOG.isDebugEnabled()) {
LOG.info("Received message: " + message);
}
}
messageList.add(message);
if (messageList.size() >= data.length) {
synchronized (lock) {
lock.notifyAll();
}
}
}
/**
* Returns the ArrayList as a synchronized list.
*
* @return List
*/
protected List<Message> createConcurrentList() {
return Collections.synchronizedList(new ArrayList<Message>());
}
/**
* Just a hook so can insert failure tests
*
* @throws Exception
*/
protected void messageSent() throws Exception {
}
}

View File

@ -0,0 +1,310 @@
/**
* 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.util.Date;
import java.util.Vector;
import java.util.concurrent.TimeUnit;
import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.Topic;
import org.apache.activemq.broker.BrokerRegistry;
import org.apache.activemq.broker.region.DestinationStatistics;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.util.Wait;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
*/
public class JmsSendReceiveWithMessageExpirationTest extends TestSupport {
private static final Logger LOG = LoggerFactory.getLogger(JmsSendReceiveWithMessageExpirationTest.class);
protected int messageCount = 100;
protected String[] data;
protected Session session;
protected Destination consumerDestination;
protected Destination producerDestination;
protected boolean durable;
protected int deliveryMode = DeliveryMode.PERSISTENT;
protected long timeToLive = 5000;
protected boolean verbose;
protected Connection connection;
protected void setUp() throws Exception {
super.setUp();
data = new String[messageCount];
for (int i = 0; i < messageCount; i++) {
data[i] = "Text for message: " + i + " at " + new Date();
}
connectionFactory = createConnectionFactory();
connection = createConnection();
if (durable) {
connection.setClientID(getClass().getName());
}
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
}
/**
* Test consuming an expired queue.
*
* @throws Exception
*/
public void testConsumeExpiredQueue() throws Exception {
MessageProducer producer = createProducer(timeToLive);
consumerDestination = session.createQueue(getConsumerSubject());
producerDestination = session.createQueue(getProducerSubject());
MessageConsumer consumer = createConsumer();
connection.start();
for (int i = 0; i < data.length; i++) {
Message message = session.createTextMessage(data[i]);
message.setStringProperty("stringProperty", data[i]);
message.setIntProperty("intProperty", i);
if (verbose) {
if (LOG.isDebugEnabled()) {
LOG.debug("About to send a queue message: " + message + " with text: " + data[i]);
}
}
producer.send(producerDestination, message);
}
// sleeps a second longer than the expiration time.
// Basically waits till queue expires.
Thread.sleep(timeToLive + 1000);
// message should have expired.
assertNull(consumer.receive(1000));
}
public void testConsumeExpiredQueueAndDlq() throws Exception {
MessageProducer producerNormal = createProducer(0);
MessageProducer producerExpire = createProducer(500);
consumerDestination = session.createQueue("ActiveMQ.DLQ");
MessageConsumer dlqConsumer = createConsumer();
consumerDestination = session.createQueue(getConsumerSubject());
producerDestination = session.createQueue(getProducerSubject());
Connection consumerConnection = createConnection();
ActiveMQPrefetchPolicy prefetchPolicy = new ActiveMQPrefetchPolicy();
prefetchPolicy.setAll(10);
((ActiveMQConnection)consumerConnection).setPrefetchPolicy(prefetchPolicy);
Session consumerSession = consumerConnection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
MessageConsumer consumer = consumerSession.createConsumer(consumerDestination);
consumerConnection.start();
connection.start();
String msgBody = new String(new byte[20*1024]);
for (int i = 0; i < data.length; i++) {
Message message = session.createTextMessage(msgBody);
producerExpire.send(producerDestination, message);
}
for (int i = 0; i < data.length; i++) {
Message message = session.createTextMessage(msgBody);
producerNormal.send(producerDestination, message);
}
Vector<Message> messages = new Vector<Message>();
Message received;
while ((received = consumer.receive(1000)) != null) {
messages.add(received);
if (messages.size() == 1) {
TimeUnit.SECONDS.sleep(1);
}
received.acknowledge();
};
assertEquals("got all (normal plus one with ttl) messages", messageCount + 1, messages.size());
Vector<Message> dlqMessages = new Vector<Message>();
while ((received = dlqConsumer.receive(1000)) != null) {
dlqMessages.add(received);
};
assertEquals("got dlq messages", data.length - 1, dlqMessages.size());
final DestinationStatistics view = getDestinationStatistics(BrokerRegistry.getInstance().findFirst(), ActiveMQDestination.transform(consumerDestination));
// wait for all to inflight to expire
assertTrue("all inflight messages expired ", Wait.waitFor(new Wait.Condition() {
@Override
public boolean isSatisified() throws Exception {
return view.getInflight().getCount() == 0;
}
}));
assertEquals("Wrong inFlightCount: ", 0, view.getInflight().getCount());
LOG.info("Stats: received: " + messages.size() + ", messages: " + view.getMessages().getCount() + ", enqueues: " + view.getEnqueues().getCount() + ", dequeues: " + view.getDequeues().getCount()
+ ", dispatched: " + view.getDispatched().getCount() + ", inflight: " + view.getInflight().getCount() + ", expired: " + view.getExpired().getCount());
}
/**
* Sends and consumes the messages to a queue destination.
*
* @throws Exception
*/
public void testConsumeQueue() throws Exception {
MessageProducer producer = createProducer(0);
consumerDestination = session.createQueue(getConsumerSubject());
producerDestination = session.createQueue(getProducerSubject());
MessageConsumer consumer = createConsumer();
connection.start();
for (int i = 0; i < data.length; i++) {
Message message = session.createTextMessage(data[i]);
message.setStringProperty("stringProperty", data[i]);
message.setIntProperty("intProperty", i);
if (verbose) {
if (LOG.isDebugEnabled()) {
LOG.debug("About to send a queue message: " + message + " with text: " + data[i]);
}
}
producer.send(producerDestination, message);
}
// should receive a queue since there is no expiration.
assertNotNull(consumer.receive(1000));
}
/**
* Test consuming an expired topic.
*
* @throws Exception
*/
public void testConsumeExpiredTopic() throws Exception {
MessageProducer producer = createProducer(timeToLive);
consumerDestination = session.createTopic(getConsumerSubject());
producerDestination = session.createTopic(getProducerSubject());
MessageConsumer consumer = createConsumer();
connection.start();
for (int i = 0; i < data.length; i++) {
Message message = session.createTextMessage(data[i]);
message.setStringProperty("stringProperty", data[i]);
message.setIntProperty("intProperty", i);
if (verbose) {
if (LOG.isDebugEnabled()) {
LOG.debug("About to send a topic message: " + message + " with text: " + data[i]);
}
}
producer.send(producerDestination, message);
}
// sleeps a second longer than the expiration time.
// Basically waits till topic expires.
Thread.sleep(timeToLive + 1000);
// message should have expired.
assertNull(consumer.receive(1000));
}
/**
* Sends and consumes the messages to a topic destination.
*
* @throws Exception
*/
public void testConsumeTopic() throws Exception {
MessageProducer producer = createProducer(0);
consumerDestination = session.createTopic(getConsumerSubject());
producerDestination = session.createTopic(getProducerSubject());
MessageConsumer consumer = createConsumer();
connection.start();
for (int i = 0; i < data.length; i++) {
Message message = session.createTextMessage(data[i]);
message.setStringProperty("stringProperty", data[i]);
message.setIntProperty("intProperty", i);
if (verbose) {
if (LOG.isDebugEnabled()) {
LOG.debug("About to send a topic message: " + message + " with text: " + data[i]);
}
}
producer.send(producerDestination, message);
}
// should receive a topic since there is no expiration.
assertNotNull(consumer.receive(1000));
}
protected MessageProducer createProducer(long timeToLive) throws JMSException {
MessageProducer producer = session.createProducer(null);
producer.setDeliveryMode(deliveryMode);
producer.setTimeToLive(timeToLive);
return producer;
}
protected MessageConsumer createConsumer() throws JMSException {
if (durable) {
LOG.info("Creating durable consumer");
return session.createDurableSubscriber((Topic)consumerDestination, getName());
}
return session.createConsumer(consumerDestination);
}
protected void tearDown() throws Exception {
LOG.info("Dumping stats...");
LOG.info("Closing down connection");
session.close();
connection.close();
}
}

View File

@ -0,0 +1,127 @@
/**
* 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.util.concurrent.CountDownLatch;
import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Queue;
import javax.jms.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
*/
public class JmsSendWithAsyncCallbackTest extends TestSupport {
private static final Logger LOG = LoggerFactory.getLogger(JmsSendWithAsyncCallbackTest.class);
private Connection connection;
@Override
protected void setUp() throws Exception {
super.setUp();
connection = createConnection();
}
/**
* @see junit.framework.TestCase#tearDown()
*/
@Override
protected void tearDown() throws Exception {
if (connection != null) {
connection.close();
connection = null;
}
super.tearDown();
}
public void testAsyncCallbackIsFaster() throws JMSException, InterruptedException {
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue(getName());
// setup a consumer to drain messages..
MessageConsumer consumer = session.createConsumer(queue);
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
}
});
// warmup...
for (int i = 0; i < 10; i++) {
benchmarkNonCallbackRate();
benchmarkCallbackRate();
}
double callbackRate = benchmarkCallbackRate();
double nonCallbackRate = benchmarkNonCallbackRate();
LOG.info(String.format("AsyncCallback Send rate: %,.2f m/s", callbackRate));
LOG.info(String.format("NonAsyncCallback Send rate: %,.2f m/s", nonCallbackRate));
// The async style HAS to be faster than the non-async style..
assertTrue("async rate[" + callbackRate + "] should beat non-async rate[" + nonCallbackRate + "]", callbackRate / nonCallbackRate > 1.5);
}
private double benchmarkNonCallbackRate() throws JMSException {
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue(getName());
int count = 1000;
ActiveMQMessageProducer producer = (ActiveMQMessageProducer) session.createProducer(queue);
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
long start = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
producer.send(session.createTextMessage("Hello"));
}
return 1000.0 * count / (System.currentTimeMillis() - start);
}
private double benchmarkCallbackRate() throws JMSException, InterruptedException {
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue(getName());
int count = 1000;
final CountDownLatch messagesSent = new CountDownLatch(count);
ActiveMQMessageProducer producer = (ActiveMQMessageProducer) session.createProducer(queue);
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
long start = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
producer.send(session.createTextMessage("Hello"), new AsyncCallback() {
@Override
public void onSuccess() {
messagesSent.countDown();
}
@Override
public void onException(JMSException exception) {
exception.printStackTrace();
}
});
}
messagesSent.await();
return 1000.0 * count / (System.currentTimeMillis() - start);
}
}

View File

@ -0,0 +1,294 @@
/**
* 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.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import junit.framework.TestCase;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
/**
* Testcases to see if Session.recover() work.
*
*
*/
public class JmsSessionRecoverTest extends TestCase {
private Connection connection;
private ActiveMQConnectionFactory factory;
private Destination dest;
/**
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
factory = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false");
connection = factory.createConnection();
}
/**
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
if (connection != null) {
connection.close();
connection = null;
}
}
/**
*
* @throws JMSException
* @throws InterruptedException
*/
public void testQueueSynchRecover() throws JMSException, InterruptedException {
dest = new ActiveMQQueue("Queue-" + System.currentTimeMillis());
doTestSynchRecover();
}
/**
*
* @throws JMSException
* @throws InterruptedException
*/
public void testQueueAsynchRecover() throws JMSException, InterruptedException {
dest = new ActiveMQQueue("Queue-" + System.currentTimeMillis());
doTestAsynchRecover();
}
/**
*
* @throws JMSException
* @throws InterruptedException
*/
public void testTopicSynchRecover() throws JMSException, InterruptedException {
dest = new ActiveMQTopic("Topic-" + System.currentTimeMillis());
doTestSynchRecover();
}
/**
*
* @throws JMSException
* @throws InterruptedException
*/
public void testTopicAsynchRecover() throws JMSException, InterruptedException {
dest = new ActiveMQTopic("Topic-" + System.currentTimeMillis());
doTestAsynchRecover();
}
/**
*
* @throws JMSException
* @throws InterruptedException
*/
public void testQueueAsynchRecoverWithAutoAck() throws JMSException, InterruptedException {
dest = new ActiveMQQueue("Queue-" + System.currentTimeMillis());
doTestAsynchRecoverWithAutoAck();
}
/**
*
* @throws JMSException
* @throws InterruptedException
*/
public void testTopicAsynchRecoverWithAutoAck() throws JMSException, InterruptedException {
dest = new ActiveMQTopic("Topic-" + System.currentTimeMillis());
doTestAsynchRecoverWithAutoAck();
}
/**
* Test to make sure that a Sync recover works.
*
* @throws JMSException
*/
public void doTestSynchRecover() throws JMSException {
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
MessageConsumer consumer = session.createConsumer(dest);
connection.start();
MessageProducer producer = session.createProducer(dest);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
producer.send(session.createTextMessage("First"));
producer.send(session.createTextMessage("Second"));
TextMessage message = (TextMessage)consumer.receive(1000);
assertEquals("First", message.getText());
assertFalse(message.getJMSRedelivered());
message.acknowledge();
message = (TextMessage)consumer.receive(1000);
assertEquals("Second", message.getText());
assertFalse(message.getJMSRedelivered());
session.recover();
message = (TextMessage)consumer.receive(2000);
assertEquals("Second", message.getText());
assertTrue(message.getJMSRedelivered());
message.acknowledge();
}
/**
* Test to make sure that a Async recover works.
*
* @throws JMSException
* @throws InterruptedException
*/
public void doTestAsynchRecover() throws JMSException, InterruptedException {
final Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
final String errorMessage[] = new String[] {null};
final CountDownLatch doneCountDownLatch = new CountDownLatch(1);
MessageConsumer consumer = session.createConsumer(dest);
MessageProducer producer = session.createProducer(dest);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
producer.send(session.createTextMessage("First"));
producer.send(session.createTextMessage("Second"));
consumer.setMessageListener(new MessageListener() {
int counter;
public void onMessage(Message msg) {
counter++;
try {
TextMessage message = (TextMessage)msg;
switch (counter) {
case 1:
assertEquals("First", message.getText());
assertFalse(message.getJMSRedelivered());
message.acknowledge();
break;
case 2:
assertEquals("Second", message.getText());
assertFalse(message.getJMSRedelivered());
session.recover();
break;
case 3:
assertEquals("Second", message.getText());
assertTrue(message.getJMSRedelivered());
message.acknowledge();
doneCountDownLatch.countDown();
break;
default:
errorMessage[0] = "Got too many messages: " + counter;
doneCountDownLatch.countDown();
}
} catch (Throwable e) {
e.printStackTrace();
errorMessage[0] = "Got exception: " + e;
doneCountDownLatch.countDown();
}
}
});
connection.start();
if (doneCountDownLatch.await(5, TimeUnit.SECONDS)) {
if (errorMessage[0] != null) {
fail(errorMessage[0]);
}
} else {
fail("Timeout waiting for async message delivery to complete.");
}
}
/**
* Test to make sure that a Async recover works when using AUTO_ACKNOWLEDGE.
*
* @throws JMSException
* @throws InterruptedException
*/
public void doTestAsynchRecoverWithAutoAck() throws JMSException, InterruptedException {
final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
final String errorMessage[] = new String[] {null};
final CountDownLatch doneCountDownLatch = new CountDownLatch(1);
MessageConsumer consumer = session.createConsumer(dest);
MessageProducer producer = session.createProducer(dest);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
producer.send(session.createTextMessage("First"));
producer.send(session.createTextMessage("Second"));
consumer.setMessageListener(new MessageListener() {
int counter;
public void onMessage(Message msg) {
counter++;
try {
TextMessage message = (TextMessage)msg;
switch (counter) {
case 1:
assertEquals("First", message.getText());
assertFalse(message.getJMSRedelivered());
break;
case 2:
// This should rollback the delivery of this message..
// and re-deliver.
assertEquals("Second", message.getText());
assertFalse(message.getJMSRedelivered());
session.recover();
break;
case 3:
assertEquals("Second", message.getText());
assertTrue(message.getJMSRedelivered());
doneCountDownLatch.countDown();
break;
default:
errorMessage[0] = "Got too many messages: " + counter;
doneCountDownLatch.countDown();
}
} catch (Throwable e) {
e.printStackTrace();
errorMessage[0] = "Got exception: " + e;
doneCountDownLatch.countDown();
}
}
});
connection.start();
if (doneCountDownLatch.await(5000, TimeUnit.SECONDS)) {
if (errorMessage[0] != null) {
fail(errorMessage[0]);
}
} else {
fail("Timeout waiting for async message delivery to complete.");
}
}
}

View File

@ -0,0 +1,377 @@
/**
* 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.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.jms.BytesMessage;
import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.InvalidDestinationException;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TemporaryQueue;
import javax.jms.TextMessage;
import junit.framework.TestCase;
import org.apache.activemq.transport.TransportListener;
import org.apache.activemq.transport.vm.VMTransport;
import org.apache.activemq.util.Wait;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @version
*/
public class JmsTempDestinationTest extends TestCase {
private static final Logger LOG = LoggerFactory.getLogger(JmsTempDestinationTest.class);
private Connection connection;
private ActiveMQConnectionFactory factory;
protected List<Connection> connections = Collections.synchronizedList(new ArrayList<Connection>());
@Override
protected void setUp() throws Exception {
factory = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false");
factory.setAlwaysSyncSend(true);
connection = factory.createConnection();
connections.add(connection);
}
/**
* @see junit.framework.TestCase#tearDown()
*/
@Override
protected void tearDown() throws Exception {
for (Iterator<Connection> iter = connections.iterator(); iter.hasNext();) {
Connection conn = iter.next();
try {
conn.close();
} catch (Throwable e) {
}
iter.remove();
}
}
/**
* Make sure Temp destination can only be consumed by local connection
*
* @throws JMSException
*/
public void testTempDestOnlyConsumedByLocalConn() throws JMSException {
connection.start();
Session tempSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
TemporaryQueue queue = tempSession.createTemporaryQueue();
MessageProducer producer = tempSession.createProducer(queue);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
TextMessage message = tempSession.createTextMessage("First");
producer.send(message);
// temp destination should not be consume when using another connection
Connection otherConnection = factory.createConnection();
connections.add(otherConnection);
Session otherSession = otherConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
TemporaryQueue otherQueue = otherSession.createTemporaryQueue();
MessageConsumer consumer = otherSession.createConsumer(otherQueue);
Message msg = consumer.receive(3000);
assertNull(msg);
// should throw InvalidDestinationException when consuming a temp
// destination from another connection
try {
consumer = otherSession.createConsumer(queue);
fail("Send should fail since temp destination should be used from another connection");
} catch (InvalidDestinationException e) {
assertTrue("failed to throw an exception", true);
}
// should be able to consume temp destination from the same connection
consumer = tempSession.createConsumer(queue);
msg = consumer.receive(3000);
assertNotNull(msg);
}
/**
* Make sure that a temp queue does not drop message if there is an active
* consumers.
*
* @throws JMSException
*/
public void testTempQueueHoldsMessagesWithConsumers() throws JMSException {
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createTemporaryQueue();
MessageConsumer consumer = session.createConsumer(queue);
connection.start();
MessageProducer producer = session.createProducer(queue);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
TextMessage message = session.createTextMessage("Hello");
producer.send(message);
Message message2 = consumer.receive(1000);
assertNotNull(message2);
assertTrue("Expected message to be a TextMessage", message2 instanceof TextMessage);
assertTrue("Expected message to be a '" + message.getText() + "'", ((TextMessage)message2).getText().equals(message.getText()));
}
/**
* Make sure that a temp queue does not drop message if there are no active
* consumers.
*
* @throws JMSException
*/
public void testTempQueueHoldsMessagesWithoutConsumers() throws JMSException {
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createTemporaryQueue();
MessageProducer producer = session.createProducer(queue);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
TextMessage message = session.createTextMessage("Hello");
producer.send(message);
connection.start();
MessageConsumer consumer = session.createConsumer(queue);
Message message2 = consumer.receive(3000);
assertNotNull(message2);
assertTrue("Expected message to be a TextMessage", message2 instanceof TextMessage);
assertTrue("Expected message to be a '" + message.getText() + "'", ((TextMessage)message2).getText().equals(message.getText()));
}
/**
* Test temp queue works under load
*
* @throws JMSException
*/
public void testTmpQueueWorksUnderLoad() throws JMSException {
int count = 500;
int dataSize = 1024;
ArrayList<BytesMessage> list = new ArrayList<BytesMessage>(count);
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createTemporaryQueue();
MessageProducer producer = session.createProducer(queue);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
byte[] data = new byte[dataSize];
for (int i = 0; i < count; i++) {
BytesMessage message = session.createBytesMessage();
message.writeBytes(data);
message.setIntProperty("c", i);
producer.send(message);
list.add(message);
}
connection.start();
MessageConsumer consumer = session.createConsumer(queue);
for (int i = 0; i < count; i++) {
Message message2 = consumer.receive(2000);
assertTrue(message2 != null);
assertEquals(i, message2.getIntProperty("c"));
assertTrue(message2.equals(list.get(i)));
}
}
/**
* Make sure you cannot publish to a temp destination that does not exist
* anymore.
*
* @throws JMSException
* @throws InterruptedException
* @throws URISyntaxException
*/
public void testPublishFailsForClosedConnection() throws Exception {
Connection tempConnection = factory.createConnection();
connections.add(tempConnection);
Session tempSession = tempConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
final TemporaryQueue queue = tempSession.createTemporaryQueue();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
connection.start();
final ActiveMQConnection activeMQConnection = (ActiveMQConnection) connection;
assertTrue("creation advisory received in time with async dispatch", Wait.waitFor(new Wait.Condition() {
@Override
public boolean isSatisified() throws Exception {
return activeMQConnection.activeTempDestinations.containsKey(queue);
}
}));
// This message delivery should work since the temp connection is still
// open.
MessageProducer producer = session.createProducer(queue);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
TextMessage message = session.createTextMessage("First");
producer.send(message);
// Closing the connection should destroy the temp queue that was
// created.
tempConnection.close();
Thread.sleep(5000); // Wait a little bit to let the delete take effect.
// This message delivery NOT should work since the temp connection is
// now closed.
try {
message = session.createTextMessage("Hello");
producer.send(message);
fail("Send should fail since temp destination should not exist anymore.");
} catch (JMSException e) {
}
}
/**
* Make sure you cannot publish to a temp destination that does not exist
* anymore.
*
* @throws JMSException
* @throws InterruptedException
*/
public void testPublishFailsForDestroyedTempDestination() throws Exception {
Connection tempConnection = factory.createConnection();
connections.add(tempConnection);
Session tempSession = tempConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
final TemporaryQueue queue = tempSession.createTemporaryQueue();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
connection.start();
final ActiveMQConnection activeMQConnection = (ActiveMQConnection) connection;
assertTrue("creation advisory received in time with async dispatch", Wait.waitFor(new Wait.Condition() {
@Override
public boolean isSatisified() throws Exception {
return activeMQConnection.activeTempDestinations.containsKey(queue);
}
}));
// This message delivery should work since the temp connection is still
// open.
MessageProducer producer = session.createProducer(queue);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
TextMessage message = session.createTextMessage("First");
producer.send(message);
// deleting the Queue will cause sends to fail
queue.delete();
Thread.sleep(5000); // Wait a little bit to let the delete take effect.
// This message delivery NOT should work since the temp connection is
// now closed.
try {
message = session.createTextMessage("Hello");
producer.send(message);
fail("Send should fail since temp destination should not exist anymore.");
} catch (JMSException e) {
assertTrue("failed to throw an exception", true);
}
}
/**
* Test you can't delete a Destination with Active Subscribers
*
* @throws JMSException
*/
public void testDeleteDestinationWithSubscribersFails() throws JMSException {
Connection connection = factory.createConnection();
connections.add(connection);
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
TemporaryQueue queue = session.createTemporaryQueue();
connection.start();
session.createConsumer(queue);
// This message delivery should NOT work since the temp connection is
// now closed.
try {
queue.delete();
fail("Should fail as Subscribers are active");
} catch (JMSException e) {
assertTrue("failed to throw an exception", true);
}
}
public void testSlowConsumerDoesNotBlockFastTempUsers() throws Exception {
ActiveMQConnectionFactory advisoryConnFactory = new ActiveMQConnectionFactory("vm://localhost?asyncQueueDepth=20");
Connection connection = advisoryConnFactory.createConnection();
connections.add(connection);
connection.start();
final CountDownLatch done = new CountDownLatch(1);
final AtomicBoolean ok = new AtomicBoolean(true);
final AtomicBoolean first = new AtomicBoolean(true);
VMTransport t = ((ActiveMQConnection)connection).getTransport().narrow(VMTransport.class);
t.setTransportListener(new TransportListener() {
@Override
public void onCommand(Object command) {
// block first dispatch for a while so broker backs up, but other connection should be able to proceed
if (first.compareAndSet(true, false)) {
try {
ok.set(done.await(35, TimeUnit.SECONDS));
LOG.info("Done waiting: " + ok.get());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public void onException(IOException error) {
}
@Override
public void transportInterupted() {
}
@Override
public void transportResumed() {
}
});
connection = factory.createConnection();
connections.add(connection);
((ActiveMQConnection)connection).setWatchTopicAdvisories(false);
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
for (int i=0; i<2500; i++) {
TemporaryQueue queue = session.createTemporaryQueue();
MessageConsumer consumer = session.createConsumer(queue);
consumer.close();
queue.delete();
}
LOG.info("Done with work: " + ok.get());
done.countDown();
assertTrue("ok", ok.get());
}
}

View File

@ -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.File;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import org.apache.activemq.broker.BrokerFactory;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.command.ActiveMQDestination;
/**
* Test cases used to test the JMS message consumer.
*
*
*/
public class JmsTestSupport extends CombinationTestSupport {
static final private AtomicLong TEST_COUNTER = new AtomicLong();
public String userName;
public String password;
public String messageTextPrefix = "";
protected ConnectionFactory factory;
protected ActiveMQConnection connection;
protected BrokerService broker;
protected List<Connection> connections = Collections.synchronizedList(new ArrayList<Connection>());
// /////////////////////////////////////////////////////////////////
//
// Test support methods.
//
// /////////////////////////////////////////////////////////////////
protected ActiveMQDestination createDestination(Session session, byte type) throws JMSException {
String testMethod = getName();
if( testMethod.indexOf(" ")>0 ) {
testMethod = testMethod.substring(0, testMethod.indexOf(" "));
}
String name = "TEST." + getClass().getName() + "." +testMethod+"."+TEST_COUNTER.getAndIncrement();
switch (type) {
case ActiveMQDestination.QUEUE_TYPE:
return (ActiveMQDestination)session.createQueue(name);
case ActiveMQDestination.TOPIC_TYPE:
return (ActiveMQDestination)session.createTopic(name);
case ActiveMQDestination.TEMP_QUEUE_TYPE:
return (ActiveMQDestination)session.createTemporaryQueue();
case ActiveMQDestination.TEMP_TOPIC_TYPE:
return (ActiveMQDestination)session.createTemporaryTopic();
default:
throw new IllegalArgumentException("type: " + type);
}
}
protected void sendMessages(Destination destination, int count) throws Exception {
ConnectionFactory factory = createConnectionFactory();
Connection connection = factory.createConnection();
connection.start();
sendMessages(connection, destination, count);
connection.close();
}
protected void sendMessages(Connection connection, Destination destination, int count) throws JMSException {
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
sendMessages(session, destination, count);
session.close();
}
protected void sendMessages(Session session, Destination destination, int count) throws JMSException {
MessageProducer producer = session.createProducer(destination);
sendMessages(session, producer, count);
producer.close();
}
protected void sendMessages(Session session, MessageProducer producer, int count) throws JMSException {
for (int i = 0; i < count; i++) {
producer.send(session.createTextMessage(messageTextPrefix + i));
}
}
protected ConnectionFactory createConnectionFactory() throws Exception {
return new ActiveMQConnectionFactory("vm://localhost");
}
protected BrokerService createBroker() throws Exception {
return BrokerFactory.createBroker(new URI("broker://()/localhost?persistent=false"));
}
protected void setUp() throws Exception {
super.setUp();
if (System.getProperty("basedir") == null) {
File file = new File(".");
System.setProperty("basedir", file.getAbsolutePath());
}
broker = createBroker();
broker.start();
factory = createConnectionFactory();
connection = (ActiveMQConnection)factory.createConnection(userName, password);
connections.add(connection);
}
protected void tearDown() throws Exception {
for (Iterator<Connection> iter = connections.iterator(); iter.hasNext();) {
Connection conn = iter.next();
try {
conn.close();
} catch (Throwable e) {
}
iter.remove();
}
broker.stop();
super.tearDown();
}
protected void safeClose(Connection c) {
try {
c.close();
} catch (Throwable e) {
}
}
protected void safeClose(Session s) {
try {
s.close();
} catch (Throwable e) {
}
}
protected void safeClose(MessageConsumer c) {
try {
c.close();
} catch (Throwable e) {
}
}
protected void safeClose(MessageProducer p) {
try {
p.close();
} catch (Throwable e) {
}
}
protected void profilerPause(String prompt) throws IOException {
if (System.getProperty("profiler") != null) {
pause(prompt);
}
}
protected void pause(String prompt) throws IOException {
System.out.println();
System.out.println(prompt + "> Press enter to continue: ");
while (System.in.read() != '\n') {
}
}
}

View File

@ -0,0 +1,88 @@
/**
* 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 javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.MessageConsumer;
import javax.jms.Topic;
import org.apache.activemq.test.JmsTopicSendReceiveTest;
/**
*
*/
public class JmsTopicCompositeSendReceiveTest extends JmsTopicSendReceiveTest {
private static final org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory
.getLog(JmsTopicCompositeSendReceiveTest.class);
Destination consumerDestination2;
MessageConsumer consumer2;
/**
* Sets a test to have a queue destination and non-persistent delivery mode.
*
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
deliveryMode = DeliveryMode.NON_PERSISTENT;
super.setUp();
consumerDestination2 = consumeSession.createTopic("FOO.BAR.HUMBUG2");
LOG.info("Created consumer destination: " + consumerDestination2 + " of type: " + consumerDestination2.getClass());
if (durable) {
LOG.info("Creating durable consumer");
consumer2 = consumeSession.createDurableSubscriber((Topic) consumerDestination2, getName());
} else {
consumer2 = consumeSession.createConsumer(consumerDestination2);
}
}
/**
* Returns the consumer subject.
*
* @return String - consumer subject
* @see org.apache.activemq.test.TestSupport#getConsumerSubject()
*/
protected String getConsumerSubject() {
return "FOO.BAR.HUMBUG";
}
/**
* Returns the producer subject.
*
* @return String - producer subject
* @see org.apache.activemq.test.TestSupport#getProducerSubject()
*/
protected String getProducerSubject() {
return "FOO.BAR.HUMBUG,FOO.BAR.HUMBUG2";
}
/**
* Test if all the messages sent are being received.
*
* @throws Exception
*/
public void testSendReceive() throws Exception {
super.testSendReceive();
messages.clear();
consumer2.setMessageListener(this);
assertMessagesAreReceived();
LOG.info("" + data.length + " messages(s) received, closing down connections");
}
}

View File

@ -0,0 +1,161 @@
/**
* 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 javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
*/
public class JmsTopicRedeliverTest extends TestSupport {
private static final Logger LOG = LoggerFactory.getLogger(JmsTopicRedeliverTest.class);
protected Connection connection;
protected Session session;
protected Session consumeSession;
protected MessageConsumer consumer;
protected MessageProducer producer;
protected Destination consumerDestination;
protected Destination producerDestination;
protected boolean topic = true;
protected boolean durable;
protected boolean verbose;
protected long initRedeliveryDelay;
protected void setUp() throws Exception {
super.setUp();
connectionFactory = createConnectionFactory();
connection = createConnection();
initRedeliveryDelay = ((ActiveMQConnection)connection).getRedeliveryPolicy().getInitialRedeliveryDelay();
if (durable) {
connection.setClientID(getClass().getName());
}
LOG.info("Created connection: " + connection);
session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
consumeSession = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
LOG.info("Created session: " + session);
LOG.info("Created consumeSession: " + consumeSession);
producer = session.createProducer(null);
// producer.setDeliveryMode(deliveryMode);
LOG.info("Created producer: " + producer);
if (topic) {
consumerDestination = session.createTopic(getConsumerSubject());
producerDestination = session.createTopic(getProducerSubject());
} else {
consumerDestination = session.createQueue(getConsumerSubject());
producerDestination = session.createQueue(getProducerSubject());
}
LOG.info("Created consumer destination: " + consumerDestination + " of type: " + consumerDestination.getClass());
LOG.info("Created producer destination: " + producerDestination + " of type: " + producerDestination.getClass());
consumer = createConsumer();
connection.start();
LOG.info("Created connection: " + connection);
}
protected void tearDown() throws Exception {
if (connection != null) {
connection.close();
}
super.tearDown();
}
/**
* Returns the consumer subject.
*
* @return String - consumer subject
* @see org.apache.activemq.test.TestSupport#getConsumerSubject()
*/
protected String getConsumerSubject() {
return "TEST";
}
/**
* Returns the producer subject.
*
* @return String - producer subject
* @see org.apache.activemq.test.TestSupport#getProducerSubject()
*/
protected String getProducerSubject() {
return "TEST";
}
/**
* Sends and consumes the messages.
*
* @throws Exception
*/
public void testRecover() throws Exception {
String text = "TEST";
Message sendMessage = session.createTextMessage(text);
if (verbose) {
LOG.info("About to send a message: " + sendMessage + " with text: " + text);
}
producer.send(producerDestination, sendMessage);
// receive but don't acknowledge
Message unackMessage = consumer.receive(initRedeliveryDelay + 1000);
assertNotNull(unackMessage);
String unackId = unackMessage.getJMSMessageID();
assertEquals(((TextMessage)unackMessage).getText(), text);
assertFalse(unackMessage.getJMSRedelivered());
// assertEquals(unackMessage.getIntProperty("JMSXDeliveryCount"),1);
// receive then acknowledge
consumeSession.recover();
Message ackMessage = consumer.receive(initRedeliveryDelay + 1000);
assertNotNull(ackMessage);
ackMessage.acknowledge();
String ackId = ackMessage.getJMSMessageID();
assertEquals(((TextMessage)ackMessage).getText(), text);
assertTrue(ackMessage.getJMSRedelivered());
// assertEquals(ackMessage.getIntProperty("JMSXDeliveryCount"),2);
assertEquals(unackId, ackId);
consumeSession.recover();
assertNull(consumer.receiveNoWait());
}
protected MessageConsumer createConsumer() throws JMSException {
if (durable) {
LOG.info("Creating durable consumer");
return consumeSession.createDurableSubscriber((Topic)consumerDestination, getName());
}
return consumeSession.createConsumer(consumerDestination);
}
}

View File

@ -0,0 +1,222 @@
/**
* 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.util.List;
import java.util.Vector;
import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TemporaryQueue;
import javax.jms.TemporaryTopic;
import javax.jms.TextMessage;
import org.apache.activemq.test.TestSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
*/
public class JmsTopicRequestReplyTest extends TestSupport implements MessageListener {
private static final Logger LOG = LoggerFactory.getLogger(JmsTopicRequestReplyTest.class);
protected boolean useAsyncConsume;
private Connection serverConnection;
private Connection clientConnection;
private MessageProducer replyProducer;
private Session serverSession;
private Destination requestDestination;
private List<JMSException> failures = new Vector<JMSException>();
private boolean dynamicallyCreateProducer;
private String clientSideClientID;
public void testSendAndReceive() throws Exception {
clientConnection = createConnection();
clientConnection.setClientID("ClientConnection:" + getSubject());
Session session = clientConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
clientConnection.start();
Destination replyDestination = createTemporaryDestination(session);
// lets test the destination
clientSideClientID = clientConnection.getClientID();
// TODO
// String value = ActiveMQDestination.getClientId((ActiveMQDestination)
// replyDestination);
// assertEquals("clientID from the temporary destination must be the
// same", clientSideClientID, value);
LOG.info("Both the clientID and destination clientID match properly: " + clientSideClientID);
/* build queues */
MessageProducer requestProducer = session.createProducer(requestDestination);
MessageConsumer replyConsumer = session.createConsumer(replyDestination);
/* build requestmessage */
TextMessage requestMessage = session.createTextMessage("Olivier");
requestMessage.setJMSReplyTo(replyDestination);
requestProducer.send(requestMessage);
LOG.info("Sent request.");
LOG.info(requestMessage.toString());
Message msg = replyConsumer.receive(5000);
if (msg instanceof TextMessage) {
TextMessage replyMessage = (TextMessage)msg;
LOG.info("Received reply.");
LOG.info(replyMessage.toString());
assertEquals("Wrong message content", "Hello: Olivier", replyMessage.getText());
} else {
fail("Should have received a reply by now");
}
replyConsumer.close();
deleteTemporaryDestination(replyDestination);
assertEquals("Should not have had any failures: " + failures, 0, failures.size());
}
public void testSendAndReceiveWithDynamicallyCreatedProducer() throws Exception {
dynamicallyCreateProducer = true;
testSendAndReceive();
}
/**
* Use the asynchronous subscription mechanism
*/
public void onMessage(Message message) {
try {
TextMessage requestMessage = (TextMessage)message;
LOG.info("Received request.");
LOG.info(requestMessage.toString());
Destination replyDestination = requestMessage.getJMSReplyTo();
// TODO
// String value =
// ActiveMQDestination.getClientId((ActiveMQDestination)
// replyDestination);
// assertEquals("clientID from the temporary destination must be the
// same", clientSideClientID, value);
TextMessage replyMessage = serverSession.createTextMessage("Hello: " + requestMessage.getText());
replyMessage.setJMSCorrelationID(requestMessage.getJMSMessageID());
if (dynamicallyCreateProducer) {
replyProducer = serverSession.createProducer(replyDestination);
replyProducer.send(replyMessage);
} else {
replyProducer.send(replyDestination, replyMessage);
}
LOG.info("Sent reply.");
LOG.info(replyMessage.toString());
} catch (JMSException e) {
onException(e);
}
}
/**
* Use the synchronous subscription mechanism
*/
protected void syncConsumeLoop(MessageConsumer requestConsumer) {
try {
Message message = requestConsumer.receive(5000);
if (message != null) {
onMessage(message);
} else {
LOG.error("No message received");
}
} catch (JMSException e) {
onException(e);
}
}
protected void setUp() throws Exception {
super.setUp();
serverConnection = createConnection();
serverConnection.setClientID("serverConnection:" + getSubject());
serverSession = serverConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
replyProducer = serverSession.createProducer(null);
requestDestination = createDestination(serverSession);
/* build queues */
final MessageConsumer requestConsumer = serverSession.createConsumer(requestDestination);
if (useAsyncConsume) {
requestConsumer.setMessageListener(this);
} else {
Thread thread = new Thread(new Runnable() {
public void run() {
syncConsumeLoop(requestConsumer);
}
});
thread.start();
}
serverConnection.start();
}
protected void tearDown() throws Exception {
super.tearDown();
serverConnection.close();
clientConnection.stop();
clientConnection.close();
}
protected void onException(JMSException e) {
LOG.info("Caught: " + e);
e.printStackTrace();
failures.add(e);
}
protected Destination createDestination(Session session) throws JMSException {
if (topic) {
return session.createTopic(getSubject());
}
return session.createQueue(getSubject());
}
protected Destination createTemporaryDestination(Session session) throws JMSException {
if (topic) {
return session.createTemporaryTopic();
}
return session.createTemporaryQueue();
}
protected void deleteTemporaryDestination(Destination dest) throws JMSException {
if (topic) {
((TemporaryTopic)dest).delete();
} else {
((TemporaryQueue)dest).delete();
}
}
}

View File

@ -0,0 +1,208 @@
/**
* 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 javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
*/
public class JmsTopicSelectorTest extends TestSupport {
private static final Logger LOG = LoggerFactory.getLogger(JmsTopicSelectorTest.class);
protected Connection connection;
protected Session session;
protected MessageConsumer consumer;
protected MessageProducer producer;
protected Destination consumerDestination;
protected Destination producerDestination;
protected boolean topic = true;
protected boolean durable;
protected int deliveryMode = DeliveryMode.PERSISTENT;
public void setUp() throws Exception {
super.setUp();
connectionFactory = createConnectionFactory();
connection = createConnection();
if (durable) {
connection.setClientID(getClass().getName());
}
LOG.info("Created connection: " + connection);
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
LOG.info("Created session: " + session);
if (topic) {
consumerDestination = session.createTopic(getConsumerSubject());
producerDestination = session.createTopic(getProducerSubject());
} else {
consumerDestination = session.createQueue(getConsumerSubject());
producerDestination = session.createQueue(getProducerSubject());
}
LOG.info("Created consumer destination: " + consumerDestination + " of type: " + consumerDestination.getClass());
LOG.info("Created producer destination: " + producerDestination + " of type: " + producerDestination.getClass());
producer = session.createProducer(producerDestination);
producer.setDeliveryMode(deliveryMode);
LOG.info("Created producer: " + producer + " delivery mode = " + (deliveryMode == DeliveryMode.PERSISTENT ? "PERSISTENT" : "NON_PERSISTENT"));
connection.start();
}
public void tearDown() throws Exception {
session.close();
connection.close();
}
protected MessageConsumer createConsumer(String selector) throws JMSException {
if (durable) {
LOG.info("Creating durable consumer");
return session.createDurableSubscriber((Topic)consumerDestination, getName(), selector, false);
}
return session.createConsumer(consumerDestination, selector);
}
public void sendMessages() throws Exception {
TextMessage message = session.createTextMessage("1");
message.setIntProperty("id", 1);
message.setJMSType("a");
message.setStringProperty("stringProperty", "a");
message.setLongProperty("longProperty", 1);
message.setBooleanProperty("booleanProperty", true);
producer.send(message);
message = session.createTextMessage("2");
message.setIntProperty("id", 2);
message.setJMSType("a");
message.setStringProperty("stringProperty", "a");
message.setLongProperty("longProperty", 1);
message.setBooleanProperty("booleanProperty", false);
producer.send(message);
message = session.createTextMessage("3");
message.setIntProperty("id", 3);
message.setJMSType("a");
message.setStringProperty("stringProperty", "a");
message.setLongProperty("longProperty", 1);
message.setBooleanProperty("booleanProperty", true);
producer.send(message);
message = session.createTextMessage("4");
message.setIntProperty("id", 4);
message.setJMSType("b");
message.setStringProperty("stringProperty", "b");
message.setLongProperty("longProperty", 2);
message.setBooleanProperty("booleanProperty", false);
producer.send(message);
message = session.createTextMessage("5");
message.setIntProperty("id", 5);
message.setJMSType("c");
message.setStringProperty("stringProperty", "c");
message.setLongProperty("longProperty", 3);
message.setBooleanProperty("booleanProperty", true);
producer.send(message);
}
public void consumeMessages(int remaining) throws Exception {
consumer = createConsumer(null);
for (int i = 0; i < remaining; i++) {
consumer.receive(1000);
}
consumer.close();
}
public void testEmptyPropertySelector() throws Exception {
int remaining = 5;
Message message = null;
consumer = createConsumer("");
sendMessages();
while (true) {
message = consumer.receive(1000);
if (message == null) {
break;
}
remaining--;
}
assertEquals(remaining, 0);
consumer.close();
consumeMessages(remaining);
}
public void testPropertySelector() throws Exception {
int remaining = 5;
Message message = null;
consumer = createConsumer("stringProperty = 'a' and longProperty = 1 and booleanProperty = true");
sendMessages();
while (true) {
message = consumer.receive(1000);
if (message == null) {
break;
}
String text = ((TextMessage)message).getText();
if (!text.equals("1") && !text.equals("3")) {
fail("unexpected message: " + text);
}
remaining--;
}
assertEquals(remaining, 3);
consumer.close();
consumeMessages(remaining);
}
public void testJMSPropertySelector() throws Exception {
int remaining = 5;
Message message = null;
consumer = createConsumer("JMSType = 'a' and stringProperty = 'a'");
sendMessages();
while (true) {
message = consumer.receive(1000);
if (message == null) {
break;
}
String text = ((TextMessage)message).getText();
if (!text.equals("1") && !text.equals("2") && !text.equals("3")) {
fail("unexpected message: " + text);
}
remaining--;
}
assertEquals(remaining, 2);
consumer.close();
consumeMessages(remaining);
}
}

View File

@ -0,0 +1,36 @@
/**
* 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 javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.Topic;
import javax.jms.TopicSession;
/**
*
*/
public class JmsTopicSendReceiveSubscriberTest extends JmsTopicSendReceiveTest {
protected MessageConsumer createConsumer() throws JMSException {
if (durable) {
return super.createConsumer();
} else {
TopicSession topicSession = (TopicSession)session;
return topicSession.createSubscriber((Topic)consumerDestination, null, false);
}
}
}

View File

@ -0,0 +1,92 @@
/**
* 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 javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.Topic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
*/
public class JmsTopicSendReceiveTest extends JmsSendReceiveTestSupport {
private static final Logger LOG = LoggerFactory.getLogger(JmsTopicSendReceiveTest.class);
protected Connection connection;
protected void setUp() throws Exception {
super.setUp();
connectionFactory = createConnectionFactory();
connection = createConnection();
if (durable) {
connection.setClientID(getClass().getName());
}
LOG.info("Created connection: " + connection);
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
LOG.info("Created session: " + session);
producer = session.createProducer(null);
producer.setDeliveryMode(deliveryMode);
LOG.info("Created producer: " + producer + " delivery mode = " + (deliveryMode == DeliveryMode.PERSISTENT ? "PERSISTENT" : "NON_PERSISTENT"));
if (topic) {
consumerDestination = session.createTopic(getConsumerSubject());
producerDestination = session.createTopic(getProducerSubject());
} else {
consumerDestination = session.createQueue(getConsumerSubject());
producerDestination = session.createQueue(getProducerSubject());
}
LOG.info("Created consumer destination: " + consumerDestination + " of type: " + consumerDestination.getClass());
LOG.info("Created producer destination: " + producerDestination + " of type: " + producerDestination.getClass());
consumer = createConsumer();
consumer.setMessageListener(this);
connection.start();
// log.info("Created connection: " + connection);
}
protected MessageConsumer createConsumer() throws JMSException {
if (durable) {
LOG.info("Creating durable consumer");
return session.createDurableSubscriber((Topic)consumerDestination, getName());
}
return session.createConsumer(consumerDestination);
}
protected void tearDown() throws Exception {
LOG.info("Dumping stats...");
// connectionFactory.getStats().reset();
LOG.info("Closing down connection");
/** TODO we should be able to shut down properly */
session.close();
connection.close();
}
}

View File

@ -0,0 +1,113 @@
/**
* 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 javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.Session;
/**
* @version
*/
public class JmsTopicSendReceiveWithTwoConnectionsTest extends JmsSendReceiveTestSupport {
private static final org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory
.getLog(JmsTopicSendReceiveWithTwoConnectionsTest.class);
protected Connection sendConnection;
protected Connection receiveConnection;
protected Session receiveSession;
protected void setUp() throws Exception {
super.setUp();
connectionFactory = createConnectionFactory();
sendConnection = createSendConnection();
sendConnection.start();
receiveConnection = createReceiveConnection();
receiveConnection.start();
LOG.info("Created sendConnection: " + sendConnection);
LOG.info("Created receiveConnection: " + receiveConnection);
session = createSendSession(sendConnection);
receiveSession = createReceiveSession(receiveConnection);
LOG.info("Created sendSession: " + session);
LOG.info("Created receiveSession: " + receiveSession);
producer = session.createProducer(null);
producer.setDeliveryMode(deliveryMode);
LOG.info("Created producer: " + producer + " delivery mode = "
+ (deliveryMode == DeliveryMode.PERSISTENT ? "PERSISTENT" : "NON_PERSISTENT"));
if (topic) {
consumerDestination = session.createTopic(getConsumerSubject());
producerDestination = session.createTopic(getProducerSubject());
} else {
consumerDestination = session.createQueue(getConsumerSubject());
producerDestination = session.createQueue(getProducerSubject());
}
LOG.info("Created consumer destination: " + consumerDestination + " of type: "
+ consumerDestination.getClass());
LOG.info("Created producer destination: " + producerDestination + " of type: "
+ producerDestination.getClass());
consumer = createConsumer(receiveSession, consumerDestination);
consumer.setMessageListener(this);
LOG.info("Started connections");
}
protected Session createReceiveSession(Connection receiveConnection) throws Exception {
return receiveConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
}
protected Session createSendSession(Connection sendConnection) throws Exception {
return sendConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
}
protected Connection createReceiveConnection() throws Exception {
return createConnection();
}
protected Connection createSendConnection() throws Exception {
return createConnection();
}
protected MessageConsumer createConsumer(Session session, Destination dest) throws JMSException {
return session.createConsumer(dest);
}
protected ActiveMQConnectionFactory createConnectionFactory() throws Exception {
return new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false");
}
protected void tearDown() throws Exception {
session.close();
receiveSession.close();
sendConnection.close();
receiveConnection.close();
}
}

View File

@ -0,0 +1,29 @@
/**
* 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;
/**
*
*
*/
public class JmsTopicSendReceiveWithTwoConnectionsWithJMXTest extends
JmsTopicSendReceiveWithTwoConnectionsTest {
protected ActiveMQConnectionFactory createConnectionFactory() throws Exception {
return new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false&broker.useJmx=true");
}
}

View File

@ -0,0 +1,48 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq;
import javax.jms.TextMessage;
/**
*
*/
public class JmsTopicSendSameMessageTest extends JmsTopicSendReceiveWithTwoConnectionsTest {
private static final org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory
.getLog(JmsTopicSendSameMessageTest.class);
public void testSendReceive() throws Exception {
messages.clear();
TextMessage message = session.createTextMessage();
for (int i = 0; i < data.length; i++) {
message.setText(data[i]);
message.setStringProperty("stringProperty", data[i]);
message.setIntProperty("intProperty", i);
if (verbose) {
LOG.info("About to send a message: " + message + " with text: " + data[i]);
}
producer.send(producerDestination, message);
}
assertMessagesAreReceived();
}
}

View File

@ -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.
*/
package org.apache.activemq;
import org.apache.activemq.test.JmsResourceProvider;
/**
*
*/
public class JmsTopicTransactionTest extends JmsTransactionTestSupport {
/**
* @see org.apache.activemq.JmsTransactionTestSupport#getJmsResourceProvider()
*/
protected JmsResourceProvider getJmsResourceProvider() {
JmsResourceProvider p = new JmsResourceProvider();
p.setTopic(true);
p.setDurableName("testsub");
p.setClientID("testclient");
return p;
}
}

View File

@ -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;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.test.JmsTopicSendReceiveTest;
/**
*
*/
public class JmsTopicWildcardSendReceiveTest extends JmsTopicSendReceiveTest {
private String destination1String = "TEST.ONE.ONE";
private String destination2String = "TEST.ONE.ONE.ONE";
private String destination3String = "TEST.ONE.TWO";
private String destination4String = "TEST.TWO.ONE";
protected void setUp() throws Exception {
topic = true;
durable = false;
deliveryMode = DeliveryMode.NON_PERSISTENT;
super.setUp();
}
protected String getConsumerSubject() {
return "FOO.>";
}
protected String getProducerSubject() {
return "FOO.BAR.HUMBUG";
}
public void testReceiveWildcardTopicEndAsterisk() throws Exception {
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
ActiveMQDestination destination1 = (ActiveMQDestination)session.createTopic(destination1String);
ActiveMQDestination destination3 = (ActiveMQDestination)session.createTopic(destination3String);
Message m = null;
MessageConsumer consumer = null;
String text = null;
ActiveMQDestination destination6 = (ActiveMQDestination)session.createTopic("TEST.ONE.*");
consumer = session.createConsumer(destination6);
sendMessage(session, destination1, destination1String);
sendMessage(session, destination3, destination3String);
m = consumer.receive(1000);
assertNotNull(m);
text = ((TextMessage)m).getText();
if (!(text.equals(destination1String) || text.equals(destination3String))) {
fail("unexpected message:" + text);
}
m = consumer.receive(1000);
assertNotNull(m);
text = ((TextMessage)m).getText();
if (!(text.equals(destination1String) || text.equals(destination3String))) {
fail("unexpected message:" + text);
}
assertNull(consumer.receiveNoWait());
}
public void testReceiveWildcardTopicEndGreaterThan() throws Exception {
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
ActiveMQDestination destination1 = (ActiveMQDestination)session.createTopic(destination1String);
ActiveMQDestination destination2 = (ActiveMQDestination)session.createTopic(destination2String);
ActiveMQDestination destination3 = (ActiveMQDestination)session.createTopic(destination3String);
Message m = null;
MessageConsumer consumer = null;
String text = null;
ActiveMQDestination destination7 = (ActiveMQDestination)session.createTopic("TEST.ONE.>");
consumer = session.createConsumer(destination7);
sendMessage(session, destination1, destination1String);
sendMessage(session, destination2, destination2String);
sendMessage(session, destination3, destination3String);
m = consumer.receive(1000);
assertNotNull(m);
text = ((TextMessage)m).getText();
if (!(text.equals(destination1String) || text.equals(destination2String) || text.equals(destination3String))) {
fail("unexpected message:" + text);
}
m = consumer.receive(1000);
assertNotNull(m);
if (!(text.equals(destination1String) || text.equals(destination2String) || text.equals(destination3String))) {
fail("unexpected message:" + text);
}
m = consumer.receive(1000);
assertNotNull(m);
if (!(text.equals(destination1String) || text.equals(destination2String) || text.equals(destination3String))) {
fail("unexpected message:" + text);
}
assertNull(consumer.receiveNoWait());
}
public void testReceiveWildcardTopicMidAsterisk() throws Exception {
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
ActiveMQDestination destination1 = (ActiveMQDestination)session.createTopic(destination1String);
ActiveMQDestination destination4 = (ActiveMQDestination)session.createTopic(destination4String);
Message m = null;
MessageConsumer consumer = null;
String text = null;
ActiveMQDestination destination8 = (ActiveMQDestination)session.createTopic("TEST.*.ONE");
consumer = session.createConsumer(destination8);
sendMessage(session, destination1, destination1String);
sendMessage(session, destination4, destination4String);
m = consumer.receive(1000);
assertNotNull(m);
text = ((TextMessage)m).getText();
if (!(text.equals(destination1String) || text.equals(destination4String))) {
fail("unexpected message:" + text);
}
m = consumer.receive(1000);
assertNotNull(m);
text = ((TextMessage)m).getText();
if (!(text.equals(destination1String) || text.equals(destination4String))) {
fail("unexpected message:" + text);
}
assertNull(consumer.receiveNoWait());
}
public void testReceiveWildcardTopicMatchDoubleWildcard() throws Exception {
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
ActiveMQDestination destination1 = (ActiveMQDestination)session.createTopic("a.*.>.>");
ActiveMQDestination destination2 = (ActiveMQDestination)session.createTopic("a.b");
Message m = null;
MessageConsumer consumer = null;
String text = null;
consumer = session.createConsumer(destination1);
sendMessage(session, destination2, destination3String);
m = consumer.receive(1000);
assertNotNull(m);
text = ((TextMessage)m).getText();
if (!(text.equals(destination1String) || text.equals(destination3String))) {
fail("unexpected message:" + text);
}
assertNull(consumer.receiveNoWait());
}
public void testReceiveWildcardTopicMatchSinglePastTheEndWildcard() throws Exception {
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
ActiveMQDestination destination1 = (ActiveMQDestination)session.createTopic("a.>");
ActiveMQDestination destination2 = (ActiveMQDestination)session.createTopic("a");
Message m = null;
MessageConsumer consumer = null;
String text = null;
consumer = session.createConsumer(destination1);
sendMessage(session, destination2, destination3String);
m = consumer.receive(1000);
assertNotNull(m);
text = ((TextMessage)m).getText();
if (!(text.equals(destination1String) || text.equals(destination3String))) {
fail("unexpected message:" + text);
}
assertNull(consumer.receiveNoWait());
}
private void sendMessage(Session session, Destination destination, String text) throws JMSException {
MessageProducer producer = session.createProducer(destination);
producer.send(session.createTextMessage(text));
producer.close();
}
}

View File

@ -0,0 +1,197 @@
/**
* 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.util.concurrent.atomic.AtomicInteger;
import javax.jms.BytesMessage;
import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.Topic;
import org.apache.activemq.command.ActiveMQMessage;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
import org.apache.activemq.util.IdGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
*/
public class LargeMessageTestSupport extends ClientTestSupport implements MessageListener {
protected static final int LARGE_MESSAGE_SIZE = 128 * 1024;
protected static final int MESSAGE_COUNT = 100;
private static final Logger LOG = LoggerFactory.getLogger(LargeMessageTestSupport.class);
protected Connection producerConnection;
protected Connection consumerConnection;
protected MessageConsumer consumer;
protected MessageProducer producer;
protected Session producerSession;
protected Session consumerSession;
protected byte[] largeMessageData;
protected Destination destination;
protected boolean isTopic = true;
protected boolean isDurable = true;
protected int deliveryMode = DeliveryMode.PERSISTENT;
protected IdGenerator idGen = new IdGenerator();
protected boolean validMessageConsumption = true;
protected AtomicInteger messageCount = new AtomicInteger(0);
protected int prefetchValue = 10000000;
protected Destination createDestination() {
String subject = getClass().getName();
if (isTopic) {
return new ActiveMQTopic(subject);
} else {
return new ActiveMQQueue(subject);
}
}
protected MessageConsumer createConsumer() throws JMSException {
if (isTopic && isDurable) {
return consumerSession.createDurableSubscriber((Topic)destination, idGen.generateId());
} else {
return consumerSession.createConsumer(destination);
}
}
public void setUp() throws Exception {
super.setUp();
ClientTestSupport.removeMessageStore();
LOG.info("Setting up . . . . . ");
messageCount.set(0);
destination = createDestination();
largeMessageData = new byte[LARGE_MESSAGE_SIZE];
for (int i = 0; i < LARGE_MESSAGE_SIZE; i++) {
if (i % 2 == 0) {
largeMessageData[i] = 'a';
} else {
largeMessageData[i] = 'z';
}
}
try {
// allow the broker to start
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new JMSException(e.getMessage());
}
ActiveMQConnectionFactory fac = getConnectionFactory();
producerConnection = fac.createConnection();
setPrefetchPolicy((ActiveMQConnection)producerConnection);
producerConnection.start();
consumerConnection = fac.createConnection();
setPrefetchPolicy((ActiveMQConnection)consumerConnection);
consumerConnection.setClientID(idGen.generateId());
consumerConnection.start();
producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
producer = producerSession.createProducer(createDestination());
producer.setDeliveryMode(deliveryMode);
consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
consumer = createConsumer();
consumer.setMessageListener(this);
LOG.info("Setup complete");
}
protected void setPrefetchPolicy(ActiveMQConnection activeMQConnection) {
activeMQConnection.getPrefetchPolicy().setTopicPrefetch(prefetchValue);
activeMQConnection.getPrefetchPolicy().setQueuePrefetch(prefetchValue);
activeMQConnection.getPrefetchPolicy().setDurableTopicPrefetch(prefetchValue);
activeMQConnection.getPrefetchPolicy().setQueueBrowserPrefetch(prefetchValue);
activeMQConnection.getPrefetchPolicy().setOptimizeDurableTopicPrefetch(prefetchValue);
}
public void tearDown() throws Exception {
Thread.sleep(1000);
producerConnection.close();
consumerConnection.close();
super.tearDown();
largeMessageData = null;
}
protected boolean isSame(BytesMessage msg1) throws Exception {
boolean result = false;
((ActiveMQMessage)msg1).setReadOnlyBody(true);
for (int i = 0; i < LARGE_MESSAGE_SIZE; i++) {
result = msg1.readByte() == largeMessageData[i];
if (!result) {
break;
}
}
return result;
}
public void onMessage(Message msg) {
try {
BytesMessage ba = (BytesMessage)msg;
validMessageConsumption &= isSame(ba);
assertTrue(ba.getBodyLength() == LARGE_MESSAGE_SIZE);
if (messageCount.incrementAndGet() >= MESSAGE_COUNT) {
synchronized (messageCount) {
messageCount.notify();
}
}
LOG.info("got message = " + messageCount);
if (messageCount.get() % 50 == 0) {
LOG.info("count = " + messageCount);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void testLargeMessages() throws Exception {
for (int i = 0; i < MESSAGE_COUNT; i++) {
LOG.info("Sending message: " + i);
BytesMessage msg = producerSession.createBytesMessage();
msg.writeBytes(largeMessageData);
producer.send(msg);
}
long now = System.currentTimeMillis();
while (now + 60000 > System.currentTimeMillis() && messageCount.get() < MESSAGE_COUNT) {
LOG.info("message count = " + messageCount);
synchronized (messageCount) {
messageCount.wait(1000);
}
}
LOG.info("Finished count = " + messageCount);
assertTrue("Not enough messages - expected " + MESSAGE_COUNT + " but got " + messageCount, messageCount.get() == MESSAGE_COUNT);
assertTrue("received messages are not valid", validMessageConsumption);
Thread.sleep(1000);
LOG.info("FINAL count = " + messageCount);
}
}

View File

@ -0,0 +1,162 @@
/**
* 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;
/**
* 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.
*/
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import javax.jms.Destination;
import javax.jms.Session;
import junit.framework.TestCase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author rnewson
*/
public final class LargeStreamletTest extends TestCase {
private static final Logger LOG = LoggerFactory.getLogger(LargeStreamletTest.class);
private static final String BROKER_URL = "vm://localhost?broker.persistent=false";
private static final int BUFFER_SIZE = 1 * 1024;
private static final int MESSAGE_COUNT = 10 * 1024;
protected Exception writerException;
protected Exception readerException;
private final AtomicInteger totalRead = new AtomicInteger();
private final AtomicInteger totalWritten = new AtomicInteger();
private final AtomicBoolean stopThreads = new AtomicBoolean(false);
public void testStreamlets() throws Exception {
final ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(BROKER_URL);
final ActiveMQConnection connection = (ActiveMQConnection)factory.createConnection();
connection.start();
try {
final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
try {
final Destination destination = session.createQueue("wibble");
final Thread readerThread = new Thread(new Runnable() {
@Override
public void run() {
totalRead.set(0);
try {
final InputStream inputStream = connection.createInputStream(destination);
try {
int read;
final byte[] buf = new byte[BUFFER_SIZE];
while (!stopThreads.get() && (read = inputStream.read(buf)) != -1) {
totalRead.addAndGet(read);
}
} finally {
inputStream.close();
}
} catch (Exception e) {
readerException = e;
e.printStackTrace();
} finally {
LOG.info(totalRead + " total bytes read.");
}
}
});
final Thread writerThread = new Thread(new Runnable() {
private final Random random = new Random();
@Override
public void run() {
totalWritten.set(0);
int count = MESSAGE_COUNT;
try {
final OutputStream outputStream = connection.createOutputStream(destination);
try {
final byte[] buf = new byte[BUFFER_SIZE];
random.nextBytes(buf);
while (count > 0 && !stopThreads.get()) {
outputStream.write(buf);
totalWritten.addAndGet(buf.length);
count--;
}
} finally {
outputStream.close();
}
} catch (Exception e) {
writerException = e;
e.printStackTrace();
} finally {
LOG.info(totalWritten + " total bytes written.");
}
}
});
readerThread.start();
writerThread.start();
// Wait till reader is has finished receiving all the messages
// or he has stopped
// receiving messages.
Thread.sleep(1000);
int lastRead = totalRead.get();
while (readerThread.isAlive()) {
readerThread.join(1000);
// No progress?? then stop waiting..
if (lastRead == totalRead.get()) {
break;
}
lastRead = totalRead.get();
}
stopThreads.set(true);
assertTrue("Should not have received a reader exception", readerException == null);
assertTrue("Should not have received a writer exception", writerException == null);
assertEquals("Not all messages accounted for", totalWritten.get(), totalRead.get());
} finally {
session.close();
}
} finally {
connection.close();
}
}
}

View File

@ -0,0 +1,171 @@
/**
* 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.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import javax.jms.BytesMessage;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.Topic;
import junit.framework.Test;
import org.apache.activemq.broker.BrokerFactory;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.broker.TransportConnector;
import org.apache.activemq.command.ActiveMQDestination;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Small burn test moves sends a moderate amount of messages through the broker,
* to checking to make sure that the broker does not lock up after a while of
* sustained messaging.
*
*
*/
public class LoadTestBurnIn extends JmsTestSupport {
private static final transient Logger LOG = LoggerFactory.getLogger(LoadTestBurnIn.class);
public ActiveMQDestination destination;
public int deliveryMode;
public byte destinationType;
public boolean durableConsumer;
public int messageCount = 50000;
public int messageSize = 1024;
public static Test suite() {
return suite(LoadTestBurnIn.class);
}
protected void setUp() throws Exception {
LOG.info("Start: " + getName());
super.setUp();
}
protected void tearDown() throws Exception {
try {
super.tearDown();
} catch (Throwable e) {
e.printStackTrace(System.out);
} finally {
LOG.info("End: " + getName());
}
}
public static void main(String[] args) {
junit.textui.TestRunner.run(suite());
}
protected BrokerService createBroker() throws Exception {
return BrokerFactory.createBroker(new URI("broker://(tcp://localhost:0)?useJmx=true"));
// return BrokerFactory.createBroker(new
// URI("xbean:org/apache/activemq/broker/store/loadtester.xml"));
}
protected ConnectionFactory createConnectionFactory() throws URISyntaxException, IOException {
return new ActiveMQConnectionFactory(((TransportConnector)broker.getTransportConnectors().get(0))
.getServer().getConnectURI());
}
public void initCombosForTestSendReceive() {
addCombinationValues("deliveryMode", new Object[] {Integer.valueOf(DeliveryMode.NON_PERSISTENT),
Integer.valueOf(DeliveryMode.PERSISTENT)});
addCombinationValues("destinationType", new Object[] {Byte.valueOf(ActiveMQDestination.TOPIC_TYPE)});
addCombinationValues("durableConsumer", new Object[] {Boolean.TRUE});
addCombinationValues("messageSize", new Object[] {Integer.valueOf(101), Integer.valueOf(102),
Integer.valueOf(103), Integer.valueOf(104),
Integer.valueOf(105), Integer.valueOf(106),
Integer.valueOf(107), Integer.valueOf(108)});
}
public void testSendReceive() throws Exception {
// Durable consumer combination is only valid with topics
if (durableConsumer && destinationType != ActiveMQDestination.TOPIC_TYPE) {
return;
}
connection.setClientID(getName());
connection.getPrefetchPolicy().setAll(1000);
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = createDestination(session, destinationType);
MessageConsumer consumer;
if (durableConsumer) {
consumer = session.createDurableSubscriber((Topic)destination, "sub1:"
+ System.currentTimeMillis());
} else {
consumer = session.createConsumer(destination);
}
profilerPause("Ready: ");
final CountDownLatch producerDoneLatch = new CountDownLatch(1);
// Send the messages, async
new Thread() {
public void run() {
Connection connection2 = null;
try {
connection2 = factory.createConnection();
Session session = connection2.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(deliveryMode);
for (int i = 0; i < messageCount; i++) {
BytesMessage m = session.createBytesMessage();
m.writeBytes(new byte[messageSize]);
producer.send(m);
}
producer.close();
} catch (JMSException e) {
e.printStackTrace();
} finally {
safeClose(connection2);
producerDoneLatch.countDown();
}
}
}.start();
// Make sure all the messages were delivered.
Message message = null;
for (int i = 0; i < messageCount; i++) {
message = consumer.receive(5000);
assertNotNull("Did not get message: " + i, message);
}
profilerPause("Done: ");
assertNull(consumer.receiveNoWait());
message.acknowledge();
// Make sure the producer thread finishes.
assertTrue(producerDoneLatch.await(5, TimeUnit.SECONDS));
}
}

View File

@ -0,0 +1,288 @@
/**
* 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 static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.Topic;
import org.apache.activemq.advisory.AdvisorySupport;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.broker.region.policy.ConstantPendingMessageLimitStrategy;
import org.apache.activemq.broker.region.policy.FilePendingSubscriberMessageStoragePolicy;
import org.apache.activemq.broker.region.policy.OldestMessageEvictionStrategy;
import org.apache.activemq.broker.region.policy.PendingSubscriberMessageStoragePolicy;
import org.apache.activemq.broker.region.policy.PolicyEntry;
import org.apache.activemq.broker.region.policy.PolicyMap;
import org.apache.activemq.broker.region.policy.VMPendingSubscriberMessageStoragePolicy;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.ActiveMQMessage;
import org.apache.activemq.command.ActiveMQTopic;
import org.apache.activemq.util.Wait;
import org.junit.After;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MessageEvictionTest {
static final Logger LOG = LoggerFactory.getLogger(MessageEvictionTest.class);
private BrokerService broker;
private ConnectionFactory connectionFactory;
Connection connection;
private Session session;
private Topic destination;
private final String destinationName = "verifyEvection";
protected int numMessages = 2000;
protected String payload = new String(new byte[1024*2]);
public void setUp(PendingSubscriberMessageStoragePolicy pendingSubscriberPolicy) throws Exception {
broker = createBroker(pendingSubscriberPolicy);
broker.start();
connectionFactory = createConnectionFactory();
connection = connectionFactory.createConnection();
connection.start();
session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
destination = session.createTopic(destinationName);
}
@After
public void tearDown() throws Exception {
connection.stop();
broker.stop();
}
@Test
public void testMessageEvictionMemoryUsageFileCursor() throws Exception {
setUp(new FilePendingSubscriberMessageStoragePolicy());
doTestMessageEvictionMemoryUsage();
}
@Test
public void testMessageEvictionMemoryUsageVmCursor() throws Exception {
setUp(new VMPendingSubscriberMessageStoragePolicy());
doTestMessageEvictionMemoryUsage();
}
@Test
public void testMessageEvictionDiscardedAdvisory() throws Exception {
setUp(new VMPendingSubscriberMessageStoragePolicy());
ExecutorService executor = Executors.newSingleThreadExecutor();
final CountDownLatch consumerRegistered = new CountDownLatch(1);
final CountDownLatch gotAdvisory = new CountDownLatch(1);
final CountDownLatch advisoryIsGood = new CountDownLatch(1);
executor.execute(new Runnable() {
@Override
public void run() {
try {
ActiveMQTopic discardedAdvisoryDestination =
AdvisorySupport.getMessageDiscardedAdvisoryTopic(destination);
// use separate session rather than asyncDispatch on consumer session
// as we want consumer session to block
Session advisorySession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
final MessageConsumer consumer = advisorySession.createConsumer(discardedAdvisoryDestination);
consumer.setMessageListener(new MessageListener() {
int advisoriesReceived = 0;
@Override
public void onMessage(Message message) {
try {
LOG.info("advisory:" + message);
ActiveMQMessage activeMQMessage = (ActiveMQMessage) message;
assertNotNull(activeMQMessage.getStringProperty(AdvisorySupport.MSG_PROPERTY_CONSUMER_ID));
assertEquals(++advisoriesReceived, activeMQMessage.getIntProperty(AdvisorySupport.MSG_PROPERTY_DISCARDED_COUNT));
message.acknowledge();
advisoryIsGood.countDown();
} catch (JMSException e) {
e.printStackTrace();
fail(e.toString());
} finally {
gotAdvisory.countDown();
}
}
});
consumerRegistered.countDown();
gotAdvisory.await(120, TimeUnit.SECONDS);
consumer.close();
advisorySession.close();
} catch (Exception e) {
e.printStackTrace();
fail(e.toString());
}
}
});
assertTrue("we have an advisory consumer", consumerRegistered.await(60, TimeUnit.SECONDS));
doTestMessageEvictionMemoryUsage();
assertTrue("got an advisory for discarded", gotAdvisory.await(0, TimeUnit.SECONDS));
assertTrue("advisory is good",advisoryIsGood.await(0, TimeUnit.SECONDS));
}
public void doTestMessageEvictionMemoryUsage() throws Exception {
ExecutorService executor = Executors.newCachedThreadPool();
final CountDownLatch doAck = new CountDownLatch(1);
final CountDownLatch ackDone = new CountDownLatch(1);
final CountDownLatch consumerRegistered = new CountDownLatch(1);
executor.execute(new Runnable() {
@Override
public void run() {
try {
final MessageConsumer consumer = session.createConsumer(destination);
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
try {
// very slow, only ack once
doAck.await(60, TimeUnit.SECONDS);
LOG.info("acking: " + message.getJMSMessageID());
message.acknowledge();
ackDone.countDown();
} catch (Exception e) {
e.printStackTrace();
fail(e.toString());
} finally {
consumerRegistered.countDown();
ackDone.countDown();
}
}
});
consumerRegistered.countDown();
ackDone.await(60, TimeUnit.SECONDS);
consumer.close();
} catch (Exception e) {
e.printStackTrace();
fail(e.toString());
}
}
});
assertTrue("we have a consumer", consumerRegistered.await(10, TimeUnit.SECONDS));
final AtomicInteger sent = new AtomicInteger(0);
final CountDownLatch sendDone = new CountDownLatch(1);
executor.execute(new Runnable() {
@Override
public void run() {
MessageProducer producer;
try {
producer = session.createProducer(destination);
for (int i=0; i< numMessages; i++) {
producer.send(session.createTextMessage(payload));
sent.incrementAndGet();
TimeUnit.MILLISECONDS.sleep(10);
}
producer.close();
sendDone.countDown();
} catch (Exception e) {
sendDone.countDown();
e.printStackTrace();
fail(e.toString());
}
}
});
assertTrue("messages sending done", sendDone.await(180, TimeUnit.SECONDS));
assertEquals("all message were sent", numMessages, sent.get());
doAck.countDown();
executor.shutdown();
executor.awaitTermination(30, TimeUnit.SECONDS);
assertTrue("usage goes to 0 once consumer goes away", Wait.waitFor(new Wait.Condition() {
@Override
public boolean isSatisified() throws Exception {
return 0 == TestSupport.getDestination(broker,
ActiveMQDestination.transform(destination)).getMemoryUsage().getPercentUsage();
}
}));
}
BrokerService createBroker(PendingSubscriberMessageStoragePolicy pendingSubscriberPolicy) throws Exception {
BrokerService brokerService = new BrokerService();
brokerService.addConnector("tcp://localhost:0");
brokerService.setUseJmx(false);
brokerService.setDeleteAllMessagesOnStartup(true);
// spooling to disk early so topic memory limit is not reached
brokerService.getSystemUsage().getMemoryUsage().setLimit(500*1024);
final List<PolicyEntry> policyEntries = new ArrayList<PolicyEntry>();
final PolicyEntry entry = new PolicyEntry();
entry.setTopic(">");
entry.setAdvisoryForDiscardingMessages(true);
// so consumer does not get over run while blocked limit the prefetch
entry.setTopicPrefetch(50);
entry.setPendingSubscriberPolicy(pendingSubscriberPolicy);
// limit the number of outstanding messages, large enough to use the file store
// or small enough not to blow memory limit
int pendingMessageLimit = 50;
if (pendingSubscriberPolicy instanceof FilePendingSubscriberMessageStoragePolicy) {
pendingMessageLimit = 500;
}
ConstantPendingMessageLimitStrategy pendingMessageLimitStrategy = new ConstantPendingMessageLimitStrategy();
pendingMessageLimitStrategy.setLimit(pendingMessageLimit);
entry.setPendingMessageLimitStrategy(pendingMessageLimitStrategy);
// to keep the limit in check and up to date rather than just the first few, evict some
OldestMessageEvictionStrategy messageEvictionStrategy = new OldestMessageEvictionStrategy();
// whether to check expiry before eviction, default limit 1000 is fine as no ttl set in this test
//messageEvictionStrategy.setEvictExpiredMessagesHighWatermark(1000);
entry.setMessageEvictionStrategy(messageEvictionStrategy);
// let evicted messaged disappear
entry.setDeadLetterStrategy(null);
policyEntries.add(entry);
final PolicyMap policyMap = new PolicyMap();
policyMap.setPolicyEntries(policyEntries);
brokerService.setDestinationPolicy(policyMap);
return brokerService;
}
ConnectionFactory createConnectionFactory() throws Exception {
String url = broker.getTransportConnectors().get(0).getServer().getConnectURI().toString();
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(url);
factory.setWatchTopicAdvisories(false);
return factory;
}
}

View File

@ -0,0 +1,357 @@
/**
* 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.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import junit.framework.TestCase;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.ActiveMQMessage;
import org.apache.activemq.command.ActiveMQQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MessageListenerRedeliveryTest extends TestCase {
private static final Logger LOG = LoggerFactory.getLogger(MessageListenerRedeliveryTest.class);
private Connection connection;
@Override
protected void setUp() throws Exception {
connection = createConnection();
}
/**
* @see junit.framework.TestCase#tearDown()
*/
@Override
protected void tearDown() throws Exception {
if (connection != null) {
connection.close();
connection = null;
}
}
protected RedeliveryPolicy getRedeliveryPolicy() {
RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
redeliveryPolicy.setInitialRedeliveryDelay(0);
redeliveryPolicy.setRedeliveryDelay(1000);
redeliveryPolicy.setMaximumRedeliveries(3);
redeliveryPolicy.setBackOffMultiplier((short)2);
redeliveryPolicy.setUseExponentialBackOff(true);
return redeliveryPolicy;
}
protected Connection createConnection() throws Exception {
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false&marshal=true");
factory.setRedeliveryPolicy(getRedeliveryPolicy());
return factory.createConnection();
}
private class TestMessageListener implements MessageListener {
public int counter;
private final Session session;
public TestMessageListener(Session session) {
this.session = session;
}
@Override
public void onMessage(Message message) {
try {
LOG.info("Message Received: " + message);
counter++;
if (counter <= 4) {
LOG.info("Message Rollback.");
session.rollback();
} else {
LOG.info("Message Commit.");
message.acknowledge();
session.commit();
}
} catch (JMSException e) {
LOG.error("Error when rolling back transaction");
}
}
}
public void testQueueRollbackConsumerListener() throws JMSException {
connection.start();
Session session = connection.createSession(true, Session.CLIENT_ACKNOWLEDGE);
Queue queue = session.createQueue("queue-" + getName());
MessageProducer producer = createProducer(session, queue);
Message message = createTextMessage(session);
producer.send(message);
session.commit();
MessageConsumer consumer = session.createConsumer(queue);
ActiveMQMessageConsumer mc = (ActiveMQMessageConsumer)consumer;
mc.setRedeliveryPolicy(getRedeliveryPolicy());
TestMessageListener listener = new TestMessageListener(session);
consumer.setMessageListener(listener);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
// first try.. should get 2 since there is no delay on the
// first redeliver..
assertEquals(2, listener.counter);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
// 2nd redeliver (redelivery after 1 sec)
assertEquals(3, listener.counter);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
// 3rd redeliver (redelivery after 2 seconds) - it should give up after
// that
assertEquals(4, listener.counter);
// create new message
producer.send(createTextMessage(session));
session.commit();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
// it should be committed, so no redelivery
assertEquals(5, listener.counter);
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
}
// no redelivery, counter should still be 4
assertEquals(5, listener.counter);
session.close();
}
public void testQueueRollbackSessionListener() throws JMSException {
connection.start();
Session session = connection.createSession(true, Session.CLIENT_ACKNOWLEDGE);
Queue queue = session.createQueue("queue-" + getName());
MessageProducer producer = createProducer(session, queue);
Message message = createTextMessage(session);
producer.send(message);
session.commit();
MessageConsumer consumer = session.createConsumer(queue);
ActiveMQMessageConsumer mc = (ActiveMQMessageConsumer)consumer;
mc.setRedeliveryPolicy(getRedeliveryPolicy());
TestMessageListener listener = new TestMessageListener(session);
consumer.setMessageListener(listener);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
// first try
assertEquals(2, listener.counter);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
// second try (redelivery after 1 sec)
assertEquals(3, listener.counter);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
// third try (redelivery after 2 seconds) - it should give up after that
assertEquals(4, listener.counter);
// create new message
producer.send(createTextMessage(session));
session.commit();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// ignore
}
// it should be committed, so no redelivery
assertEquals(5, listener.counter);
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
// ignore
}
// no redelivery, counter should still be 4
assertEquals(5, listener.counter);
session.close();
}
public void testQueueSessionListenerExceptionRetry() throws Exception {
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue("queue-" + getName());
MessageProducer producer = createProducer(session, queue);
Message message = createTextMessage(session, "1");
producer.send(message);
message = createTextMessage(session, "2");
producer.send(message);
MessageConsumer consumer = session.createConsumer(queue);
final CountDownLatch gotMessage = new CountDownLatch(2);
final AtomicInteger count = new AtomicInteger(0);
final int maxDeliveries = getRedeliveryPolicy().getMaximumRedeliveries();
final ArrayList<String> received = new ArrayList<String>();
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
LOG.info("Message Received: " + message);
try {
received.add(((TextMessage) message).getText());
} catch (JMSException e) {
e.printStackTrace();
fail(e.toString());
}
if (count.incrementAndGet() < maxDeliveries) {
throw new RuntimeException(getName() + " force a redelivery");
}
// new blood
count.set(0);
gotMessage.countDown();
}
});
assertTrue("got message before retry expiry", gotMessage.await(20, TimeUnit.SECONDS));
for (int i=0; i<maxDeliveries; i++) {
assertEquals("got first redelivered: " + i, "1", received.get(i));
}
for (int i=maxDeliveries; i<maxDeliveries*2; i++) {
assertEquals("got first redelivered: " + i, "2", received.get(i));
}
session.close();
}
public void testQueueSessionListenerExceptionDlq() throws Exception {
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue("queue-" + getName());
MessageProducer producer = createProducer(session, queue);
Message message = createTextMessage(session);
producer.send(message);
final Message[] dlqMessage = new Message[1];
ActiveMQDestination dlqDestination = new ActiveMQQueue("ActiveMQ.DLQ");
MessageConsumer dlqConsumer = session.createConsumer(dlqDestination);
final CountDownLatch gotDlqMessage = new CountDownLatch(1);
dlqConsumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
LOG.info("DLQ Message Received: " + message);
dlqMessage[0] = message;
gotDlqMessage.countDown();
}
});
MessageConsumer consumer = session.createConsumer(queue);
final int maxDeliveries = getRedeliveryPolicy().getMaximumRedeliveries();
final CountDownLatch gotMessage = new CountDownLatch(maxDeliveries);
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
LOG.info("Message Received: " + message);
gotMessage.countDown();
throw new RuntimeException(getName() + " force a redelivery");
}
});
assertTrue("got message before retry expiry", gotMessage.await(20, TimeUnit.SECONDS));
// check DLQ
assertTrue("got dlq message", gotDlqMessage.await(20, TimeUnit.SECONDS));
// check DLQ message cause is captured
message = dlqMessage[0];
assertNotNull("dlq message captured", message);
String cause = message.getStringProperty(ActiveMQMessage.DLQ_DELIVERY_FAILURE_CAUSE_PROPERTY);
LOG.info("DLQ'd message cause reported as: {}", cause);
assertTrue("cause 'cause' exception is remembered", cause.contains("RuntimeException"));
assertTrue("is correct exception", cause.contains(getName()));
assertTrue("cause exception is remembered", cause.contains("Throwable"));
assertTrue("cause policy is remembered", cause.contains("RedeliveryPolicy"));
session.close();
}
private TextMessage createTextMessage(Session session, String text) throws JMSException {
return session.createTextMessage(text);
}
private TextMessage createTextMessage(Session session) throws JMSException {
return session.createTextMessage("Hello");
}
private MessageProducer createProducer(Session session, Destination queue) throws JMSException {
MessageProducer producer = session.createProducer(queue);
producer.setDeliveryMode(getDeliveryMode());
return producer;
}
protected int getDeliveryMode() {
return DeliveryMode.PERSISTENT;
}
}

Some files were not shown because too many files have changed in this diff Show More