ARTEMIS-3758: clean up lots of tests that never run, remove related files + dependencies and some unnecessary deps
This commit is contained in:
parent
94aa67bd81
commit
6da678177a
|
@ -29,16 +29,6 @@
|
|||
|
||||
<properties>
|
||||
<activemq.basedir>${project.basedir}/../..</activemq.basedir>
|
||||
<jmdns-version>3.4.1</jmdns-version>
|
||||
<ftpserver-version>1.0.6</ftpserver-version>
|
||||
<jmock-version>2.5.1</jmock-version>
|
||||
<spring-version>5.3.18</spring-version>
|
||||
<org-apache-derby-version>10.11.1.1</org-apache-derby-version>
|
||||
<commons-net-version>3.3</commons-net-version>
|
||||
<xbean-version>3.18</xbean-version>
|
||||
<hamcrest-version>1.3</hamcrest-version>
|
||||
<jasypt-version>1.9.3</jasypt-version>
|
||||
<activeio-core-version>3.1.4</activeio-core-version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
@ -93,18 +83,6 @@
|
|||
<version>${activemq5-version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.activemq</groupId>
|
||||
<artifactId>activemq-leveldb-store</artifactId>
|
||||
<version>${activemq5-version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-beanutils</groupId>
|
||||
<artifactId>commons-beanutils-core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.activemq</groupId>
|
||||
<artifactId>activemq-pool</artifactId>
|
||||
|
@ -117,36 +95,12 @@
|
|||
<version>${activemq5-version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.activemq</groupId>
|
||||
<artifactId>activemq-partition</artifactId>
|
||||
<version>${activemq5-version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.activemq</groupId>
|
||||
<artifactId>activemq-stomp</artifactId>
|
||||
<version>${activemq5-version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.activemq</groupId>
|
||||
<artifactId>activemq-console</artifactId>
|
||||
<version>${activemq5-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>
|
||||
|
@ -159,137 +113,23 @@
|
|||
<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>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-net</groupId>
|
||||
<artifactId>commons-net</artifactId>
|
||||
<version>${commons-net-version}</version>
|
||||
</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.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${spring-version}</version>
|
||||
<version>${spring.version}</version>
|
||||
<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>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.directory.server</groupId>
|
||||
<artifactId>apacheds-server-integ</artifactId>
|
||||
<version>${directory-version}</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</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>${spring.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
<?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 -->
|
|
@ -1,37 +0,0 @@
|
|||
<?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 -->
|
|
@ -32,7 +32,6 @@ import org.apache.activemq.command.ActiveMQDestination;
|
|||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.apache.activemq.command.ActiveMQTopic;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.springframework.jms.core.JmsTemplate;
|
||||
|
||||
/**
|
||||
* A useful base class which creates and closes an embedded broker
|
||||
|
@ -45,7 +44,6 @@ public abstract class EmbeddedBrokerTestSupport extends CombinationTestSupport {
|
|||
protected ConnectionFactory connectionFactory;
|
||||
protected boolean useTopic;
|
||||
protected ActiveMQDestination destination;
|
||||
protected JmsTemplate template;
|
||||
protected boolean disableWrapper = false;
|
||||
|
||||
public TemporaryFolder temporaryFolder;
|
||||
|
@ -68,11 +66,6 @@ public abstract class EmbeddedBrokerTestSupport extends CombinationTestSupport {
|
|||
connectionFactory = createConnectionFactory();
|
||||
|
||||
destination = createDestination();
|
||||
|
||||
template = createJmsTemplate();
|
||||
template.setDefaultDestination(destination);
|
||||
template.setPubSubDomain(useTopic);
|
||||
template.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -115,15 +108,6 @@ public abstract class EmbeddedBrokerTestSupport extends CombinationTestSupport {
|
|||
return "tcp://" + localhostAddress + ":" + (61616 + serverID);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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}
|
||||
*
|
||||
|
|
|
@ -1,668 +0,0 @@
|
|||
/**
|
||||
* 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.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 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 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() {
|
||||
@Override
|
||||
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)}.
|
||||
*
|
||||
* @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
|
||||
* @see #hasBridge(String, String)
|
||||
*/
|
||||
protected void waitForBridge(final String localBrokerName,
|
||||
final String remoteBrokerName,
|
||||
long time,
|
||||
TimeUnit units) throws InterruptedException, TimeoutException, Exception {
|
||||
if (!Wait.waitFor(new Wait.Condition() {
|
||||
@Override
|
||||
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() {
|
||||
@Override
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
brokers = new HashMap<>();
|
||||
destinations = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
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(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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,168 +0,0 @@
|
|||
/**
|
||||
* 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.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 java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import junit.framework.Test;
|
||||
|
||||
import org.apache.activemq.broker.BrokerFactory;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
LOG.info("Start: " + getName());
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
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());
|
||||
}
|
||||
|
||||
@Override
|
||||
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"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConnectionFactory createConnectionFactory() throws URISyntaxException, IOException {
|
||||
return new ActiveMQConnectionFactory(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() {
|
||||
@Override
|
||||
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));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
/**
|
||||
* 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.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.context.support.AbstractApplicationContext;
|
||||
|
||||
/**
|
||||
* A useful base class for spring based unit test cases
|
||||
*/
|
||||
public abstract class SpringTestSupport extends TestCase {
|
||||
|
||||
protected AbstractApplicationContext context;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
context = createApplicationContext();
|
||||
}
|
||||
|
||||
protected abstract AbstractApplicationContext createApplicationContext();
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
if (context != null) {
|
||||
context.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
protected Object getBean(String name) {
|
||||
Object bean = context.getBean(name);
|
||||
if (bean == null) {
|
||||
fail("Should have found bean named '" + name + "' in the Spring ApplicationContext");
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
protected void assertSetEquals(String description, Object[] expected, Set<?> actual) {
|
||||
Set<Object> expectedSet = new HashSet<>();
|
||||
expectedSet.addAll(Arrays.asList(expected));
|
||||
assertEquals(description, expectedSet, actual);
|
||||
}
|
||||
|
||||
}
|
|
@ -35,7 +35,6 @@ import org.apache.activemq.command.ActiveMQTopic;
|
|||
import org.apache.activemq.store.PersistenceAdapter;
|
||||
import org.apache.activemq.store.jdbc.JDBCPersistenceAdapter;
|
||||
import org.apache.activemq.store.kahadb.KahaDBPersistenceAdapter;
|
||||
import org.apache.activemq.store.leveldb.LevelDBPersistenceAdapter;
|
||||
import org.apache.activemq.store.memory.MemoryPersistenceAdapter;
|
||||
|
||||
/**
|
||||
|
@ -168,7 +167,7 @@ public abstract class TestSupport extends CombinationTestSupport {
|
|||
return destination.isQueue() ? regionBroker.getQueueRegion().getDestinationMap() : regionBroker.getTopicRegion().getDestinationMap();
|
||||
}
|
||||
|
||||
public static enum PersistenceAdapterChoice {LevelDB, KahaDB, AMQ, JDBC, MEM}
|
||||
public static enum PersistenceAdapterChoice {KahaDB, AMQ, JDBC, MEM}
|
||||
|
||||
public PersistenceAdapter setDefaultPersistenceAdapter(BrokerService broker) throws IOException {
|
||||
return setPersistenceAdapter(broker, defaultPersistenceAdapter);
|
||||
|
@ -186,9 +185,6 @@ public abstract class TestSupport extends CombinationTestSupport {
|
|||
case KahaDB:
|
||||
adapter = new KahaDBPersistenceAdapter();
|
||||
break;
|
||||
case LevelDB:
|
||||
adapter = new LevelDBPersistenceAdapter();
|
||||
break;
|
||||
case MEM:
|
||||
adapter = new MemoryPersistenceAdapter();
|
||||
break;
|
||||
|
|
|
@ -35,7 +35,6 @@ import org.apache.activemq.command.ActiveMQDestination;
|
|||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.apache.activemq.command.ConsumerControl;
|
||||
import org.apache.activemq.command.ExceptionResponse;
|
||||
import org.apache.activemq.spring.SpringConsumer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -54,9 +53,8 @@ public class ZeroPrefetchConsumerTest extends EmbeddedBrokerTestSupport {
|
|||
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
MessageConsumer consumer = session.createConsumer(queue);
|
||||
|
||||
MessageListener listener = new SpringConsumer();
|
||||
try {
|
||||
consumer.setMessageListener(listener);
|
||||
consumer.setMessageListener(msg -> {});
|
||||
fail("Should have thrown JMSException as we cannot use MessageListener with zero prefetch");
|
||||
} catch (JMSException e) {
|
||||
LOG.info("Received expected exception : " + e);
|
||||
|
|
|
@ -1,226 +0,0 @@
|
|||
/**
|
||||
* 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.advisory;
|
||||
|
||||
import javax.jms.BytesMessage;
|
||||
import javax.jms.Connection;
|
||||
import javax.jms.ConnectionFactory;
|
||||
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.TemporaryQueue;
|
||||
import javax.jms.Topic;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnection;
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.region.policy.ConstantPendingMessageLimitStrategy;
|
||||
import org.apache.activemq.broker.region.policy.PolicyEntry;
|
||||
import org.apache.activemq.broker.region.policy.PolicyMap;
|
||||
import org.apache.activemq.command.ActiveMQDestination;
|
||||
import org.apache.activemq.command.ActiveMQMessage;
|
||||
|
||||
public class AdvisoryTempDestinationTests extends TestCase {
|
||||
|
||||
protected static final int MESSAGE_COUNT = 2000;
|
||||
protected BrokerService broker;
|
||||
protected Connection connection;
|
||||
protected String bindAddress = ActiveMQConnectionFactory.DEFAULT_BROKER_BIND_URL;
|
||||
protected int topicCount;
|
||||
|
||||
public void testNoSlowConsumerAdvisory() throws Exception {
|
||||
Session s = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
TemporaryQueue queue = s.createTemporaryQueue();
|
||||
MessageConsumer consumer = s.createConsumer(queue);
|
||||
consumer.setMessageListener(new MessageListener() {
|
||||
@Override
|
||||
public void onMessage(Message message) {
|
||||
}
|
||||
});
|
||||
Topic advisoryTopic = AdvisorySupport.getSlowConsumerAdvisoryTopic((ActiveMQDestination) queue);
|
||||
s = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
MessageConsumer advisoryConsumer = s.createConsumer(advisoryTopic);
|
||||
// start throwing messages at the consumer
|
||||
MessageProducer producer = s.createProducer(queue);
|
||||
for (int i = 0; i < MESSAGE_COUNT; i++) {
|
||||
BytesMessage m = s.createBytesMessage();
|
||||
m.writeBytes(new byte[1024]);
|
||||
producer.send(m);
|
||||
}
|
||||
Message msg = advisoryConsumer.receive(1000);
|
||||
assertNull(msg);
|
||||
}
|
||||
|
||||
public void testSlowConsumerAdvisory() throws Exception {
|
||||
Session s = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
TemporaryQueue queue = s.createTemporaryQueue();
|
||||
MessageConsumer consumer = s.createConsumer(queue);
|
||||
assertNotNull(consumer);
|
||||
|
||||
Topic advisoryTopic = AdvisorySupport.getSlowConsumerAdvisoryTopic((ActiveMQDestination) queue);
|
||||
s = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
MessageConsumer advisoryConsumer = s.createConsumer(advisoryTopic);
|
||||
// start throwing messages at the consumer
|
||||
MessageProducer producer = s.createProducer(queue);
|
||||
for (int i = 0; i < MESSAGE_COUNT; i++) {
|
||||
BytesMessage m = s.createBytesMessage();
|
||||
m.writeBytes(new byte[1024]);
|
||||
producer.send(m);
|
||||
}
|
||||
Message msg = advisoryConsumer.receive(1000);
|
||||
assertNotNull(msg);
|
||||
}
|
||||
|
||||
public void testMessageDeliveryAdvisory() throws Exception {
|
||||
Session s = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
TemporaryQueue queue = s.createTemporaryQueue();
|
||||
MessageConsumer consumer = s.createConsumer(queue);
|
||||
assertNotNull(consumer);
|
||||
|
||||
Topic advisoryTopic = AdvisorySupport.getMessageDeliveredAdvisoryTopic((ActiveMQDestination) queue);
|
||||
MessageConsumer advisoryConsumer = s.createConsumer(advisoryTopic);
|
||||
//start throwing messages at the consumer
|
||||
MessageProducer producer = s.createProducer(queue);
|
||||
|
||||
BytesMessage m = s.createBytesMessage();
|
||||
m.writeBytes(new byte[1024]);
|
||||
producer.send(m);
|
||||
|
||||
Message msg = advisoryConsumer.receive(1000);
|
||||
assertNotNull(msg);
|
||||
}
|
||||
|
||||
public void testTempMessageConsumedAdvisory() throws Exception {
|
||||
Session s = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
TemporaryQueue queue = s.createTemporaryQueue();
|
||||
MessageConsumer consumer = s.createConsumer(queue);
|
||||
|
||||
Topic advisoryTopic = AdvisorySupport.getMessageConsumedAdvisoryTopic((ActiveMQDestination) queue);
|
||||
MessageConsumer advisoryConsumer = s.createConsumer(advisoryTopic);
|
||||
//start throwing messages at the consumer
|
||||
MessageProducer producer = s.createProducer(queue);
|
||||
|
||||
BytesMessage m = s.createBytesMessage();
|
||||
m.writeBytes(new byte[1024]);
|
||||
producer.send(m);
|
||||
String id = m.getJMSMessageID();
|
||||
Message msg = consumer.receive(1000);
|
||||
assertNotNull(msg);
|
||||
|
||||
msg = advisoryConsumer.receive(1000);
|
||||
assertNotNull(msg);
|
||||
|
||||
ActiveMQMessage message = (ActiveMQMessage) msg;
|
||||
ActiveMQMessage payload = (ActiveMQMessage) message.getDataStructure();
|
||||
String originalId = payload.getJMSMessageID();
|
||||
assertEquals(originalId, id);
|
||||
}
|
||||
|
||||
public void testMessageExpiredAdvisory() throws Exception {
|
||||
Session s = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
Queue queue = s.createQueue(getClass().getName());
|
||||
MessageConsumer consumer = s.createConsumer(queue);
|
||||
assertNotNull(consumer);
|
||||
|
||||
Topic advisoryTopic = AdvisorySupport.getExpiredMessageTopic((ActiveMQDestination) queue);
|
||||
MessageConsumer advisoryConsumer = s.createConsumer(advisoryTopic);
|
||||
//start throwing messages at the consumer
|
||||
MessageProducer producer = s.createProducer(queue);
|
||||
producer.setTimeToLive(1);
|
||||
for (int i = 0; i < MESSAGE_COUNT; i++) {
|
||||
BytesMessage m = s.createBytesMessage();
|
||||
m.writeBytes(new byte[1024]);
|
||||
producer.send(m);
|
||||
}
|
||||
|
||||
Message msg = advisoryConsumer.receive(5000);
|
||||
assertNotNull(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
if (broker == null) {
|
||||
broker = createBroker();
|
||||
}
|
||||
ConnectionFactory factory = createConnectionFactory();
|
||||
connection = factory.createConnection();
|
||||
connection.start();
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
connection.close();
|
||||
if (broker != null) {
|
||||
broker.stop();
|
||||
}
|
||||
}
|
||||
|
||||
protected ActiveMQConnectionFactory createConnectionFactory() throws Exception {
|
||||
ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_BROKER_URL);
|
||||
return cf;
|
||||
}
|
||||
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerService answer = new BrokerService();
|
||||
configureBroker(answer);
|
||||
answer.start();
|
||||
return answer;
|
||||
}
|
||||
|
||||
protected void configureBroker(BrokerService answer) throws Exception {
|
||||
answer.setPersistent(false);
|
||||
ConstantPendingMessageLimitStrategy strategy = new ConstantPendingMessageLimitStrategy();
|
||||
strategy.setLimit(10);
|
||||
PolicyEntry tempQueueEntry = createPolicyEntry(strategy);
|
||||
tempQueueEntry.setTempQueue(true);
|
||||
PolicyEntry tempTopicEntry = createPolicyEntry(strategy);
|
||||
tempTopicEntry.setTempTopic(true);
|
||||
|
||||
PolicyMap pMap = new PolicyMap();
|
||||
final List<PolicyEntry> policyEntries = new ArrayList<>();
|
||||
policyEntries.add(tempQueueEntry);
|
||||
policyEntries.add(tempTopicEntry);
|
||||
pMap.setPolicyEntries(policyEntries);
|
||||
|
||||
answer.setDestinationPolicy(pMap);
|
||||
answer.addConnector(bindAddress);
|
||||
answer.setDeleteAllMessagesOnStartup(true);
|
||||
}
|
||||
|
||||
private PolicyEntry createPolicyEntry(ConstantPendingMessageLimitStrategy strategy) {
|
||||
PolicyEntry policy = new PolicyEntry();
|
||||
policy.setAdvisoryForFastProducers(true);
|
||||
policy.setAdvisoryForConsumed(true);
|
||||
policy.setAdvisoryForDelivery(true);
|
||||
policy.setAdvisoryForDiscardingMessages(true);
|
||||
policy.setAdvisoryForSlowConsumers(true);
|
||||
policy.setAdvisoryWhenFull(true);
|
||||
policy.setProducerFlowControl(false);
|
||||
policy.setPendingMessageLimitStrategy(strategy);
|
||||
|
||||
return policy;
|
||||
}
|
||||
}
|
|
@ -1,234 +0,0 @@
|
|||
/**
|
||||
* 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.advisory;
|
||||
|
||||
import javax.jms.BytesMessage;
|
||||
import javax.jms.Connection;
|
||||
import javax.jms.ConnectionFactory;
|
||||
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.Topic;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnection;
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.ActiveMQPrefetchPolicy;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.region.policy.ConstantPendingMessageLimitStrategy;
|
||||
import org.apache.activemq.broker.region.policy.PolicyEntry;
|
||||
import org.apache.activemq.broker.region.policy.PolicyMap;
|
||||
import org.apache.activemq.command.ActiveMQDestination;
|
||||
import org.apache.activemq.command.ActiveMQMessage;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class AdvisoryTests extends TestCase {
|
||||
|
||||
protected static final int MESSAGE_COUNT = 2000;
|
||||
protected BrokerService broker;
|
||||
protected Connection connection;
|
||||
protected String bindAddress = ActiveMQConnectionFactory.DEFAULT_BROKER_BIND_URL;
|
||||
protected int topicCount;
|
||||
|
||||
public void testNoSlowConsumerAdvisory() throws Exception {
|
||||
Session s = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
Queue queue = s.createQueue(getClass().getName());
|
||||
MessageConsumer consumer = s.createConsumer(queue);
|
||||
consumer.setMessageListener(new MessageListener() {
|
||||
@Override
|
||||
public void onMessage(Message message) {
|
||||
}
|
||||
});
|
||||
Topic advisoryTopic = AdvisorySupport.getSlowConsumerAdvisoryTopic((ActiveMQDestination) queue);
|
||||
s = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
MessageConsumer advisoryConsumer = s.createConsumer(advisoryTopic);
|
||||
// start throwing messages at the consumer
|
||||
MessageProducer producer = s.createProducer(queue);
|
||||
for (int i = 0; i < MESSAGE_COUNT; i++) {
|
||||
BytesMessage m = s.createBytesMessage();
|
||||
m.writeBytes(new byte[1024]);
|
||||
producer.send(m);
|
||||
}
|
||||
Message msg = advisoryConsumer.receive(1000);
|
||||
assertNull(msg);
|
||||
}
|
||||
|
||||
public void testSlowConsumerAdvisory() throws Exception {
|
||||
Session s = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
Queue queue = s.createQueue(getClass().getName());
|
||||
MessageConsumer consumer = s.createConsumer(queue);
|
||||
assertNotNull(consumer);
|
||||
|
||||
Topic advisoryTopic = AdvisorySupport.getSlowConsumerAdvisoryTopic((ActiveMQDestination) queue);
|
||||
s = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
MessageConsumer advisoryConsumer = s.createConsumer(advisoryTopic);
|
||||
// start throwing messages at the consumer
|
||||
MessageProducer producer = s.createProducer(queue);
|
||||
for (int i = 0; i < MESSAGE_COUNT; i++) {
|
||||
BytesMessage m = s.createBytesMessage();
|
||||
m.writeBytes(new byte[1024]);
|
||||
producer.send(m);
|
||||
}
|
||||
Message msg = advisoryConsumer.receive(1000);
|
||||
assertNotNull(msg);
|
||||
}
|
||||
|
||||
public void testMessageDeliveryAdvisory() throws Exception {
|
||||
Session s = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
Queue queue = s.createQueue(getClass().getName());
|
||||
MessageConsumer consumer = s.createConsumer(queue);
|
||||
assertNotNull(consumer);
|
||||
|
||||
Topic advisoryTopic = AdvisorySupport.getMessageDeliveredAdvisoryTopic((ActiveMQDestination) queue);
|
||||
MessageConsumer advisoryConsumer = s.createConsumer(advisoryTopic);
|
||||
//start throwing messages at the consumer
|
||||
MessageProducer producer = s.createProducer(queue);
|
||||
|
||||
BytesMessage m = s.createBytesMessage();
|
||||
m.writeBytes(new byte[1024]);
|
||||
producer.send(m);
|
||||
|
||||
Message msg = advisoryConsumer.receive(1000);
|
||||
assertNotNull(msg);
|
||||
}
|
||||
|
||||
public void testMessageConsumedAdvisory() throws Exception {
|
||||
Session s = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
Queue queue = s.createQueue(getClass().getName());
|
||||
MessageConsumer consumer = s.createConsumer(queue);
|
||||
|
||||
Topic advisoryTopic = AdvisorySupport.getMessageConsumedAdvisoryTopic((ActiveMQDestination) queue);
|
||||
MessageConsumer advisoryConsumer = s.createConsumer(advisoryTopic);
|
||||
//start throwing messages at the consumer
|
||||
MessageProducer producer = s.createProducer(queue);
|
||||
|
||||
BytesMessage m = s.createBytesMessage();
|
||||
m.writeBytes(new byte[1024]);
|
||||
producer.send(m);
|
||||
String id = m.getJMSMessageID();
|
||||
Message msg = consumer.receive(1000);
|
||||
assertNotNull(msg);
|
||||
|
||||
msg = advisoryConsumer.receive(1000);
|
||||
assertNotNull(msg);
|
||||
|
||||
ActiveMQMessage message = (ActiveMQMessage) msg;
|
||||
ActiveMQMessage payload = (ActiveMQMessage) message.getDataStructure();
|
||||
String originalId = payload.getJMSMessageID();
|
||||
assertEquals(originalId, id);
|
||||
}
|
||||
|
||||
public void testMessageExpiredAdvisory() throws Exception {
|
||||
Session s = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
Queue queue = s.createQueue(getClass().getName());
|
||||
MessageConsumer consumer = s.createConsumer(queue);
|
||||
assertNotNull(consumer);
|
||||
|
||||
Topic advisoryTopic = AdvisorySupport.getExpiredMessageTopic((ActiveMQDestination) queue);
|
||||
MessageConsumer advisoryConsumer = s.createConsumer(advisoryTopic);
|
||||
//start throwing messages at the consumer
|
||||
MessageProducer producer = s.createProducer(queue);
|
||||
producer.setTimeToLive(1);
|
||||
for (int i = 0; i < MESSAGE_COUNT; i++) {
|
||||
BytesMessage m = s.createBytesMessage();
|
||||
m.writeBytes(new byte[1024]);
|
||||
producer.send(m);
|
||||
}
|
||||
|
||||
Message msg = advisoryConsumer.receive(2000);
|
||||
assertNotNull(msg);
|
||||
}
|
||||
|
||||
public void xtestMessageDiscardedAdvisory() throws Exception {
|
||||
Session s = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
Topic topic = s.createTopic(getClass().getName());
|
||||
MessageConsumer consumer = s.createConsumer(topic);
|
||||
assertNotNull(consumer);
|
||||
|
||||
Topic advisoryTopic = AdvisorySupport.getMessageDiscardedAdvisoryTopic((ActiveMQDestination) topic);
|
||||
MessageConsumer advisoryConsumer = s.createConsumer(advisoryTopic);
|
||||
//start throwing messages at the consumer
|
||||
MessageProducer producer = s.createProducer(topic);
|
||||
int count = (new ActiveMQPrefetchPolicy().getTopicPrefetch() * 2);
|
||||
for (int i = 0; i < count; i++) {
|
||||
BytesMessage m = s.createBytesMessage();
|
||||
producer.send(m);
|
||||
}
|
||||
|
||||
Message msg = advisoryConsumer.receive(1000);
|
||||
assertNotNull(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
if (broker == null) {
|
||||
broker = createBroker();
|
||||
}
|
||||
ConnectionFactory factory = createConnectionFactory();
|
||||
connection = factory.createConnection();
|
||||
connection.start();
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
connection.close();
|
||||
if (broker != null) {
|
||||
broker.stop();
|
||||
}
|
||||
}
|
||||
|
||||
protected ActiveMQConnectionFactory createConnectionFactory() throws Exception {
|
||||
ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_BROKER_URL);
|
||||
return cf;
|
||||
}
|
||||
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerService answer = new BrokerService();
|
||||
configureBroker(answer);
|
||||
answer.start();
|
||||
return answer;
|
||||
}
|
||||
|
||||
protected void configureBroker(BrokerService answer) throws Exception {
|
||||
answer.setPersistent(false);
|
||||
PolicyEntry policy = new PolicyEntry();
|
||||
policy.setAdvisoryForFastProducers(true);
|
||||
policy.setAdvisoryForConsumed(true);
|
||||
policy.setAdvisoryForDelivery(true);
|
||||
policy.setAdvisoryForDiscardingMessages(true);
|
||||
policy.setAdvisoryForSlowConsumers(true);
|
||||
policy.setAdvisoryWhenFull(true);
|
||||
policy.setProducerFlowControl(false);
|
||||
ConstantPendingMessageLimitStrategy strategy = new ConstantPendingMessageLimitStrategy();
|
||||
strategy.setLimit(10);
|
||||
policy.setPendingMessageLimitStrategy(strategy);
|
||||
PolicyMap pMap = new PolicyMap();
|
||||
pMap.setDefaultEntry(policy);
|
||||
|
||||
answer.setDestinationPolicy(pMap);
|
||||
answer.addConnector(bindAddress);
|
||||
answer.setDeleteAllMessagesOnStartup(true);
|
||||
}
|
||||
}
|
|
@ -1,156 +0,0 @@
|
|||
/**
|
||||
* 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.advisory;
|
||||
|
||||
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.Session;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.activemq.EmbeddedBrokerTestSupport;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class ConsumerListenerTest extends EmbeddedBrokerTestSupport implements ConsumerListener {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ConsumerListenerTest.class);
|
||||
|
||||
protected Session consumerSession1;
|
||||
protected Session consumerSession2;
|
||||
protected int consumerCounter;
|
||||
protected ConsumerEventSource consumerEventSource;
|
||||
protected BlockingQueue<ConsumerEvent> eventQueue = new ArrayBlockingQueue<>(1000);
|
||||
private Connection connection;
|
||||
|
||||
public void testConsumerEvents() throws Exception {
|
||||
consumerEventSource.start();
|
||||
|
||||
consumerSession1 = createConsumer();
|
||||
assertConsumerEvent(1, true);
|
||||
|
||||
consumerSession2 = createConsumer();
|
||||
assertConsumerEvent(2, true);
|
||||
|
||||
consumerSession1.close();
|
||||
consumerSession1 = null;
|
||||
assertConsumerEvent(1, false);
|
||||
|
||||
consumerSession2.close();
|
||||
consumerSession2 = null;
|
||||
assertConsumerEvent(0, false);
|
||||
}
|
||||
|
||||
public void testListenWhileAlreadyConsumersActive() throws Exception {
|
||||
consumerSession1 = createConsumer();
|
||||
consumerSession2 = createConsumer();
|
||||
|
||||
consumerEventSource.start();
|
||||
assertConsumerEvent(2, true);
|
||||
assertConsumerEvent(2, true);
|
||||
|
||||
consumerSession1.close();
|
||||
consumerSession1 = null;
|
||||
assertConsumerEvent(1, false);
|
||||
|
||||
consumerSession2.close();
|
||||
consumerSession2 = null;
|
||||
assertConsumerEvent(0, false);
|
||||
}
|
||||
|
||||
public void testConsumerEventsOnTemporaryDestination() throws Exception {
|
||||
|
||||
Session s = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
|
||||
Destination dest = useTopic ? s.createTemporaryTopic() : s.createTemporaryQueue();
|
||||
consumerEventSource = new ConsumerEventSource(connection, dest);
|
||||
consumerEventSource.setConsumerListener(this);
|
||||
consumerEventSource.start();
|
||||
MessageConsumer consumer = s.createConsumer(dest);
|
||||
assertConsumerEvent(1, true);
|
||||
consumer.close();
|
||||
assertConsumerEvent(0, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConsumerEvent(ConsumerEvent event) {
|
||||
eventQueue.add(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
connection = createConnection();
|
||||
connection.start();
|
||||
consumerEventSource = new ConsumerEventSource(connection, destination);
|
||||
consumerEventSource.setConsumerListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
if (consumerEventSource != null) {
|
||||
consumerEventSource.stop();
|
||||
}
|
||||
if (consumerSession2 != null) {
|
||||
consumerSession2.close();
|
||||
}
|
||||
if (consumerSession1 != null) {
|
||||
consumerSession1.close();
|
||||
}
|
||||
if (connection != null) {
|
||||
connection.close();
|
||||
}
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
protected void assertConsumerEvent(int count, boolean started) throws InterruptedException {
|
||||
ConsumerEvent event = waitForConsumerEvent();
|
||||
assertEquals("Consumer count", count, event.getConsumerCount());
|
||||
assertEquals("started", started, event.isStarted());
|
||||
}
|
||||
|
||||
protected Session createConsumer() throws JMSException {
|
||||
final String consumerText = "Consumer: " + (++consumerCounter);
|
||||
LOG.info("Creating consumer: " + consumerText + " on destination: " + destination);
|
||||
|
||||
Session answer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
MessageConsumer consumer = answer.createConsumer(destination);
|
||||
consumer.setMessageListener(new MessageListener() {
|
||||
@Override
|
||||
public void onMessage(Message message) {
|
||||
LOG.info("Received message by: " + consumerText + " message: " + message);
|
||||
}
|
||||
});
|
||||
return answer;
|
||||
}
|
||||
|
||||
protected ConsumerEvent waitForConsumerEvent() throws InterruptedException {
|
||||
ConsumerEvent answer = eventQueue.poll(100000, TimeUnit.MILLISECONDS);
|
||||
assertTrue("Should have received a consumer event!", answer != null);
|
||||
return answer;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,129 +0,0 @@
|
|||
/**
|
||||
* 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.advisory;
|
||||
|
||||
import javax.jms.MessageProducer;
|
||||
import javax.jms.Session;
|
||||
import javax.jms.TextMessage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnection;
|
||||
import org.apache.activemq.EmbeddedBrokerTestSupport;
|
||||
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.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.isIn;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class DestinationListenerTest extends EmbeddedBrokerTestSupport implements DestinationListener {
|
||||
|
||||
private static final transient Logger LOG = LoggerFactory.getLogger(DestinationListenerTest.class);
|
||||
protected ActiveMQConnection connection;
|
||||
protected ActiveMQQueue sampleQueue = new ActiveMQQueue("foo.bar");
|
||||
protected ActiveMQTopic sampleTopic = new ActiveMQTopic("cheese");
|
||||
protected List<ActiveMQDestination> newDestinations = new ArrayList<>();
|
||||
|
||||
public void testDestiationSourceHasInitialDestinations() throws Exception {
|
||||
Thread.sleep(1000);
|
||||
|
||||
DestinationSource destinationSource = connection.getDestinationSource();
|
||||
Set<ActiveMQQueue> queues = destinationSource.getQueues();
|
||||
Set<ActiveMQTopic> topics = destinationSource.getTopics();
|
||||
|
||||
LOG.info("Queues: " + queues);
|
||||
LOG.info("Topics: " + topics);
|
||||
|
||||
assertTrue("The queues should not be empty!", !queues.isEmpty());
|
||||
assertTrue("The topics should not be empty!", !topics.isEmpty());
|
||||
|
||||
assertTrue("queues contains initial queue: " + queues, queues.contains(sampleQueue));
|
||||
assertTrue("topics contains initial topic: " + queues, topics.contains(sampleTopic));
|
||||
}
|
||||
|
||||
public void testConsumerForcesNotificationOfNewDestination() throws Exception {
|
||||
// now lets cause a destination to be created
|
||||
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
ActiveMQQueue newQueue = new ActiveMQQueue("Test.Cheese");
|
||||
session.createConsumer(newQueue);
|
||||
|
||||
Thread.sleep(3000);
|
||||
|
||||
assertThat(newQueue, isIn(newDestinations));
|
||||
|
||||
LOG.info("New destinations are: " + newDestinations);
|
||||
}
|
||||
|
||||
public void testProducerForcesNotificationOfNewDestination() throws Exception {
|
||||
// now lets cause a destination to be created
|
||||
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
ActiveMQQueue newQueue = new ActiveMQQueue("Test.Beer");
|
||||
MessageProducer producer = session.createProducer(newQueue);
|
||||
TextMessage message = session.createTextMessage("<hello>world</hello>");
|
||||
producer.send(message);
|
||||
|
||||
Thread.sleep(3000);
|
||||
|
||||
assertThat(newQueue, isIn(newDestinations));
|
||||
|
||||
LOG.info("New destinations are: " + newDestinations);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestinationEvent(DestinationEvent event) {
|
||||
ActiveMQDestination destination = event.getDestination();
|
||||
if (event.isAddOperation()) {
|
||||
LOG.info("Added: " + destination);
|
||||
newDestinations.add(destination);
|
||||
} else {
|
||||
LOG.info("Removed: " + destination);
|
||||
newDestinations.remove(destination);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
connection = (ActiveMQConnection) createConnection();
|
||||
connection.start();
|
||||
connection.getDestinationSource().setDestinationListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerService broker = super.createBroker();
|
||||
broker.setDestinations(new ActiveMQDestination[]{sampleQueue, sampleTopic});
|
||||
return broker;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
if (connection != null) {
|
||||
connection.close();
|
||||
}
|
||||
super.tearDown();
|
||||
}
|
||||
}
|
|
@ -1,150 +0,0 @@
|
|||
/**
|
||||
* 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.advisory;
|
||||
|
||||
import javax.jms.Connection;
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.MessageProducer;
|
||||
import javax.jms.Session;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.activemq.EmbeddedBrokerTestSupport;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class ProducerListenerTest extends EmbeddedBrokerTestSupport implements ProducerListener {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ProducerListenerTest.class);
|
||||
|
||||
protected Session consumerSession1;
|
||||
protected Session consumerSession2;
|
||||
protected int consumerCounter;
|
||||
protected ProducerEventSource producerEventSource;
|
||||
protected BlockingQueue<ProducerEvent> eventQueue = new ArrayBlockingQueue<>(1000);
|
||||
private Connection connection;
|
||||
|
||||
public void testProducerEvents() throws Exception {
|
||||
producerEventSource.start();
|
||||
|
||||
consumerSession1 = createProducer();
|
||||
assertProducerEvent(1, true);
|
||||
|
||||
consumerSession2 = createProducer();
|
||||
assertProducerEvent(2, true);
|
||||
|
||||
consumerSession1.close();
|
||||
consumerSession1 = null;
|
||||
assertProducerEvent(1, false);
|
||||
|
||||
consumerSession2.close();
|
||||
consumerSession2 = null;
|
||||
assertProducerEvent(0, false);
|
||||
}
|
||||
|
||||
public void testListenWhileAlreadyConsumersActive() throws Exception {
|
||||
consumerSession1 = createProducer();
|
||||
consumerSession2 = createProducer();
|
||||
|
||||
producerEventSource.start();
|
||||
assertProducerEvent(2, true);
|
||||
assertProducerEvent(2, true);
|
||||
|
||||
consumerSession1.close();
|
||||
consumerSession1 = null;
|
||||
assertProducerEvent(1, false);
|
||||
|
||||
consumerSession2.close();
|
||||
consumerSession2 = null;
|
||||
assertProducerEvent(0, false);
|
||||
}
|
||||
|
||||
public void testConsumerEventsOnTemporaryDestination() throws Exception {
|
||||
|
||||
Session s = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
|
||||
Destination dest = useTopic ? s.createTemporaryTopic() : s.createTemporaryQueue();
|
||||
producerEventSource = new ProducerEventSource(connection, dest);
|
||||
producerEventSource.setProducerListener(this);
|
||||
producerEventSource.start();
|
||||
MessageProducer producer = s.createProducer(dest);
|
||||
assertProducerEvent(1, true);
|
||||
producer.close();
|
||||
assertProducerEvent(0, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProducerEvent(ProducerEvent event) {
|
||||
eventQueue.add(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
connection = createConnection();
|
||||
connection.start();
|
||||
producerEventSource = new ProducerEventSource(connection, destination);
|
||||
producerEventSource.setProducerListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
if (producerEventSource != null) {
|
||||
producerEventSource.stop();
|
||||
}
|
||||
if (consumerSession2 != null) {
|
||||
consumerSession2.close();
|
||||
}
|
||||
if (consumerSession1 != null) {
|
||||
consumerSession1.close();
|
||||
}
|
||||
if (connection != null) {
|
||||
connection.close();
|
||||
}
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
protected void assertProducerEvent(int count, boolean started) throws InterruptedException {
|
||||
ProducerEvent event = waitForProducerEvent();
|
||||
assertEquals("Producer count", count, event.getProducerCount());
|
||||
assertEquals("started", started, event.isStarted());
|
||||
}
|
||||
|
||||
protected Session createProducer() throws JMSException {
|
||||
final String consumerText = "Consumer: " + (++consumerCounter);
|
||||
LOG.info("Creating consumer: " + consumerText + " on destination: " + destination);
|
||||
|
||||
Session answer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
MessageProducer producer = answer.createProducer(destination);
|
||||
assertNotNull(producer);
|
||||
|
||||
return answer;
|
||||
}
|
||||
|
||||
protected ProducerEvent waitForProducerEvent() throws InterruptedException {
|
||||
ProducerEvent answer = eventQueue.poll(100000, TimeUnit.MILLISECONDS);
|
||||
assertTrue("Should have received a consumer event!", answer != null);
|
||||
return answer;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,152 +0,0 @@
|
|||
/**
|
||||
* 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.advisory;
|
||||
|
||||
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.Session;
|
||||
import javax.jms.Topic;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.activemq.EmbeddedBrokerTestSupport;
|
||||
import org.apache.activemq.broker.region.RegionBroker;
|
||||
import org.apache.activemq.command.ActiveMQTempQueue;
|
||||
import org.apache.activemq.command.ActiveMQTempTopic;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class TempDestDeleteTest extends EmbeddedBrokerTestSupport implements ConsumerListener {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TempDestDeleteTest.class);
|
||||
|
||||
protected int consumerCounter;
|
||||
protected ConsumerEventSource topicConsumerEventSource;
|
||||
protected BlockingQueue<ConsumerEvent> eventQueue = new ArrayBlockingQueue<>(1000);
|
||||
|
||||
private ConsumerEventSource queueConsumerEventSource;
|
||||
private Connection connection;
|
||||
private Session session;
|
||||
private ActiveMQTempTopic tempTopic;
|
||||
private ActiveMQTempQueue tempQueue;
|
||||
|
||||
public void testDeleteTempTopicDeletesAvisoryTopics() throws Exception {
|
||||
topicConsumerEventSource.start();
|
||||
|
||||
MessageConsumer consumer = createConsumer(tempTopic);
|
||||
assertConsumerEvent(1, true);
|
||||
|
||||
Topic advisoryTopic = AdvisorySupport.getConsumerAdvisoryTopic(tempTopic);
|
||||
assertTrue(destinationExists(advisoryTopic));
|
||||
|
||||
consumer.close();
|
||||
|
||||
// Once we delete the topic, the advisory topic for the destination
|
||||
// should also be deleted.
|
||||
tempTopic.delete();
|
||||
|
||||
assertFalse(destinationExists(advisoryTopic));
|
||||
}
|
||||
|
||||
public void testDeleteTempQueueDeletesAvisoryTopics() throws Exception {
|
||||
queueConsumerEventSource.start();
|
||||
|
||||
MessageConsumer consumer = createConsumer(tempQueue);
|
||||
assertConsumerEvent(1, true);
|
||||
|
||||
Topic advisoryTopic = AdvisorySupport.getConsumerAdvisoryTopic(tempQueue);
|
||||
assertTrue(destinationExists(advisoryTopic));
|
||||
|
||||
consumer.close();
|
||||
|
||||
// Once we delete the queue, the advisory topic for the destination
|
||||
// should also be deleted.
|
||||
tempQueue.delete();
|
||||
|
||||
assertFalse(destinationExists(advisoryTopic));
|
||||
}
|
||||
|
||||
private boolean destinationExists(Destination dest) throws Exception {
|
||||
RegionBroker rb = (RegionBroker) broker.getBroker().getAdaptor(RegionBroker.class);
|
||||
return rb.getTopicRegion().getDestinationMap().containsKey(dest) || rb.getQueueRegion().getDestinationMap().containsKey(dest) || rb.getTempTopicRegion().getDestinationMap().containsKey(dest) || rb.getTempQueueRegion().getDestinationMap().containsKey(dest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConsumerEvent(ConsumerEvent event) {
|
||||
eventQueue.add(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
connection = createConnection();
|
||||
connection.start();
|
||||
|
||||
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
|
||||
tempTopic = (ActiveMQTempTopic) session.createTemporaryTopic();
|
||||
topicConsumerEventSource = new ConsumerEventSource(connection, tempTopic);
|
||||
topicConsumerEventSource.setConsumerListener(this);
|
||||
|
||||
tempQueue = (ActiveMQTempQueue) session.createTemporaryQueue();
|
||||
queueConsumerEventSource = new ConsumerEventSource(connection, tempQueue);
|
||||
queueConsumerEventSource.setConsumerListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
if (connection != null) {
|
||||
connection.close();
|
||||
}
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
protected void assertConsumerEvent(int count, boolean started) throws InterruptedException {
|
||||
ConsumerEvent event = waitForConsumerEvent();
|
||||
assertEquals("Consumer count", count, event.getConsumerCount());
|
||||
assertEquals("started", started, event.isStarted());
|
||||
}
|
||||
|
||||
protected MessageConsumer createConsumer(Destination dest) throws JMSException {
|
||||
final String consumerText = "Consumer: " + (++consumerCounter);
|
||||
LOG.info("Creating consumer: " + consumerText + " on destination: " + dest);
|
||||
|
||||
MessageConsumer consumer = session.createConsumer(dest);
|
||||
consumer.setMessageListener(new MessageListener() {
|
||||
@Override
|
||||
public void onMessage(Message message) {
|
||||
LOG.info("Received message by: " + consumerText + " message: " + message);
|
||||
}
|
||||
});
|
||||
return consumer;
|
||||
}
|
||||
|
||||
protected ConsumerEvent waitForConsumerEvent() throws InterruptedException {
|
||||
ConsumerEvent answer = eventQueue.poll(1000, TimeUnit.MILLISECONDS);
|
||||
assertTrue("Should have received a consumer event!", answer != null);
|
||||
return answer;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
/**
|
||||
* 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.advisory;
|
||||
|
||||
import javax.jms.Connection;
|
||||
import javax.jms.MessageConsumer;
|
||||
import javax.jms.MessageProducer;
|
||||
import javax.jms.Session;
|
||||
import javax.jms.TemporaryQueue;
|
||||
import javax.jms.TemporaryTopic;
|
||||
|
||||
import org.apache.activemq.EmbeddedBrokerTestSupport;
|
||||
import org.apache.activemq.broker.region.Destination;
|
||||
import org.apache.activemq.broker.region.RegionBroker;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class TempDestLoadTest extends EmbeddedBrokerTestSupport {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TempDestLoadTest.class);
|
||||
|
||||
protected int consumerCounter;
|
||||
private Connection connection;
|
||||
private Session session;
|
||||
private static final int MESSAGE_COUNT = 2000;
|
||||
|
||||
public void testLoadTempAdvisoryQueues() throws Exception {
|
||||
|
||||
for (int i = 0; i < MESSAGE_COUNT; i++) {
|
||||
TemporaryQueue tempQueue = session.createTemporaryQueue();
|
||||
MessageConsumer consumer = session.createConsumer(tempQueue);
|
||||
MessageProducer producer = session.createProducer(tempQueue);
|
||||
consumer.close();
|
||||
producer.close();
|
||||
tempQueue.delete();
|
||||
}
|
||||
|
||||
AdvisoryBroker ab = (AdvisoryBroker) broker.getBroker().getAdaptor(AdvisoryBroker.class);
|
||||
|
||||
assertTrue(ab.getAdvisoryDestinations().size() == 0);
|
||||
assertTrue(ab.getAdvisoryConsumers().size() == 0);
|
||||
assertTrue(ab.getAdvisoryProducers().size() == 0);
|
||||
|
||||
RegionBroker rb = (RegionBroker) broker.getBroker().getAdaptor(RegionBroker.class);
|
||||
|
||||
for (Destination dest : rb.getDestinationMap().values()) {
|
||||
LOG.debug("Destination: {}", dest);
|
||||
}
|
||||
|
||||
// there should be at least 2 destinations - advisories -
|
||||
// 1 for the connection + 1 generic ones
|
||||
assertTrue("Should be at least 2 destinations", rb.getDestinationMap().size() > 2);
|
||||
}
|
||||
|
||||
public void testLoadTempAdvisoryTopics() throws Exception {
|
||||
for (int i = 0; i < MESSAGE_COUNT; i++) {
|
||||
TemporaryTopic tempTopic = session.createTemporaryTopic();
|
||||
MessageConsumer consumer = session.createConsumer(tempTopic);
|
||||
MessageProducer producer = session.createProducer(tempTopic);
|
||||
consumer.close();
|
||||
producer.close();
|
||||
tempTopic.delete();
|
||||
}
|
||||
|
||||
AdvisoryBroker ab = (AdvisoryBroker) broker.getBroker().getAdaptor(AdvisoryBroker.class);
|
||||
assertTrue(ab.getAdvisoryDestinations().size() == 0);
|
||||
assertTrue(ab.getAdvisoryConsumers().size() == 0);
|
||||
assertTrue(ab.getAdvisoryProducers().size() == 0);
|
||||
RegionBroker rb = (RegionBroker) broker.getBroker().getAdaptor(RegionBroker.class);
|
||||
|
||||
for (Destination dest : rb.getDestinationMap().values()) {
|
||||
LOG.debug("Destination: {}", dest);
|
||||
}
|
||||
|
||||
// there should be at least 2 destinations - advisories -
|
||||
// 1 for the connection + 1 generic ones
|
||||
assertTrue("Should be at least 2 destinations", rb.getDestinationMap().size() > 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
connection = createConnection();
|
||||
connection.start();
|
||||
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
if (connection != null) {
|
||||
connection.close();
|
||||
}
|
||||
super.tearDown();
|
||||
}
|
||||
}
|
|
@ -1,170 +0,0 @@
|
|||
/**
|
||||
* 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.advisory;
|
||||
|
||||
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 java.util.Vector;
|
||||
|
||||
import org.apache.activemq.EmbeddedBrokerTestSupport;
|
||||
import org.apache.activemq.broker.region.RegionBroker;
|
||||
import org.apache.activemq.command.ActiveMQDestination;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
|
||||
public class TempQueueMemoryTest extends EmbeddedBrokerTestSupport {
|
||||
|
||||
protected Connection serverConnection;
|
||||
protected Session serverSession;
|
||||
protected Connection clientConnection;
|
||||
protected Session clientSession;
|
||||
protected Destination serverDestination;
|
||||
protected int messagesToSend = 10;
|
||||
protected boolean deleteTempQueue = true;
|
||||
protected boolean serverTransactional = false;
|
||||
protected boolean clientTransactional = false;
|
||||
protected int numConsumers = 1;
|
||||
protected int numProducers = 1;
|
||||
|
||||
public void testConcurrentProducerRequestReply() throws Exception {
|
||||
numProducers = 10;
|
||||
testLoadRequestReply();
|
||||
}
|
||||
|
||||
public void testLoadRequestReply() throws Exception {
|
||||
for (int i = 0; i < numConsumers; i++) {
|
||||
serverSession.createConsumer(serverDestination).setMessageListener(new MessageListener() {
|
||||
@Override
|
||||
public void onMessage(Message msg) {
|
||||
try {
|
||||
Destination replyTo = msg.getJMSReplyTo();
|
||||
MessageProducer producer = serverSession.createProducer(replyTo);
|
||||
producer.send(replyTo, msg);
|
||||
if (serverTransactional) {
|
||||
serverSession.commit();
|
||||
}
|
||||
producer.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
class Producer extends Thread {
|
||||
|
||||
private final int numToSend;
|
||||
|
||||
public Producer(int numToSend) {
|
||||
this.numToSend = numToSend;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Session session = clientConnection.createSession(clientTransactional, clientTransactional ? Session.SESSION_TRANSACTED : Session.AUTO_ACKNOWLEDGE);
|
||||
MessageProducer producer = session.createProducer(serverDestination);
|
||||
|
||||
for (int i = 0; i < numToSend; i++) {
|
||||
TemporaryQueue replyTo = session.createTemporaryQueue();
|
||||
MessageConsumer consumer = session.createConsumer(replyTo);
|
||||
Message msg = session.createMessage();
|
||||
msg.setJMSReplyTo(replyTo);
|
||||
producer.send(msg);
|
||||
if (clientTransactional) {
|
||||
session.commit();
|
||||
}
|
||||
consumer.receive();
|
||||
if (clientTransactional) {
|
||||
session.commit();
|
||||
}
|
||||
consumer.close();
|
||||
if (deleteTempQueue) {
|
||||
replyTo.delete();
|
||||
} else {
|
||||
// temp queue will be cleaned up on clientConnection.close
|
||||
}
|
||||
}
|
||||
} catch (JMSException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
Vector<Thread> threads = new Vector<>(numProducers);
|
||||
for (int i = 0; i < numProducers; i++) {
|
||||
threads.add(new Producer(messagesToSend / numProducers));
|
||||
}
|
||||
startAndJoinThreads(threads);
|
||||
|
||||
clientSession.close();
|
||||
serverSession.close();
|
||||
clientConnection.close();
|
||||
serverConnection.close();
|
||||
|
||||
AdvisoryBroker ab = (AdvisoryBroker) broker.getBroker().getAdaptor(AdvisoryBroker.class);
|
||||
|
||||
// The server destination will be left
|
||||
assertTrue(ab.getAdvisoryDestinations().size() == 1);
|
||||
|
||||
assertTrue("should be zero but is " + ab.getAdvisoryConsumers().size(), ab.getAdvisoryConsumers().size() == 0);
|
||||
assertTrue("should be zero but is " + ab.getAdvisoryProducers().size(), ab.getAdvisoryProducers().size() == 0);
|
||||
|
||||
RegionBroker rb = (RegionBroker) broker.getBroker().getAdaptor(RegionBroker.class);
|
||||
|
||||
assertTrue(rb.getDestinationMap().size() >= 6);
|
||||
}
|
||||
|
||||
private void startAndJoinThreads(Vector<Thread> threads) throws Exception {
|
||||
for (Thread thread : threads) {
|
||||
thread.start();
|
||||
}
|
||||
for (Thread thread : threads) {
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
serverConnection = createConnection();
|
||||
serverConnection.start();
|
||||
serverSession = serverConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
clientConnection = createConnection();
|
||||
clientConnection.start();
|
||||
clientSession = clientConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
serverDestination = createDestination();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
serverTransactional = clientTransactional = false;
|
||||
numConsumers = numProducers = 1;
|
||||
messagesToSend = 2000;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ActiveMQDestination createDestination() {
|
||||
return new ActiveMQQueue(getClass().getName());
|
||||
}
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
/**
|
||||
* 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.blob;
|
||||
|
||||
import javax.jms.JMSException;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.apache.activemq.command.ActiveMQBlobMessage;
|
||||
|
||||
public class FTPBlobDownloadStrategyTest extends FTPTestSupport {
|
||||
|
||||
final int FILE_SIZE = Short.MAX_VALUE * 10;
|
||||
|
||||
public void testDownload() throws Exception {
|
||||
setConnection();
|
||||
|
||||
// create file
|
||||
File uploadFile = new File(ftpHomeDirFile, "test.txt");
|
||||
FileWriter wrt = new FileWriter(uploadFile);
|
||||
|
||||
wrt.write("hello world");
|
||||
|
||||
for (int ix = 0; ix < FILE_SIZE; ++ix) {
|
||||
wrt.write("a");
|
||||
}
|
||||
|
||||
wrt.close();
|
||||
|
||||
ActiveMQBlobMessage message = new ActiveMQBlobMessage();
|
||||
BlobDownloadStrategy strategy = new FTPBlobDownloadStrategy(new BlobTransferPolicy());
|
||||
InputStream stream;
|
||||
try {
|
||||
message.setURL(new URL(ftpUrl + "test.txt"));
|
||||
stream = strategy.getInputStream(message);
|
||||
int i = stream.read();
|
||||
StringBuilder sb = new StringBuilder(2048);
|
||||
while (i != -1) {
|
||||
sb.append((char) i);
|
||||
i = stream.read();
|
||||
}
|
||||
assertEquals("hello world", sb.toString().substring(0, "hello world".length()));
|
||||
assertEquals(FILE_SIZE, sb.toString().substring("hello world".length()).length());
|
||||
|
||||
assertTrue(uploadFile.exists());
|
||||
strategy.deleteFile(message);
|
||||
assertFalse(uploadFile.exists());
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
assertTrue(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void testWrongAuthentification() throws MalformedURLException {
|
||||
ActiveMQBlobMessage message = new ActiveMQBlobMessage();
|
||||
BlobDownloadStrategy strategy = new FTPBlobDownloadStrategy(new BlobTransferPolicy());
|
||||
try {
|
||||
message.setURL(new URL("ftp://" + userNamePass + "_wrong:" + userNamePass + "@localhost:" + ftpPort + "/ftptest/"));
|
||||
strategy.getInputStream(message);
|
||||
} catch (JMSException e) {
|
||||
assertEquals("Wrong Exception", "Cant Authentificate to FTP-Server", e.getMessage());
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
System.out.println(e);
|
||||
assertTrue("Wrong Exception " + e, false);
|
||||
return;
|
||||
}
|
||||
|
||||
assertTrue("Expect Exception", false);
|
||||
}
|
||||
|
||||
public void testWrongFTPPort() throws MalformedURLException {
|
||||
ActiveMQBlobMessage message = new ActiveMQBlobMessage();
|
||||
BlobDownloadStrategy strategy = new FTPBlobDownloadStrategy(new BlobTransferPolicy());
|
||||
try {
|
||||
message.setURL(new URL("ftp://" + userNamePass + ":" + userNamePass + "@localhost:" + 422 + "/ftptest/"));
|
||||
strategy.getInputStream(message);
|
||||
} catch (JMSException e) {
|
||||
assertEquals("Wrong Exception", "Problem connecting the FTP-server", e.getMessage());
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
assertTrue("Wrong Exception " + e, false);
|
||||
return;
|
||||
}
|
||||
|
||||
assertTrue("Expect Exception", false);
|
||||
}
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
/**
|
||||
* 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.blob;
|
||||
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageConsumer;
|
||||
import javax.jms.MessageProducer;
|
||||
import javax.jms.Session;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.activemq.ActiveMQSession;
|
||||
import org.apache.activemq.BlobMessage;
|
||||
import org.apache.activemq.command.ActiveMQBlobMessage;
|
||||
|
||||
public class FTPBlobTest extends FTPTestSupport {
|
||||
|
||||
public void testBlobFile() throws Exception {
|
||||
setConnection();
|
||||
// first create Message
|
||||
File file = File.createTempFile("amq-data-file-", ".dat");
|
||||
// lets write some data
|
||||
String content = "hello world " + System.currentTimeMillis();
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
|
||||
writer.append(content);
|
||||
writer.close();
|
||||
|
||||
ActiveMQSession session = (ActiveMQSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
MessageProducer producer = session.createProducer(destination);
|
||||
MessageConsumer consumer = session.createConsumer(destination);
|
||||
BlobMessage message = session.createBlobMessage(file);
|
||||
message.setName("fileName");
|
||||
|
||||
producer.send(message);
|
||||
Thread.sleep(1000);
|
||||
|
||||
// check message send
|
||||
Message msg = consumer.receive(1000);
|
||||
assertTrue(msg instanceof ActiveMQBlobMessage);
|
||||
|
||||
assertEquals("name is correct", "fileName", ((ActiveMQBlobMessage) msg).getName());
|
||||
InputStream input = ((ActiveMQBlobMessage) msg).getInputStream();
|
||||
StringBuilder b = new StringBuilder();
|
||||
int i = input.read();
|
||||
while (i != -1) {
|
||||
b.append((char) i);
|
||||
i = input.read();
|
||||
}
|
||||
input.close();
|
||||
File uploaded = new File(ftpHomeDirFile, msg.getJMSMessageID().toString().replace(":", "_"));
|
||||
assertEquals(content, b.toString());
|
||||
assertTrue(uploaded.exists());
|
||||
((ActiveMQBlobMessage) msg).deleteFile();
|
||||
assertFalse(uploaded.exists());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
/**
|
||||
* 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.blob;
|
||||
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Session;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnection;
|
||||
import org.apache.activemq.ActiveMQSession;
|
||||
import org.apache.activemq.command.ActiveMQBlobMessage;
|
||||
|
||||
public class FTPBlobUploadStrategyTest extends FTPTestSupport {
|
||||
|
||||
public void testFileUpload() throws Exception {
|
||||
setConnection();
|
||||
File file = File.createTempFile("amq-data-file-", ".dat");
|
||||
// lets write some data
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
|
||||
writer.append("hello world");
|
||||
writer.close();
|
||||
|
||||
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
((ActiveMQConnection) connection).setCopyMessageOnSend(false);
|
||||
|
||||
ActiveMQBlobMessage message = (ActiveMQBlobMessage) ((ActiveMQSession) session).createBlobMessage(file);
|
||||
message.setJMSMessageID("testmessage");
|
||||
message.onSend();
|
||||
assertEquals(ftpUrl + "ID_testmessage", message.getURL().toString());
|
||||
File uploaded = new File(ftpHomeDirFile, "ID_testmessage");
|
||||
assertTrue("File doesn't exists", uploaded.exists());
|
||||
}
|
||||
|
||||
public void testWriteDenied() throws Exception {
|
||||
userNamePass = "guest";
|
||||
setConnection();
|
||||
File file = File.createTempFile("amq-data-file-", ".dat");
|
||||
// lets write some data
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
|
||||
writer.append("hello world");
|
||||
writer.close();
|
||||
|
||||
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
((ActiveMQConnection) connection).setCopyMessageOnSend(false);
|
||||
|
||||
ActiveMQBlobMessage message = (ActiveMQBlobMessage) ((ActiveMQSession) session).createBlobMessage(file);
|
||||
message.setJMSMessageID("testmessage");
|
||||
try {
|
||||
message.onSend();
|
||||
} catch (JMSException e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
fail("Should have failed with permission denied exception!");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
/**
|
||||
* 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.blob;
|
||||
|
||||
import javax.jms.Connection;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.activemq.EmbeddedBrokerTestSupport;
|
||||
import org.apache.activemq.util.IOHelper;
|
||||
import org.apache.ftpserver.FtpServer;
|
||||
import org.apache.ftpserver.FtpServerFactory;
|
||||
import org.apache.ftpserver.ftplet.Authority;
|
||||
import org.apache.ftpserver.ftplet.UserManager;
|
||||
import org.apache.ftpserver.listener.ListenerFactory;
|
||||
import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
|
||||
import org.apache.ftpserver.usermanager.impl.BaseUser;
|
||||
import org.apache.ftpserver.usermanager.impl.WritePermission;
|
||||
import org.jmock.Mockery;
|
||||
|
||||
public abstract class FTPTestSupport extends EmbeddedBrokerTestSupport {
|
||||
|
||||
protected static final String ftpServerListenerName = "default";
|
||||
protected Connection connection;
|
||||
protected FtpServer server;
|
||||
String userNamePass = "activemq";
|
||||
|
||||
Mockery context = null;
|
||||
String ftpUrl;
|
||||
int ftpPort;
|
||||
|
||||
final File ftpHomeDirFile = new File("target/FTPBlobTest/ftptest");
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
|
||||
if (ftpHomeDirFile.getParentFile().exists()) {
|
||||
IOHelper.deleteFile(ftpHomeDirFile.getParentFile());
|
||||
}
|
||||
ftpHomeDirFile.mkdirs();
|
||||
ftpHomeDirFile.getParentFile().deleteOnExit();
|
||||
|
||||
FtpServerFactory serverFactory = new FtpServerFactory();
|
||||
ListenerFactory factory = new ListenerFactory();
|
||||
|
||||
PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
|
||||
UserManager userManager = userManagerFactory.createUserManager();
|
||||
|
||||
BaseUser user = new BaseUser();
|
||||
user.setName("activemq");
|
||||
user.setPassword("activemq");
|
||||
user.setHomeDirectory(ftpHomeDirFile.getParent());
|
||||
|
||||
// authorize user
|
||||
List<Authority> auths = new ArrayList<>();
|
||||
Authority auth = new WritePermission();
|
||||
auths.add(auth);
|
||||
user.setAuthorities(auths);
|
||||
|
||||
userManager.save(user);
|
||||
|
||||
BaseUser guest = new BaseUser();
|
||||
guest.setName("guest");
|
||||
guest.setPassword("guest");
|
||||
guest.setHomeDirectory(ftpHomeDirFile.getParent());
|
||||
|
||||
userManager.save(guest);
|
||||
|
||||
serverFactory.setUserManager(userManager);
|
||||
factory.setPort(0);
|
||||
serverFactory.addListener(ftpServerListenerName, factory.createListener());
|
||||
server = serverFactory.createServer();
|
||||
server.start();
|
||||
ftpPort = serverFactory.getListener(ftpServerListenerName).getPort();
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public void setConnection() throws Exception {
|
||||
ftpUrl = "ftp://" + userNamePass + ":" + userNamePass + "@localhost:" + ftpPort + "/ftptest/";
|
||||
bindAddress = "vm://localhost?jms.blobTransferPolicy.defaultUploadUrl=" + ftpUrl;
|
||||
|
||||
connectionFactory = createConnectionFactory();
|
||||
|
||||
connection = createConnection();
|
||||
connection.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
if (connection != null) {
|
||||
connection.stop();
|
||||
}
|
||||
super.tearDown();
|
||||
if (server != null) {
|
||||
server.stop();
|
||||
}
|
||||
IOHelper.deleteFile(ftpHomeDirFile.getParentFile());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
/**
|
||||
* 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.blob;
|
||||
|
||||
import javax.jms.Connection;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageConsumer;
|
||||
import javax.jms.MessageProducer;
|
||||
import javax.jms.Session;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.activemq.ActiveMQSession;
|
||||
import org.apache.activemq.BlobMessage;
|
||||
import org.apache.activemq.EmbeddedBrokerTestSupport;
|
||||
import org.apache.activemq.command.ActiveMQBlobMessage;
|
||||
import org.apache.activemq.util.IOHelper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class FilesystemBlobTest extends EmbeddedBrokerTestSupport {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(FilesystemBlobTest.class);
|
||||
|
||||
private Connection connection;
|
||||
private final String tmpDir = System.getProperty("user.dir") + "/target/FilesystemBlobTest";
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
// replace \ with / to let it work on windows too
|
||||
String fileUrl = "file:///" + tmpDir.replaceAll("\\\\", "/");
|
||||
LOG.info("Using file: " + fileUrl);
|
||||
bindAddress = "vm://localhost?jms.blobTransferPolicy.defaultUploadUrl=" + fileUrl;
|
||||
|
||||
connectionFactory = createConnectionFactory();
|
||||
|
||||
connection = createConnection();
|
||||
connection.start();
|
||||
}
|
||||
|
||||
public void testBlobFile() throws Exception {
|
||||
// first create Message
|
||||
File file = File.createTempFile("amq-data-file-", ".dat");
|
||||
// lets write some data
|
||||
String content = "hello world " + System.currentTimeMillis();
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
|
||||
writer.append(content);
|
||||
writer.close();
|
||||
|
||||
ActiveMQSession session = (ActiveMQSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
MessageProducer producer = session.createProducer(destination);
|
||||
MessageConsumer consumer = session.createConsumer(destination);
|
||||
BlobMessage message = session.createBlobMessage(file);
|
||||
|
||||
producer.send(message);
|
||||
Thread.sleep(1000);
|
||||
|
||||
// check message send
|
||||
Message msg = consumer.receive(1000);
|
||||
assertTrue(msg instanceof ActiveMQBlobMessage);
|
||||
|
||||
InputStream input = ((ActiveMQBlobMessage) msg).getInputStream();
|
||||
StringBuilder b = new StringBuilder();
|
||||
int i = input.read();
|
||||
while (i != -1) {
|
||||
b.append((char) i);
|
||||
i = input.read();
|
||||
}
|
||||
input.close();
|
||||
File uploaded = new File(tmpDir, msg.getJMSMessageID().toString().replace(":", "_"));
|
||||
assertEquals(content, b.toString());
|
||||
assertTrue(uploaded.exists());
|
||||
((ActiveMQBlobMessage) msg).deleteFile();
|
||||
assertFalse(uploaded.exists());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
if (connection != null) {
|
||||
connection.stop();
|
||||
}
|
||||
super.tearDown();
|
||||
|
||||
IOHelper.deleteFile(new File(tmpDir));
|
||||
}
|
||||
}
|
|
@ -1,184 +0,0 @@
|
|||
/**
|
||||
* 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 javax.jms.Message;
|
||||
import javax.jms.MessageConsumer;
|
||||
import javax.jms.MessageProducer;
|
||||
import javax.jms.Session;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnection;
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.RedeliveryPolicy;
|
||||
import org.apache.activemq.broker.region.policy.RedeliveryPolicyMap;
|
||||
import org.apache.activemq.broker.region.policy.SharedDeadLetterStrategy;
|
||||
import org.apache.activemq.broker.util.RedeliveryPlugin;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class BrokerRedeliveryTest extends org.apache.activemq.TestSupport {
|
||||
|
||||
static final Logger LOG = LoggerFactory.getLogger(BrokerRedeliveryTest.class);
|
||||
BrokerService broker = null;
|
||||
|
||||
final ActiveMQQueue destination = new ActiveMQQueue("Redelivery");
|
||||
final String data = "hi";
|
||||
final long redeliveryDelayMillis = 2000;
|
||||
long initialRedeliveryDelayMillis = 4000;
|
||||
int maxBrokerRedeliveries = 2;
|
||||
|
||||
public void testScheduledRedelivery() throws Exception {
|
||||
doTestScheduledRedelivery(maxBrokerRedeliveries, true);
|
||||
}
|
||||
|
||||
public void testInfiniteRedelivery() throws Exception {
|
||||
initialRedeliveryDelayMillis = redeliveryDelayMillis;
|
||||
maxBrokerRedeliveries = RedeliveryPolicy.NO_MAXIMUM_REDELIVERIES;
|
||||
doTestScheduledRedelivery(RedeliveryPolicy.DEFAULT_MAXIMUM_REDELIVERIES + 1, false);
|
||||
}
|
||||
|
||||
public void doTestScheduledRedelivery(int maxBrokerRedeliveriesToValidate, boolean validateDLQ) throws Exception {
|
||||
|
||||
startBroker(true);
|
||||
sendMessage(0);
|
||||
|
||||
ActiveMQConnection consumerConnection = (ActiveMQConnection) createConnection();
|
||||
RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
|
||||
redeliveryPolicy.setInitialRedeliveryDelay(0);
|
||||
redeliveryPolicy.setMaximumRedeliveries(0);
|
||||
consumerConnection.setRedeliveryPolicy(redeliveryPolicy);
|
||||
consumerConnection.start();
|
||||
Session consumerSession = consumerConnection.createSession(true, Session.SESSION_TRANSACTED);
|
||||
MessageConsumer consumer = consumerSession.createConsumer(destination);
|
||||
Message message = consumer.receive(1000);
|
||||
assertNotNull("got message", message);
|
||||
LOG.info("got: " + message);
|
||||
consumerSession.rollback();
|
||||
|
||||
for (int i = 0; i < maxBrokerRedeliveriesToValidate; i++) {
|
||||
Message shouldBeNull = consumer.receive(500);
|
||||
assertNull("did not get message after redelivery count exceeded: " + shouldBeNull, shouldBeNull);
|
||||
|
||||
TimeUnit.SECONDS.sleep(3);
|
||||
|
||||
Message brokerRedeliveryMessage = consumer.receive(500);
|
||||
LOG.info("got: " + brokerRedeliveryMessage);
|
||||
assertNotNull("got message via broker redelivery after delay", brokerRedeliveryMessage);
|
||||
assertEquals("message matches", message.getStringProperty("data"), brokerRedeliveryMessage.getStringProperty("data"));
|
||||
assertEquals("has expiryDelay specified", i == 0 ? initialRedeliveryDelayMillis : redeliveryDelayMillis, brokerRedeliveryMessage.getLongProperty(RedeliveryPlugin.REDELIVERY_DELAY));
|
||||
|
||||
consumerSession.rollback();
|
||||
}
|
||||
|
||||
if (validateDLQ) {
|
||||
MessageConsumer dlqConsumer = consumerSession.createConsumer(new ActiveMQQueue(SharedDeadLetterStrategy.DEFAULT_DEAD_LETTER_QUEUE_NAME));
|
||||
Message dlqMessage = dlqConsumer.receive(2000);
|
||||
assertNotNull("Got message from dql", dlqMessage);
|
||||
assertEquals("message matches", message.getStringProperty("data"), dlqMessage.getStringProperty("data"));
|
||||
consumerSession.commit();
|
||||
} else {
|
||||
// consume/commit ok
|
||||
message = consumer.receive(3000);
|
||||
assertNotNull("got message", message);
|
||||
assertEquals("redeliveries accounted for", maxBrokerRedeliveriesToValidate + 2, message.getLongProperty("JMSXDeliveryCount"));
|
||||
consumerSession.commit();
|
||||
}
|
||||
|
||||
consumerConnection.close();
|
||||
}
|
||||
|
||||
public void testNoScheduledRedeliveryOfExpired() throws Exception {
|
||||
startBroker(true);
|
||||
ActiveMQConnection consumerConnection = (ActiveMQConnection) createConnection();
|
||||
consumerConnection.start();
|
||||
Session consumerSession = consumerConnection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
|
||||
MessageConsumer consumer = consumerSession.createConsumer(destination);
|
||||
sendMessage(1500);
|
||||
Message message = consumer.receive(1000);
|
||||
assertNotNull("got message", message);
|
||||
|
||||
// ensure there is another consumer to redispatch to
|
||||
MessageConsumer redeliverConsumer = consumerSession.createConsumer(destination);
|
||||
|
||||
// allow consumed to expire so it gets redelivered
|
||||
TimeUnit.SECONDS.sleep(2);
|
||||
consumer.close();
|
||||
|
||||
// should go to dlq as it has expired
|
||||
// validate DLQ
|
||||
MessageConsumer dlqConsumer = consumerSession.createConsumer(new ActiveMQQueue(SharedDeadLetterStrategy.DEFAULT_DEAD_LETTER_QUEUE_NAME));
|
||||
Message dlqMessage = dlqConsumer.receive(2000);
|
||||
assertNotNull("Got message from dql", dlqMessage);
|
||||
assertEquals("message matches", message.getStringProperty("data"), dlqMessage.getStringProperty("data"));
|
||||
}
|
||||
|
||||
private void sendMessage(int timeToLive) throws Exception {
|
||||
ActiveMQConnection producerConnection = (ActiveMQConnection) createConnection();
|
||||
producerConnection.start();
|
||||
Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
MessageProducer producer = producerSession.createProducer(destination);
|
||||
if (timeToLive > 0) {
|
||||
producer.setTimeToLive(timeToLive);
|
||||
}
|
||||
Message message = producerSession.createMessage();
|
||||
message.setStringProperty("data", data);
|
||||
producer.send(message);
|
||||
producerConnection.close();
|
||||
}
|
||||
|
||||
private void startBroker(boolean deleteMessages) throws Exception {
|
||||
broker = new BrokerService();
|
||||
broker.setSchedulerSupport(true);
|
||||
|
||||
RedeliveryPlugin redeliveryPlugin = new RedeliveryPlugin();
|
||||
|
||||
RedeliveryPolicy brokerRedeliveryPolicy = new RedeliveryPolicy();
|
||||
brokerRedeliveryPolicy.setRedeliveryDelay(redeliveryDelayMillis);
|
||||
brokerRedeliveryPolicy.setInitialRedeliveryDelay(initialRedeliveryDelayMillis);
|
||||
brokerRedeliveryPolicy.setMaximumRedeliveries(maxBrokerRedeliveries);
|
||||
|
||||
RedeliveryPolicyMap redeliveryPolicyMap = new RedeliveryPolicyMap();
|
||||
redeliveryPolicyMap.setDefaultEntry(brokerRedeliveryPolicy);
|
||||
redeliveryPlugin.setRedeliveryPolicyMap(redeliveryPolicyMap);
|
||||
|
||||
broker.setPlugins(new BrokerPlugin[]{redeliveryPlugin});
|
||||
|
||||
if (deleteMessages) {
|
||||
broker.setDeleteAllMessagesOnStartup(true);
|
||||
}
|
||||
broker.start();
|
||||
}
|
||||
|
||||
private void stopBroker() throws Exception {
|
||||
if (broker != null)
|
||||
broker.stop();
|
||||
broker = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ActiveMQConnectionFactory createConnectionFactory() throws Exception {
|
||||
return new ActiveMQConnectionFactory("vm://localhost");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
stopBroker();
|
||||
super.tearDown();
|
||||
}
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
/**
|
||||
* 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 junit.framework.TestCase;
|
||||
|
||||
import org.apache.activemq.network.NetworkConnector;
|
||||
|
||||
/**
|
||||
* Tests for the BrokerService class
|
||||
*
|
||||
* @author chirino
|
||||
*/
|
||||
public class BrokerServiceTest extends TestCase {
|
||||
|
||||
public void testAddRemoveTransportsWithJMX() throws Exception {
|
||||
BrokerService service = new BrokerService();
|
||||
service.setUseJmx(true);
|
||||
service.setPersistent(false);
|
||||
TransportConnector connector = service.addConnector("tcp://localhost:0");
|
||||
service.start();
|
||||
|
||||
service.removeConnector(connector);
|
||||
connector.stop();
|
||||
service.stop();
|
||||
}
|
||||
|
||||
public void testAddRemoveTransportsWithoutJMX() throws Exception {
|
||||
BrokerService service = new BrokerService();
|
||||
service.setPersistent(false);
|
||||
service.setUseJmx(false);
|
||||
TransportConnector connector = service.addConnector("tcp://localhost:0");
|
||||
service.start();
|
||||
|
||||
service.removeConnector(connector);
|
||||
connector.stop();
|
||||
service.stop();
|
||||
}
|
||||
|
||||
public void testAddRemoveNetworkWithJMX() throws Exception {
|
||||
BrokerService service = new BrokerService();
|
||||
service.setPersistent(false);
|
||||
service.setUseJmx(true);
|
||||
NetworkConnector connector = service.addNetworkConnector("multicast://default?group=group-" + System.currentTimeMillis());
|
||||
service.start();
|
||||
|
||||
service.removeNetworkConnector(connector);
|
||||
connector.stop();
|
||||
service.stop();
|
||||
}
|
||||
|
||||
public void testAddRemoveNetworkWithoutJMX() throws Exception {
|
||||
BrokerService service = new BrokerService();
|
||||
service.setPersistent(false);
|
||||
service.setUseJmx(false);
|
||||
NetworkConnector connector = service.addNetworkConnector("multicast://default?group=group-" + System.currentTimeMillis());
|
||||
service.start();
|
||||
|
||||
service.removeNetworkConnector(connector);
|
||||
connector.stop();
|
||||
service.stop();
|
||||
}
|
||||
|
||||
public void testSystemUsage() {
|
||||
BrokerService service = new BrokerService();
|
||||
assertEquals(1024 * 1024 * 1024, service.getSystemUsage().getMemoryUsage().getLimit());
|
||||
assertEquals(1024L * 1024 * 1024 * 50, service.getSystemUsage().getTempUsage().getLimit());
|
||||
assertEquals(1024L * 1024 * 1024 * 100, service.getSystemUsage().getStoreUsage().getLimit());
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
/**
|
||||
* 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 junit.framework.Test;
|
||||
|
||||
import org.apache.activemq.advisory.AdvisorySupport;
|
||||
import org.apache.activemq.command.ConnectionInfo;
|
||||
import org.apache.activemq.command.ConsumerId;
|
||||
import org.apache.activemq.command.ConsumerInfo;
|
||||
import org.apache.activemq.command.SessionId;
|
||||
|
||||
public class ConcurrentConnectSimulationTest extends BrokerTestSupport {
|
||||
|
||||
/*
|
||||
* simulate failover and retry of connection before broker has killed connection
|
||||
* which appears as a concurrent connect request to the broker
|
||||
* see: https://issues.apache.org/activemq/browse/AMQ-2241
|
||||
*/
|
||||
public void testConcurrentConnection() throws Exception {
|
||||
|
||||
StubConnection connection1 = createConnection();
|
||||
StubConnection connection2 = createConnection();
|
||||
|
||||
// reuse same connection info
|
||||
ConnectionInfo connectionInfo = createConnectionInfo();
|
||||
connection1.request(connectionInfo);
|
||||
connection2.request(connectionInfo);
|
||||
|
||||
// second one should win out, verify using consumer on default session (watchAdvisories)
|
||||
ConsumerId consumerId = new ConsumerId(new SessionId(connectionInfo.getConnectionId(), -1), 1);
|
||||
ConsumerInfo consumerInfo = new ConsumerInfo(consumerId);
|
||||
consumerInfo.setDestination(AdvisorySupport.TEMP_DESTINATION_COMPOSITE_ADVISORY_TOPIC);
|
||||
|
||||
connection2.request(consumerInfo);
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return suite(ConcurrentConnectSimulationTest.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(suite());
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.broker;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.activemq.EmbeddedBrokerTestSupport;
|
||||
import org.apache.activemq.broker.region.Destination;
|
||||
import org.apache.activemq.command.ActiveMQDestination;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.apache.activemq.command.ActiveMQTopic;
|
||||
import org.apache.activemq.xbean.XBeanBrokerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class CreateDestinationsOnStartupViaXBeanTest extends EmbeddedBrokerTestSupport {
|
||||
|
||||
public void testNewDestinationsAreCreatedOnStartup() throws Exception {
|
||||
assertQueueCreated("FOO.BAR", true);
|
||||
assertQueueCreated("FOO.DoesNotExist", false);
|
||||
|
||||
assertTopicCreated("SOME.TOPIC", true);
|
||||
assertTopicCreated("FOO.DoesNotExist", false);
|
||||
}
|
||||
|
||||
protected void assertQueueCreated(String name, boolean expected) throws Exception {
|
||||
assertDestinationCreated(new ActiveMQQueue(name), expected);
|
||||
}
|
||||
|
||||
protected void assertTopicCreated(String name, boolean expected) throws Exception {
|
||||
assertDestinationCreated(new ActiveMQTopic(name), expected);
|
||||
}
|
||||
|
||||
protected void assertDestinationCreated(ActiveMQDestination destination, boolean expected) throws Exception {
|
||||
Set<Destination> answer = broker.getBroker().getDestinations(destination);
|
||||
int size = expected ? 1 : 0;
|
||||
assertEquals("Could not find destination: " + destination + ". Size of found destinations: " + answer, size, answer.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
XBeanBrokerFactory factory = new XBeanBrokerFactory();
|
||||
BrokerService answer = factory.createBroker(new URI(getBrokerConfigUri()));
|
||||
|
||||
// lets disable persistence as we are a test
|
||||
answer.setPersistent(false);
|
||||
|
||||
return answer;
|
||||
}
|
||||
|
||||
protected String getBrokerConfigUri() {
|
||||
return "org/apache/activemq/broker/destinations-on-start.xml";
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
/**
|
||||
* 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 junit.framework.Test;
|
||||
|
||||
public class DedicatedTaskRunnerBrokerTest extends BrokerTest {
|
||||
|
||||
@Override
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerService broker = super.createBroker();
|
||||
broker.setDedicatedTaskRunner(true);
|
||||
return broker;
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return suite(DedicatedTaskRunnerBrokerTest.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(suite());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
/**
|
||||
* 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 javax.jms.DeliveryMode;
|
||||
|
||||
import junit.framework.Test;
|
||||
|
||||
import org.apache.activemq.command.ActiveMQDestination;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
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.ProducerInfo;
|
||||
import org.apache.activemq.command.SessionInfo;
|
||||
import org.apache.activemq.network.NetworkTestSupport;
|
||||
|
||||
/**
|
||||
* Pretend to be an abusive client that sends multiple identical ConsumerInfo
|
||||
* commands and make sure the broker doesn't stall because of it.
|
||||
*/
|
||||
|
||||
public class DoubleSubscriptionTest extends NetworkTestSupport {
|
||||
|
||||
public ActiveMQDestination destination;
|
||||
public int deliveryMode;
|
||||
|
||||
private String remoteURI = "tcp://localhost:0?wireFormat.tcpNoDelayEnabled=true";
|
||||
|
||||
public static Test suite() {
|
||||
return suite(DoubleSubscriptionTest.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(suite());
|
||||
}
|
||||
|
||||
public void initCombosForTestDoubleSubscription() {
|
||||
addCombinationValues("destination", new Object[]{new ActiveMQQueue("TEST"), new ActiveMQQueue("TEST")});
|
||||
}
|
||||
|
||||
public void testDoubleSubscription() throws Exception {
|
||||
|
||||
// Start a normal consumer on the remote broker
|
||||
StubConnection connection1 = createRemoteConnection();
|
||||
ConnectionInfo connectionInfo1 = createConnectionInfo();
|
||||
SessionInfo sessionInfo1 = createSessionInfo(connectionInfo1);
|
||||
ConsumerInfo consumerInfo1 = createConsumerInfo(sessionInfo1, destination);
|
||||
connection1.send(connectionInfo1);
|
||||
connection1.send(sessionInfo1);
|
||||
connection1.request(consumerInfo1);
|
||||
|
||||
// Start a normal producer on a remote broker
|
||||
StubConnection connection2 = createRemoteConnection();
|
||||
ConnectionInfo connectionInfo2 = createConnectionInfo();
|
||||
SessionInfo sessionInfo2 = createSessionInfo(connectionInfo2);
|
||||
ProducerInfo producerInfo2 = createProducerInfo(sessionInfo2);
|
||||
connection2.send(connectionInfo2);
|
||||
connection2.send(sessionInfo2);
|
||||
connection2.request(producerInfo2);
|
||||
|
||||
// Send a message to make sure the basics are working
|
||||
connection2.request(createMessage(producerInfo2, destination, DeliveryMode.PERSISTENT));
|
||||
|
||||
Message m1 = receiveMessage(connection1);
|
||||
assertNotNull(m1);
|
||||
assertNoMessagesLeft(connection1);
|
||||
|
||||
connection1.send(createAck(consumerInfo1, m1, 1, MessageAck.STANDARD_ACK_TYPE));
|
||||
|
||||
// Send a message to sit on the broker while we mess with it
|
||||
connection2.request(createMessage(producerInfo2, destination, DeliveryMode.PERSISTENT));
|
||||
|
||||
// Now we're going to resend the same consumer commands again and see if
|
||||
// the broker
|
||||
// can handle it.
|
||||
connection1.send(connectionInfo1);
|
||||
connection1.send(sessionInfo1);
|
||||
connection1.request(consumerInfo1);
|
||||
|
||||
// After this there should be 2 messages on the broker...
|
||||
connection2.request(createMessage(producerInfo2, destination, DeliveryMode.PERSISTENT));
|
||||
|
||||
// ... let's start a fresh consumer...
|
||||
connection1.stop();
|
||||
StubConnection connection3 = createRemoteConnection();
|
||||
ConnectionInfo connectionInfo3 = createConnectionInfo();
|
||||
SessionInfo sessionInfo3 = createSessionInfo(connectionInfo3);
|
||||
ConsumerInfo consumerInfo3 = createConsumerInfo(sessionInfo3, destination);
|
||||
connection3.send(connectionInfo3);
|
||||
connection3.send(sessionInfo3);
|
||||
connection3.request(consumerInfo3);
|
||||
|
||||
// ... and then grab the 2 that should be there.
|
||||
assertNotNull(receiveMessage(connection3));
|
||||
assertNotNull(receiveMessage(connection3));
|
||||
assertNoMessagesLeft(connection3);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getRemoteURI() {
|
||||
return remoteURI;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
/**
|
||||
* 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 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 javax.jms.Topic;
|
||||
|
||||
import junit.framework.Test;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnection;
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.store.kahadb.KahaDBPersistenceAdapter;
|
||||
import org.apache.activemq.transport.failover.FailoverTransport;
|
||||
|
||||
public class DurablePersistentFalseRestartTest extends BrokerRestartTestSupport {
|
||||
|
||||
@Override
|
||||
protected void configureBroker(BrokerService broker) throws Exception {
|
||||
super.configureBroker(broker);
|
||||
broker.setPersistent(false);
|
||||
broker.setPersistenceAdapter(new KahaDBPersistenceAdapter());
|
||||
broker.addConnector("tcp://0.0.0.0:0");
|
||||
}
|
||||
|
||||
public void testValidateNoPersistenceForDurableAfterRestart() throws Exception {
|
||||
|
||||
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("failover:(" + broker.getTransportConnectors().get(0).getPublishableConnectString() + ")");
|
||||
ActiveMQConnection connection = (ActiveMQConnection) connectionFactory.createConnection();
|
||||
connection.setClientID("clientId");
|
||||
connection.start();
|
||||
|
||||
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
|
||||
Topic destination = session.createTopic(queueName);
|
||||
MessageConsumer consumer = session.createDurableSubscriber(destination, "subscriberName");
|
||||
|
||||
populateDestination(10, destination, connection);
|
||||
|
||||
restartBroker();
|
||||
|
||||
// make failover aware of the restarted auto assigned port
|
||||
connection.getTransport().narrow(FailoverTransport.class).add(true, broker.getTransportConnectors().get(0).getPublishableConnectString());
|
||||
|
||||
TextMessage msg = (TextMessage) consumer.receive(4000);
|
||||
assertNull("did not get a message when persistent=false, message: " + msg, msg);
|
||||
|
||||
connection.close();
|
||||
}
|
||||
|
||||
private void populateDestination(final int nbMessages,
|
||||
final Destination destination,
|
||||
javax.jms.Connection connection) throws JMSException {
|
||||
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
MessageProducer producer = session.createProducer(destination);
|
||||
for (int i = 1; i <= nbMessages; i++) {
|
||||
producer.send(session.createTextMessage("<hello id='" + i + "'/>"));
|
||||
}
|
||||
producer.close();
|
||||
session.close();
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return suite(DurablePersistentFalseRestartTest.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(suite());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
/**
|
||||
* 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 junit.framework.Test;
|
||||
|
||||
import org.apache.activemq.command.ActiveMQDestination;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.apache.activemq.store.jdbc.JDBCPersistenceAdapter;
|
||||
import org.apache.derby.jdbc.EmbeddedDataSource;
|
||||
import org.apache.derby.jdbc.EmbeddedXADataSource;
|
||||
|
||||
public class JdbcXARecoveryBrokerTest extends XARecoveryBrokerTest {
|
||||
|
||||
EmbeddedXADataSource dataSource;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
dataSource = new EmbeddedXADataSource();
|
||||
dataSource.setDatabaseName("derbyDb");
|
||||
dataSource.setCreateDatabase("create");
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
stopDerby();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureBroker(BrokerService broker) throws Exception {
|
||||
super.configureBroker(broker);
|
||||
|
||||
JDBCPersistenceAdapter jdbc = new JDBCPersistenceAdapter();
|
||||
jdbc.setDataSource(dataSource);
|
||||
broker.setPersistenceAdapter(jdbc);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void restartBroker() throws Exception {
|
||||
broker.stop();
|
||||
stopDerby();
|
||||
dataSource = new EmbeddedXADataSource();
|
||||
dataSource.setDatabaseName("derbyDb");
|
||||
dataSource.setCreateDatabase("create");
|
||||
|
||||
broker = createRestartedBroker();
|
||||
broker.start();
|
||||
}
|
||||
|
||||
private void stopDerby() {
|
||||
LOG.info("STOPPING DB!@!!!!");
|
||||
final EmbeddedDataSource ds = dataSource;
|
||||
try {
|
||||
ds.setShutdownDatabase("shutdown");
|
||||
ds.getConnection();
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return suite(JdbcXARecoveryBrokerTest.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(suite());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ActiveMQDestination createDestination() {
|
||||
return new ActiveMQQueue("test,special");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,85 +0,0 @@
|
|||
/**
|
||||
* 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 javax.jms.Connection;
|
||||
import javax.jms.Session;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.broker.jmx.ManagementContext;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.apache.activemq.demo.DefaultQueueSender;
|
||||
|
||||
/**
|
||||
* A helper class which can be handy for running a broker in your IDE from the
|
||||
* activemq-core module.
|
||||
*/
|
||||
public final class Main {
|
||||
|
||||
protected static boolean createConsumers;
|
||||
|
||||
private Main() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
BrokerService broker = new BrokerService();
|
||||
broker.setPersistent(false);
|
||||
|
||||
// String brokerDir = "xbean:...;
|
||||
// System.setProperty("activemq.base", brokerDir);
|
||||
// BrokerService broker = BrokerFactory.createBroker(new URI(brokerDir + "/activemq.xml"));
|
||||
|
||||
// for running on Java 5 without mx4j
|
||||
ManagementContext managementContext = broker.getManagementContext();
|
||||
managementContext.setFindTigerMbeanServer(true);
|
||||
managementContext.setUseMBeanServer(true);
|
||||
managementContext.setCreateConnector(false);
|
||||
|
||||
broker.setUseJmx(true);
|
||||
// broker.setPlugins(new BrokerPlugin[] { new
|
||||
// ConnectionDotFilePlugin(), new UDPTraceBrokerPlugin() });
|
||||
broker.addConnector("tcp://localhost:61616");
|
||||
broker.addConnector("stomp://localhost:61613");
|
||||
broker.start();
|
||||
|
||||
// lets publish some messages so that there is some stuff to browse
|
||||
DefaultQueueSender.main(new String[]{"Prices.Equity.IBM"});
|
||||
DefaultQueueSender.main(new String[]{"Prices.Equity.MSFT"});
|
||||
|
||||
// lets create a dummy couple of consumers
|
||||
if (createConsumers) {
|
||||
Connection connection = new ActiveMQConnectionFactory().createConnection();
|
||||
connection.start();
|
||||
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
session.createConsumer(new ActiveMQQueue("Orders.IBM"));
|
||||
session.createConsumer(new ActiveMQQueue("Orders.MSFT"), "price > 100");
|
||||
Session session2 = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
session2.createConsumer(new ActiveMQQueue("Orders.MSFT"), "price > 200");
|
||||
} else {
|
||||
// Lets wait for the broker
|
||||
broker.waitUntilStopped();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Failed: " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.broker;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import junit.framework.Test;
|
||||
|
||||
import org.apache.activemq.command.Command;
|
||||
import org.apache.activemq.command.Response;
|
||||
import org.apache.activemq.openwire.OpenWireFormat;
|
||||
import org.apache.activemq.wireformat.WireFormat;
|
||||
|
||||
/**
|
||||
* Runs against the broker but marshals all request and response commands.
|
||||
*/
|
||||
public class MarshallingBrokerTest extends BrokerTest {
|
||||
|
||||
public WireFormat wireFormat = new OpenWireFormat();
|
||||
|
||||
public void initCombos() {
|
||||
|
||||
OpenWireFormat wf1 = new OpenWireFormat();
|
||||
wf1.setCacheEnabled(false);
|
||||
OpenWireFormat wf2 = new OpenWireFormat();
|
||||
wf2.setCacheEnabled(true);
|
||||
|
||||
addCombinationValues("wireFormat", new Object[]{wf1, wf2,});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StubConnection createConnection() throws Exception {
|
||||
return new StubConnection(broker) {
|
||||
@Override
|
||||
public Response request(Command command) throws Exception {
|
||||
Response r = super.request((Command) wireFormat.unmarshal(wireFormat.marshal(command)));
|
||||
if (r != null) {
|
||||
r = (Response) wireFormat.unmarshal(wireFormat.marshal(r));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(Command command) throws Exception {
|
||||
super.send((Command) wireFormat.unmarshal(wireFormat.marshal(command)));
|
||||
}
|
||||
|
||||
protected void dispatch(Command command) throws InterruptedException, IOException {
|
||||
super.dispatch(wireFormat.unmarshal(wireFormat.marshal(command)));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return suite(MarshallingBrokerTest.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(suite());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,276 +0,0 @@
|
|||
/**
|
||||
* 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 javax.jms.DeliveryMode;
|
||||
|
||||
import junit.framework.Test;
|
||||
|
||||
import org.apache.activemq.broker.region.policy.PolicyEntry;
|
||||
import org.apache.activemq.broker.region.policy.VMPendingSubscriberMessageStoragePolicy;
|
||||
import org.apache.activemq.command.ActiveMQDestination;
|
||||
import org.apache.activemq.command.ConnectionInfo;
|
||||
import org.apache.activemq.command.ConsumerInfo;
|
||||
import org.apache.activemq.command.LocalTransactionId;
|
||||
import org.apache.activemq.command.Message;
|
||||
import org.apache.activemq.command.MessageAck;
|
||||
import org.apache.activemq.command.ProducerInfo;
|
||||
import org.apache.activemq.command.SessionInfo;
|
||||
|
||||
public class MessageExpirationTest extends BrokerTestSupport {
|
||||
|
||||
public ActiveMQDestination destination;
|
||||
public int deliveryMode = DeliveryMode.NON_PERSISTENT;
|
||||
public int prefetch;
|
||||
public byte destinationType = ActiveMQDestination.QUEUE_TYPE;
|
||||
public boolean durableConsumer;
|
||||
|
||||
protected Message createMessage(ProducerInfo producerInfo,
|
||||
ActiveMQDestination destination,
|
||||
int deliveryMode,
|
||||
int timeToLive) {
|
||||
Message message = createMessage(producerInfo, destination, deliveryMode);
|
||||
long now = System.currentTimeMillis();
|
||||
message.setTimestamp(now);
|
||||
message.setExpiration(now + timeToLive);
|
||||
return message;
|
||||
}
|
||||
|
||||
public void initCombosForTestMessagesWaitingForUssageDecreaseExpire() {
|
||||
addCombinationValues("deliveryMode", new Object[]{Integer.valueOf(DeliveryMode.NON_PERSISTENT), Integer.valueOf(DeliveryMode.PERSISTENT)});
|
||||
addCombinationValues("destinationType", new Object[]{Byte.valueOf(ActiveMQDestination.TEMP_QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TEMP_TOPIC_TYPE), Byte.valueOf(ActiveMQDestination.QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TOPIC_TYPE)});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerService broker = new BrokerService();
|
||||
broker.setPersistent(false);
|
||||
return broker;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PolicyEntry getDefaultPolicy() {
|
||||
PolicyEntry policy = super.getDefaultPolicy();
|
||||
// disable spooling
|
||||
policy.setPendingSubscriberPolicy(new VMPendingSubscriberMessageStoragePolicy());
|
||||
// have aggressive expiry period to ensure no deadlock or clash
|
||||
policy.setExpireMessagesPeriod(100);
|
||||
|
||||
return policy;
|
||||
}
|
||||
|
||||
public void testMessagesWaitingForUsageDecreaseExpire() throws Exception {
|
||||
|
||||
// Start a producer
|
||||
final StubConnection connection = createConnection();
|
||||
ConnectionInfo connectionInfo = createConnectionInfo();
|
||||
SessionInfo sessionInfo = createSessionInfo(connectionInfo);
|
||||
final ProducerInfo producerInfo = createProducerInfo(sessionInfo);
|
||||
connection.send(connectionInfo);
|
||||
connection.send(sessionInfo);
|
||||
connection.send(producerInfo);
|
||||
|
||||
// Start a consumer..
|
||||
final StubConnection connection2 = createConnection();
|
||||
ConnectionInfo connectionInfo2 = createConnectionInfo();
|
||||
SessionInfo sessionInfo2 = createSessionInfo(connectionInfo2);
|
||||
connection2.send(connectionInfo2);
|
||||
connection2.send(sessionInfo2);
|
||||
|
||||
destination = createDestinationInfo(connection2, connectionInfo2, destinationType);
|
||||
ConsumerInfo consumerInfo2 = createConsumerInfo(sessionInfo2, destination);
|
||||
consumerInfo2.setPrefetchSize(1);
|
||||
connection2.request(consumerInfo2);
|
||||
|
||||
// Reduce the limit so that only 1 message can flow through the broker
|
||||
// at a time.
|
||||
broker.getSystemUsage().getMemoryUsage().setLimit(1);
|
||||
|
||||
final Message m1 = createMessage(producerInfo, destination, deliveryMode);
|
||||
final Message m2 = createMessage(producerInfo, destination, deliveryMode, 1000);
|
||||
final Message m3 = createMessage(producerInfo, destination, deliveryMode);
|
||||
final Message m4 = createMessage(producerInfo, destination, deliveryMode, 1000);
|
||||
|
||||
// Produce in an async thread since the producer will be getting blocked
|
||||
// by the usage manager..
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
// m1 and m3 should not expire.. but the others should.
|
||||
try {
|
||||
connection.send(m1);
|
||||
connection.send(m2);
|
||||
connection.send(m3);
|
||||
connection.send(m4);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
|
||||
// Make sure only 1 message was delivered due to prefetch == 1
|
||||
Message m = receiveMessage(connection2);
|
||||
assertNotNull(m);
|
||||
assertEquals(m1.getMessageId(), m.getMessageId());
|
||||
assertNoMessagesLeft(connection);
|
||||
|
||||
// Sleep before we ack so that the messages expire on the usage manager
|
||||
Thread.sleep(1500);
|
||||
connection2.send(createAck(consumerInfo2, m, 1, MessageAck.STANDARD_ACK_TYPE));
|
||||
|
||||
// 2nd message received should be m3.. it should have expired 2nd
|
||||
// message sent.
|
||||
m = receiveMessage(connection2);
|
||||
assertNotNull(m);
|
||||
assertEquals(m3.getMessageId(), m.getMessageId());
|
||||
|
||||
// Sleep before we ack so that the messages expire on the usage manager
|
||||
Thread.sleep(1500);
|
||||
connection2.send(createAck(consumerInfo2, m, 1, MessageAck.STANDARD_ACK_TYPE));
|
||||
|
||||
// And there should be no messages left now..
|
||||
assertNoMessagesLeft(connection2);
|
||||
|
||||
connection.send(closeConnectionInfo(connectionInfo));
|
||||
connection.send(closeConnectionInfo(connectionInfo2));
|
||||
}
|
||||
|
||||
public void initCombosForTestMessagesInLongTransactionExpire() {
|
||||
addCombinationValues("deliveryMode", new Object[]{Integer.valueOf(DeliveryMode.PERSISTENT), Integer.valueOf(DeliveryMode.NON_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 testMessagesInLongTransactionExpire() throws Exception {
|
||||
|
||||
// Start a producer and consumer
|
||||
StubConnection connection = createConnection();
|
||||
ConnectionInfo connectionInfo = createConnectionInfo();
|
||||
SessionInfo sessionInfo = createSessionInfo(connectionInfo);
|
||||
ProducerInfo producerInfo = createProducerInfo(sessionInfo);
|
||||
connection.send(connectionInfo);
|
||||
connection.send(sessionInfo);
|
||||
connection.send(producerInfo);
|
||||
|
||||
destination = createDestinationInfo(connection, connectionInfo, destinationType);
|
||||
|
||||
ConsumerInfo consumerInfo = createConsumerInfo(sessionInfo, destination);
|
||||
consumerInfo.setPrefetchSize(1000);
|
||||
connection.send(consumerInfo);
|
||||
|
||||
// Start the tx..
|
||||
LocalTransactionId txid = createLocalTransaction(sessionInfo);
|
||||
connection.send(createBeginTransaction(connectionInfo, txid));
|
||||
|
||||
// m1 and m3 should not expire.. but the others should.
|
||||
Message m1 = createMessage(producerInfo, destination, deliveryMode);
|
||||
m1.setTransactionId(txid);
|
||||
connection.send(m1);
|
||||
Message m = createMessage(producerInfo, destination, deliveryMode, 1000);
|
||||
m.setTransactionId(txid);
|
||||
connection.send(m);
|
||||
Message m3 = createMessage(producerInfo, destination, deliveryMode);
|
||||
m3.setTransactionId(txid);
|
||||
connection.send(m3);
|
||||
m = createMessage(producerInfo, destination, deliveryMode, 1000);
|
||||
m.setTransactionId(txid);
|
||||
connection.send(m);
|
||||
|
||||
// Sleep before we commit so that the messages expire on the commit
|
||||
// list..
|
||||
Thread.sleep(1500);
|
||||
connection.send(createCommitTransaction1Phase(connectionInfo, txid));
|
||||
|
||||
m = receiveMessage(connection);
|
||||
assertNotNull(m);
|
||||
assertEquals(m1.getMessageId(), m.getMessageId());
|
||||
connection.send(createAck(consumerInfo, m, 1, MessageAck.STANDARD_ACK_TYPE));
|
||||
|
||||
// 2nd message received should be m3.. it should have expired 2nd
|
||||
// message sent.
|
||||
m = receiveMessage(connection);
|
||||
assertNotNull(m);
|
||||
assertEquals(m3.getMessageId(), m.getMessageId());
|
||||
connection.send(createAck(consumerInfo, m, 1, MessageAck.STANDARD_ACK_TYPE));
|
||||
|
||||
// And there should be no messages left now..
|
||||
assertNoMessagesLeft(connection);
|
||||
|
||||
connection.send(closeConnectionInfo(connectionInfo));
|
||||
}
|
||||
|
||||
public void initCombosForTestMessagesInSubscriptionPendingListExpire() {
|
||||
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 testMessagesInSubscriptionPendingListExpire() throws Exception {
|
||||
|
||||
// Start a producer and consumer
|
||||
StubConnection connection = createConnection();
|
||||
ConnectionInfo connectionInfo = createConnectionInfo();
|
||||
SessionInfo sessionInfo = createSessionInfo(connectionInfo);
|
||||
ProducerInfo producerInfo = createProducerInfo(sessionInfo);
|
||||
connection.send(connectionInfo);
|
||||
connection.send(sessionInfo);
|
||||
connection.send(producerInfo);
|
||||
|
||||
destination = createDestinationInfo(connection, connectionInfo, destinationType);
|
||||
|
||||
ConsumerInfo consumerInfo = createConsumerInfo(sessionInfo, destination);
|
||||
consumerInfo.setPrefetchSize(1);
|
||||
connection.send(consumerInfo);
|
||||
|
||||
// m1 and m3 should not expire.. but the others should.
|
||||
Message m1 = createMessage(producerInfo, destination, deliveryMode);
|
||||
connection.send(m1);
|
||||
connection.send(createMessage(producerInfo, destination, deliveryMode, 1000));
|
||||
Message m3 = createMessage(producerInfo, destination, deliveryMode);
|
||||
connection.send(m3);
|
||||
connection.send(createMessage(producerInfo, destination, deliveryMode, 1000));
|
||||
|
||||
// Make sure only 1 message was delivered due to prefetch == 1
|
||||
Message m = receiveMessage(connection);
|
||||
assertNotNull(m);
|
||||
assertEquals(m1.getMessageId(), m.getMessageId());
|
||||
assertNoMessagesLeft(connection);
|
||||
|
||||
// Sleep before we ack so that the messages expire on the pending list..
|
||||
Thread.sleep(1500);
|
||||
connection.send(createAck(consumerInfo, m, 1, MessageAck.STANDARD_ACK_TYPE));
|
||||
|
||||
// 2nd message received should be m3.. it should have expired 2nd
|
||||
// message sent.
|
||||
m = receiveMessage(connection);
|
||||
assertNotNull(m);
|
||||
assertEquals(m3.getMessageId(), m.getMessageId());
|
||||
connection.send(createAck(consumerInfo, m, 1, MessageAck.STANDARD_ACK_TYPE));
|
||||
|
||||
// And there should be no messages left now..
|
||||
assertNoMessagesLeft(connection);
|
||||
|
||||
connection.send(closeConnectionInfo(connectionInfo));
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return suite(MessageExpirationTest.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(suite());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,132 +0,0 @@
|
|||
/**
|
||||
* 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 javax.jms.ConnectionFactory;
|
||||
import javax.jms.ExceptionListener;
|
||||
import javax.jms.JMSException;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnection;
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.broker.region.policy.PolicyEntry;
|
||||
import org.apache.activemq.broker.region.policy.PolicyMap;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.BlockJUnit4ClassRunner;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
@RunWith(BlockJUnit4ClassRunner.class)
|
||||
public class NioQueueSubscriptionTest extends QueueSubscriptionTest {
|
||||
|
||||
protected static final Logger LOG = LoggerFactory.getLogger(NioQueueSubscriptionTest.class);
|
||||
|
||||
private final Map<Thread, Throwable> exceptions = Collections.synchronizedMap(new HashMap<Thread, Throwable>());
|
||||
|
||||
@Override
|
||||
protected ConnectionFactory createConnectionFactory() throws Exception {
|
||||
return new ActiveMQConnectionFactory("tcp://localhost:62621?trace=false");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerService answer = BrokerFactory.createBroker(new URI("broker://nio://localhost:62621?useQueueForAccept=false&persistent=false&wiewformat.maxInactivityDuration=0"));
|
||||
answer.getManagementContext().setCreateConnector(false);
|
||||
answer.setUseJmx(false);
|
||||
answer.setDeleteAllMessagesOnStartup(true);
|
||||
final List<PolicyEntry> policyEntries = new ArrayList<>();
|
||||
final PolicyEntry entry = new PolicyEntry();
|
||||
entry.setQueue(">");
|
||||
entry.setOptimizedDispatch(true);
|
||||
policyEntries.add(entry);
|
||||
|
||||
final PolicyMap policyMap = new PolicyMap();
|
||||
policyMap.setPolicyEntries(policyEntries);
|
||||
answer.setDestinationPolicy(policyMap);
|
||||
return answer;
|
||||
}
|
||||
|
||||
@Ignore("See AMQ-4286")
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testLotsOfConcurrentConnections() throws Exception {
|
||||
ExecutorService executor = Executors.newCachedThreadPool();
|
||||
final ConnectionFactory factory = createConnectionFactory();
|
||||
int connectionCount = 400;
|
||||
final AtomicInteger threadId = new AtomicInteger(0);
|
||||
for (int i = 0; i < connectionCount; i++) {
|
||||
executor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final int innerId = threadId.incrementAndGet();
|
||||
try {
|
||||
ExceptionListener listener = new NioQueueSubscriptionTestListener(innerId, exceptions, LOG);
|
||||
ActiveMQConnection connection = (ActiveMQConnection) factory.createConnection();
|
||||
connection.setExceptionListener(listener);
|
||||
connection.start();
|
||||
assertNotNull(connection.getBrokerName());
|
||||
connections.add(connection);
|
||||
} catch (Exception e) {
|
||||
LOG.error(">>>> Exception in run() on thread " + innerId, e);
|
||||
exceptions.put(Thread.currentThread(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
executor.shutdown();
|
||||
executor.awaitTermination(30, TimeUnit.SECONDS);
|
||||
|
||||
if (!exceptions.isEmpty()) {
|
||||
LOG.error(">>>> " + exceptions.size() + " exceptions like", exceptions.values().iterator().next());
|
||||
fail("unexpected exceptions in worker threads: " + exceptions.values().iterator().next());
|
||||
}
|
||||
LOG.info("created " + connectionCount + " connections");
|
||||
}
|
||||
}
|
||||
|
||||
class NioQueueSubscriptionTestListener implements ExceptionListener {
|
||||
|
||||
private int id = 0;
|
||||
protected Logger LOG;
|
||||
private final Map<Thread, Throwable> exceptions;
|
||||
|
||||
public NioQueueSubscriptionTestListener(int id, Map<Thread, Throwable> exceptions, Logger log) {
|
||||
this.id = id;
|
||||
this.exceptions = exceptions;
|
||||
this.LOG = log;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(JMSException exception) {
|
||||
LOG.error(">>>> Exception in onException() on thread " + id, exception);
|
||||
exceptions.put(Thread.currentThread(), exception);
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.broker;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
// https://issues.apache.org/activemq/browse/AMQ-2939
|
||||
public class OutOfOrderXMLTest {
|
||||
|
||||
@Test
|
||||
public void verifyBrokerCreationWhenXmlOutOfOrderValidationFalse() throws Exception {
|
||||
BrokerService answer = BrokerFactory.createBroker(new URI("xbean:org/apache/activemq/broker/out-of-order-broker-elements.xml?validate=false"));
|
||||
answer.stop();
|
||||
|
||||
}
|
||||
}
|
|
@ -1,123 +0,0 @@
|
|||
/**
|
||||
* 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 javax.jms.MessageProducer;
|
||||
import javax.jms.Session;
|
||||
import javax.management.ObjectName;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.activemq.TestSupport;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.apache.activemq.util.JMXSupport;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@RunWith(value = Parameterized.class)
|
||||
public class QueueMbeanRestartTest extends TestSupport {
|
||||
|
||||
private static final transient Logger LOG = LoggerFactory.getLogger(QueueMbeanRestartTest.class);
|
||||
|
||||
BrokerService broker;
|
||||
|
||||
private final TestSupport.PersistenceAdapterChoice persistenceAdapterChoice;
|
||||
|
||||
@Parameterized.Parameters
|
||||
public static Collection<TestSupport.PersistenceAdapterChoice[]> getTestParameters() {
|
||||
TestSupport.PersistenceAdapterChoice[] kahaDb = {TestSupport.PersistenceAdapterChoice.KahaDB};
|
||||
TestSupport.PersistenceAdapterChoice[] levelDb = {TestSupport.PersistenceAdapterChoice.LevelDB};
|
||||
TestSupport.PersistenceAdapterChoice[] jdbc = {TestSupport.PersistenceAdapterChoice.JDBC};
|
||||
List<TestSupport.PersistenceAdapterChoice[]> choices = new ArrayList<>();
|
||||
choices.add(kahaDb);
|
||||
choices.add(levelDb);
|
||||
choices.add(jdbc);
|
||||
|
||||
return choices;
|
||||
}
|
||||
|
||||
public QueueMbeanRestartTest(TestSupport.PersistenceAdapterChoice choice) {
|
||||
this.persistenceAdapterChoice = choice;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
topic = false;
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
broker.stop();
|
||||
}
|
||||
|
||||
@Test(timeout = 60000)
|
||||
public void testMBeanPresenceOnRestart() throws Exception {
|
||||
createBroker(true);
|
||||
|
||||
sendMessages();
|
||||
verifyPresenceOfQueueMbean();
|
||||
LOG.info("restart....");
|
||||
|
||||
restartBroker();
|
||||
verifyPresenceOfQueueMbean();
|
||||
}
|
||||
|
||||
private void restartBroker() throws Exception {
|
||||
broker.stop();
|
||||
broker.waitUntilStopped();
|
||||
Thread.sleep(5 * 1000);
|
||||
createBroker(false);
|
||||
broker.waitUntilStarted();
|
||||
}
|
||||
|
||||
private void verifyPresenceOfQueueMbean() throws Exception {
|
||||
for (ObjectName name : broker.getManagementContext().queryNames(null, null)) {
|
||||
LOG.info("candidate :" + name);
|
||||
String type = name.getKeyProperty("destinationType");
|
||||
if (type != null && type.equals("Queue")) {
|
||||
assertEquals(JMXSupport.encodeObjectNamePart(((ActiveMQQueue) createDestination()).getPhysicalName()), name.getKeyProperty("destinationName"));
|
||||
LOG.info("found mbbean " + name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
fail("expected to find matching queue mbean for: " + createDestination());
|
||||
}
|
||||
|
||||
private void sendMessages() throws Exception {
|
||||
Session session = createConnection().createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
MessageProducer producer = session.createProducer(createDestination());
|
||||
producer.send(session.createTextMessage());
|
||||
}
|
||||
|
||||
private void createBroker(boolean deleteAll) throws Exception {
|
||||
broker = new BrokerService();
|
||||
setPersistenceAdapter(broker, persistenceAdapterChoice);
|
||||
|
||||
broker.setDeleteAllMessagesOnStartup(deleteAll);
|
||||
broker.start();
|
||||
}
|
||||
}
|
|
@ -1,188 +0,0 @@
|
|||
/**
|
||||
* 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.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.JmsMultipleClientsTestSupport;
|
||||
import org.apache.activemq.command.ActiveMQDestination;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.BlockJUnit4ClassRunner;
|
||||
|
||||
@RunWith(BlockJUnit4ClassRunner.class)
|
||||
public class QueueSubscriptionTest extends JmsMultipleClientsTestSupport {
|
||||
|
||||
protected int messageCount = 1000; // 1000 Messages per producer
|
||||
protected int prefetchCount = 10;
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
durable = false;
|
||||
topic = false;
|
||||
}
|
||||
|
||||
@After
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testManyProducersOneConsumer() throws Exception {
|
||||
consumerCount = 1;
|
||||
producerCount = 10;
|
||||
messageCount = 100;
|
||||
messageSize = 1; // 1 byte
|
||||
prefetchCount = 10;
|
||||
|
||||
doMultipleClientsTest();
|
||||
|
||||
assertTotalMessagesReceived(messageCount * producerCount);
|
||||
assertDestinationMemoryUsageGoesToZero();
|
||||
}
|
||||
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testOneProducerTwoConsumersSmallMessagesOnePrefetch() throws Exception {
|
||||
consumerCount = 2;
|
||||
producerCount = 1;
|
||||
messageCount = 1000;
|
||||
messageSize = 1024; // 1 Kb
|
||||
configurePrefetchOfOne();
|
||||
|
||||
doMultipleClientsTest();
|
||||
|
||||
assertTotalMessagesReceived(messageCount * producerCount);
|
||||
assertDestinationMemoryUsageGoesToZero();
|
||||
}
|
||||
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testOneProducerTwoConsumersSmallMessagesLargePrefetch() throws Exception {
|
||||
consumerCount = 2;
|
||||
producerCount = 1;
|
||||
messageCount = 1000;
|
||||
prefetchCount = messageCount * 2;
|
||||
messageSize = 1024; // 1 Kb
|
||||
|
||||
doMultipleClientsTest();
|
||||
|
||||
assertTotalMessagesReceived(messageCount * producerCount);
|
||||
assertDestinationMemoryUsageGoesToZero();
|
||||
}
|
||||
|
||||
@Test(timeout = 2 * 60 * 1000)
|
||||
public void testOneProducerTwoConsumersLargeMessagesOnePrefetch() throws Exception {
|
||||
consumerCount = 2;
|
||||
producerCount = 1;
|
||||
messageCount = 10;
|
||||
messageSize = 1024 * 1024 * 1; // 2 MB
|
||||
configurePrefetchOfOne();
|
||||
|
||||
doMultipleClientsTest();
|
||||
|
||||
assertTotalMessagesReceived(messageCount * producerCount);
|
||||
assertDestinationMemoryUsageGoesToZero();
|
||||
}
|
||||
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testOneProducerTwoConsumersLargeMessagesLargePrefetch() throws Exception {
|
||||
consumerCount = 2;
|
||||
producerCount = 1;
|
||||
messageCount = 10;
|
||||
prefetchCount = messageCount * 2;
|
||||
messageSize = 1024 * 1024 * 1; // 2 MB
|
||||
|
||||
doMultipleClientsTest();
|
||||
|
||||
assertTotalMessagesReceived(messageCount * producerCount);
|
||||
assertDestinationMemoryUsageGoesToZero();
|
||||
}
|
||||
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testOneProducerManyConsumersFewMessages() throws Exception {
|
||||
consumerCount = 50;
|
||||
producerCount = 1;
|
||||
messageCount = 10;
|
||||
messageSize = 1; // 1 byte
|
||||
prefetchCount = 10;
|
||||
|
||||
doMultipleClientsTest();
|
||||
|
||||
assertTotalMessagesReceived(messageCount * producerCount);
|
||||
assertDestinationMemoryUsageGoesToZero();
|
||||
}
|
||||
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testOneProducerManyConsumersManyMessages() throws Exception {
|
||||
consumerCount = 50;
|
||||
producerCount = 1;
|
||||
messageCount = 1000;
|
||||
messageSize = 1; // 1 byte
|
||||
prefetchCount = messageCount / consumerCount;
|
||||
allMessagesList.setMaximumDuration(allMessagesList.getMaximumDuration() * 20);
|
||||
doMultipleClientsTest();
|
||||
|
||||
assertTotalMessagesReceived(messageCount * producerCount);
|
||||
assertDestinationMemoryUsageGoesToZero();
|
||||
}
|
||||
|
||||
@Test(timeout = 2 * 60 * 1000)
|
||||
public void testManyProducersManyConsumers() throws Exception {
|
||||
consumerCount = 200;
|
||||
producerCount = 50;
|
||||
messageCount = 100;
|
||||
messageSize = 1; // 1 byte
|
||||
prefetchCount = 100;
|
||||
allMessagesList.setMaximumDuration(allMessagesList.getMaximumDuration() * 20);
|
||||
doMultipleClientsTest();
|
||||
|
||||
assertTotalMessagesReceived(messageCount * producerCount);
|
||||
assertDestinationMemoryUsageGoesToZero();
|
||||
}
|
||||
|
||||
protected void configurePrefetchOfOne() {
|
||||
prefetchCount = 1;
|
||||
|
||||
// this is gonna be a bit slow what with the low prefetch so bump up the
|
||||
// wait time
|
||||
allMessagesList.setMaximumDuration(allMessagesList.getMaximumDuration() * 20);
|
||||
}
|
||||
|
||||
public void doMultipleClientsTest() throws Exception {
|
||||
// Create destination
|
||||
final ActiveMQDestination dest = createDestination();
|
||||
|
||||
// Create consumers
|
||||
ActiveMQConnectionFactory consumerFactory = (ActiveMQConnectionFactory) createConnectionFactory();
|
||||
consumerFactory.getPrefetchPolicy().setAll(prefetchCount);
|
||||
|
||||
startConsumers(consumerFactory, dest);
|
||||
|
||||
startProducers(dest, messageCount);
|
||||
|
||||
// Wait for messages to be received. Make it proportional to the
|
||||
// messages delivered.
|
||||
int totalMessageCount = messageCount * producerCount;
|
||||
if (dest.isTopic()) {
|
||||
totalMessageCount *= consumerCount;
|
||||
}
|
||||
waitForAllMessagesToBeReceived(totalMessageCount);
|
||||
}
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
/**
|
||||
* 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 javax.jms.Connection;
|
||||
import javax.jms.ConnectionFactory;
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageConsumer;
|
||||
import javax.jms.MessageProducer;
|
||||
import javax.jms.Session;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.EmbeddedBrokerTestSupport;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class ReconnectWithJMXEnabledTest extends EmbeddedBrokerTestSupport {
|
||||
|
||||
protected Connection connection;
|
||||
protected boolean transacted;
|
||||
protected int authMode = Session.AUTO_ACKNOWLEDGE;
|
||||
|
||||
public void testTestUseConnectionCloseBrokerThenRestartInSameJVM() throws Exception {
|
||||
connection = connectionFactory.createConnection();
|
||||
useConnection(connection);
|
||||
connection.close();
|
||||
|
||||
broker.stop();
|
||||
broker = createBroker();
|
||||
startBroker();
|
||||
|
||||
connectionFactory = createConnectionFactory();
|
||||
connection = connectionFactory.createConnection();
|
||||
useConnection(connection);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
bindAddress = "tcp://localhost:0";
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConnectionFactory createConnectionFactory() throws Exception {
|
||||
return new ActiveMQConnectionFactory(broker.getTransportConnectors().get(0).getPublishableConnectString());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
if (connection != null) {
|
||||
connection.close();
|
||||
connection = null;
|
||||
}
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerService answer = new BrokerService();
|
||||
answer.setUseJmx(true);
|
||||
answer.setPersistent(isPersistent());
|
||||
answer.addConnector(bindAddress);
|
||||
return answer;
|
||||
}
|
||||
|
||||
protected void useConnection(Connection connection) throws Exception {
|
||||
connection.setClientID("foo");
|
||||
connection.start();
|
||||
Session session = connection.createSession(transacted, authMode);
|
||||
Destination destination = createDestination();
|
||||
MessageConsumer consumer = session.createConsumer(destination);
|
||||
MessageProducer producer = session.createProducer(destination);
|
||||
Message message = session.createTextMessage("Hello World");
|
||||
producer.send(message);
|
||||
Thread.sleep(1000);
|
||||
consumer.close();
|
||||
}
|
||||
}
|
|
@ -1,580 +0,0 @@
|
|||
/**
|
||||
* 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 javax.jms.DeliveryMode;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import junit.framework.Test;
|
||||
|
||||
import org.apache.activemq.command.ActiveMQDestination;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.apache.activemq.command.ActiveMQTopic;
|
||||
import org.apache.activemq.command.ConnectionInfo;
|
||||
import org.apache.activemq.command.ConsumerInfo;
|
||||
import org.apache.activemq.command.LocalTransactionId;
|
||||
import org.apache.activemq.command.Message;
|
||||
import org.apache.activemq.command.MessageAck;
|
||||
import org.apache.activemq.command.MessageId;
|
||||
import org.apache.activemq.command.ProducerInfo;
|
||||
import org.apache.activemq.command.SessionInfo;
|
||||
import org.apache.activemq.command.XATransactionId;
|
||||
|
||||
/**
|
||||
* Used to simulate the recovery that occurs when a broker shuts down.
|
||||
*/
|
||||
public class RecoveryBrokerTest extends BrokerRestartTestSupport {
|
||||
|
||||
/**
|
||||
* Used to verify that after a broker restart durable subscriptions that use
|
||||
* wild cards are still wild card subscription after broker restart.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
//need to revist!!!
|
||||
public void XtestWildCardSubscriptionPreservedOnRestart() throws Exception {
|
||||
ActiveMQDestination dest1 = new ActiveMQTopic("TEST.A");
|
||||
ActiveMQDestination dest2 = new ActiveMQTopic("TEST.B");
|
||||
ActiveMQDestination dest3 = new ActiveMQTopic("TEST.C");
|
||||
ActiveMQDestination wildDest = new ActiveMQTopic("TEST.>");
|
||||
|
||||
ArrayList<MessageId> sentBeforeRestart = new ArrayList<>();
|
||||
ArrayList<MessageId> sentBeforeCreateConsumer = new ArrayList<>();
|
||||
ArrayList<MessageId> sentAfterCreateConsumer = new ArrayList<>();
|
||||
|
||||
// Setup a first connection
|
||||
{
|
||||
StubConnection connection1 = createConnection();
|
||||
ConnectionInfo connectionInfo1 = createConnectionInfo();
|
||||
connectionInfo1.setClientId("A");
|
||||
SessionInfo sessionInfo1 = createSessionInfo(connectionInfo1);
|
||||
ProducerInfo producerInfo1 = createProducerInfo(sessionInfo1);
|
||||
connection1.send(connectionInfo1);
|
||||
connection1.send(sessionInfo1);
|
||||
connection1.send(producerInfo1);
|
||||
|
||||
// Create the durable subscription.
|
||||
ConsumerInfo consumerInfo1 = createConsumerInfo(sessionInfo1, wildDest);
|
||||
consumerInfo1.setSubscriptionName("test");
|
||||
consumerInfo1.setPrefetchSize(100);
|
||||
connection1.send(consumerInfo1);
|
||||
|
||||
// Close the subscription.
|
||||
connection1.send(closeConsumerInfo(consumerInfo1));
|
||||
|
||||
// Send the messages
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Message m = createMessage(producerInfo1, dest1, DeliveryMode.PERSISTENT);
|
||||
connection1.send(m);
|
||||
sentBeforeRestart.add(m.getMessageId());
|
||||
}
|
||||
connection1.request(closeConnectionInfo(connectionInfo1));
|
||||
connection1.stop();
|
||||
}
|
||||
|
||||
// Restart the broker.
|
||||
restartBroker();
|
||||
|
||||
// Get a connection to the new broker.
|
||||
{
|
||||
StubConnection connection2 = createConnection();
|
||||
ConnectionInfo connectionInfo2 = createConnectionInfo();
|
||||
connectionInfo2.setClientId("A");
|
||||
SessionInfo sessionInfo2 = createSessionInfo(connectionInfo2);
|
||||
connection2.send(connectionInfo2);
|
||||
connection2.send(sessionInfo2);
|
||||
|
||||
ProducerInfo producerInfo2 = createProducerInfo(sessionInfo2);
|
||||
connection2.send(producerInfo2);
|
||||
|
||||
// Send messages before the durable subscription is re-activated.
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Message m = createMessage(producerInfo2, dest2, DeliveryMode.PERSISTENT);
|
||||
connection2.send(m);
|
||||
sentBeforeCreateConsumer.add(m.getMessageId());
|
||||
}
|
||||
|
||||
// Re-open the subscription.
|
||||
ConsumerInfo consumerInfo2 = createConsumerInfo(sessionInfo2, wildDest);
|
||||
consumerInfo2.setSubscriptionName("test");
|
||||
consumerInfo2.setPrefetchSize(100);
|
||||
connection2.send(consumerInfo2);
|
||||
|
||||
// Send messages after the subscription is activated.
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Message m = createMessage(producerInfo2, dest3, DeliveryMode.PERSISTENT);
|
||||
connection2.send(m);
|
||||
sentAfterCreateConsumer.add(m.getMessageId());
|
||||
}
|
||||
|
||||
// We should get the recovered messages...
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Message m2 = receiveMessage(connection2);
|
||||
assertNotNull("Recovered message missing: " + i, m2);
|
||||
assertEquals(sentBeforeRestart.get(i), m2.getMessageId());
|
||||
}
|
||||
|
||||
// We should get get the messages that were sent before the sub was
|
||||
// reactivated.
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Message m2 = receiveMessage(connection2);
|
||||
assertNotNull("Before activated message missing: " + i, m2);
|
||||
assertEquals(sentBeforeCreateConsumer.get(i), m2.getMessageId());
|
||||
}
|
||||
|
||||
// We should get get the messages that were sent after the sub was
|
||||
// reactivated.
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Message m2 = receiveMessage(connection2);
|
||||
assertNotNull("After activated message missing: " + i, m2);
|
||||
assertEquals("" + i, sentAfterCreateConsumer.get(i), m2.getMessageId());
|
||||
}
|
||||
|
||||
assertNoMessagesLeft(connection2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testConsumedQueuePersistentMessagesLostOnRestart() throws Exception {
|
||||
|
||||
ActiveMQDestination destination = new ActiveMQQueue("TEST");
|
||||
|
||||
// Setup the producer and send the message.
|
||||
StubConnection connection = createConnection();
|
||||
ConnectionInfo connectionInfo = createConnectionInfo();
|
||||
SessionInfo sessionInfo = createSessionInfo(connectionInfo);
|
||||
ProducerInfo producerInfo = createProducerInfo(sessionInfo);
|
||||
connection.send(connectionInfo);
|
||||
connection.send(sessionInfo);
|
||||
connection.send(producerInfo);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Message message = createMessage(producerInfo, destination);
|
||||
message.setPersistent(true);
|
||||
connection.send(message);
|
||||
}
|
||||
|
||||
// Setup the consumer and receive the message.
|
||||
connection = createConnection();
|
||||
connectionInfo = createConnectionInfo();
|
||||
sessionInfo = createSessionInfo(connectionInfo);
|
||||
connection.send(connectionInfo);
|
||||
connection.send(sessionInfo);
|
||||
ConsumerInfo consumerInfo = createConsumerInfo(sessionInfo, destination);
|
||||
connection.send(consumerInfo);
|
||||
|
||||
// The we should get the messages.
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Message m2 = receiveMessage(connection);
|
||||
assertNotNull(m2);
|
||||
}
|
||||
|
||||
// restart the broker.
|
||||
restartBroker();
|
||||
|
||||
// No messages should be delivered.
|
||||
Message m = receiveMessage(connection);
|
||||
assertNull(m);
|
||||
}
|
||||
|
||||
public void testQueuePersistentUncommitedMessagesLostOnRestart() throws Exception {
|
||||
|
||||
ActiveMQDestination destination = new ActiveMQQueue("TEST");
|
||||
|
||||
// Setup the producer and send the message.
|
||||
StubConnection connection = createConnection();
|
||||
ConnectionInfo connectionInfo = createConnectionInfo();
|
||||
SessionInfo sessionInfo = createSessionInfo(connectionInfo);
|
||||
ProducerInfo producerInfo = createProducerInfo(sessionInfo);
|
||||
connection.send(connectionInfo);
|
||||
connection.send(sessionInfo);
|
||||
connection.send(producerInfo);
|
||||
|
||||
// Begin the transaction.
|
||||
LocalTransactionId txid = createLocalTransaction(sessionInfo);
|
||||
connection.send(createBeginTransaction(connectionInfo, txid));
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Message message = createMessage(producerInfo, destination);
|
||||
message.setPersistent(true);
|
||||
message.setTransactionId(txid);
|
||||
connection.send(message);
|
||||
}
|
||||
|
||||
// Don't commit
|
||||
|
||||
// restart the broker.
|
||||
restartBroker();
|
||||
|
||||
// Setup the consumer and receive the message.
|
||||
connection = createConnection();
|
||||
connectionInfo = createConnectionInfo();
|
||||
sessionInfo = createSessionInfo(connectionInfo);
|
||||
connection.send(connectionInfo);
|
||||
connection.send(sessionInfo);
|
||||
ConsumerInfo consumerInfo = createConsumerInfo(sessionInfo, destination);
|
||||
connection.send(consumerInfo);
|
||||
|
||||
// No messages should be delivered.
|
||||
Message m = receiveMessage(connection);
|
||||
assertNull(m);
|
||||
}
|
||||
|
||||
public void testTopicDurableConsumerHoldsPersistentMessageAfterRestart() throws Exception {
|
||||
|
||||
ActiveMQDestination destination = new ActiveMQTopic("TEST");
|
||||
|
||||
// Setup a first connection
|
||||
StubConnection connection1 = createConnection();
|
||||
ConnectionInfo connectionInfo1 = createConnectionInfo();
|
||||
connectionInfo1.setClientId("A");
|
||||
SessionInfo sessionInfo1 = createSessionInfo(connectionInfo1);
|
||||
ProducerInfo producerInfo1 = createProducerInfo(sessionInfo1);
|
||||
connection1.send(connectionInfo1);
|
||||
connection1.send(sessionInfo1);
|
||||
connection1.send(producerInfo1);
|
||||
|
||||
// Create the durable subscription.
|
||||
ConsumerInfo consumerInfo1 = createConsumerInfo(sessionInfo1, destination);
|
||||
consumerInfo1.setSubscriptionName("test");
|
||||
consumerInfo1.setPrefetchSize(100);
|
||||
connection1.send(consumerInfo1);
|
||||
|
||||
// Close the subscription.
|
||||
connection1.send(closeConsumerInfo(consumerInfo1));
|
||||
|
||||
// Send the messages
|
||||
connection1.send(createMessage(producerInfo1, destination, DeliveryMode.PERSISTENT));
|
||||
connection1.send(createMessage(producerInfo1, destination, DeliveryMode.PERSISTENT));
|
||||
connection1.send(createMessage(producerInfo1, destination, DeliveryMode.PERSISTENT));
|
||||
connection1.send(createMessage(producerInfo1, destination, DeliveryMode.PERSISTENT));
|
||||
connection1.request(closeConnectionInfo(connectionInfo1));
|
||||
// Restart the broker.
|
||||
restartBroker();
|
||||
|
||||
// Get a connection to the new broker.
|
||||
StubConnection connection2 = createConnection();
|
||||
ConnectionInfo connectionInfo2 = createConnectionInfo();
|
||||
connectionInfo2.setClientId("A");
|
||||
SessionInfo sessionInfo2 = createSessionInfo(connectionInfo2);
|
||||
connection2.send(connectionInfo2);
|
||||
connection2.send(sessionInfo2);
|
||||
|
||||
// Re-open the subscription.
|
||||
ConsumerInfo consumerInfo2 = createConsumerInfo(sessionInfo2, destination);
|
||||
consumerInfo2.setSubscriptionName("test");
|
||||
consumerInfo2.setPrefetchSize(100);
|
||||
connection2.send(consumerInfo2);
|
||||
|
||||
// The we should get the messages.
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Message m2 = receiveMessage(connection2);
|
||||
assertNotNull("Did not get message " + i, m2);
|
||||
}
|
||||
assertNoMessagesLeft(connection2);
|
||||
}
|
||||
|
||||
public void testQueuePersistentMessagesNotLostOnRestart() throws Exception {
|
||||
|
||||
ActiveMQDestination destination = new ActiveMQQueue("TEST");
|
||||
|
||||
// Setup the producer and send the message.
|
||||
StubConnection connection = createConnection();
|
||||
ConnectionInfo connectionInfo = createConnectionInfo();
|
||||
SessionInfo sessionInfo = createSessionInfo(connectionInfo);
|
||||
ProducerInfo producerInfo = createProducerInfo(sessionInfo);
|
||||
connection.send(connectionInfo);
|
||||
connection.send(sessionInfo);
|
||||
connection.send(producerInfo);
|
||||
Message message = createMessage(producerInfo, destination);
|
||||
message.setPersistent(true);
|
||||
connection.send(message);
|
||||
connection.request(closeConnectionInfo(connectionInfo));
|
||||
|
||||
// restart the broker.
|
||||
restartBroker();
|
||||
|
||||
// Setup the consumer and receive the message.
|
||||
connection = createConnection();
|
||||
connectionInfo = createConnectionInfo();
|
||||
sessionInfo = createSessionInfo(connectionInfo);
|
||||
connection.send(connectionInfo);
|
||||
connection.send(sessionInfo);
|
||||
ConsumerInfo consumerInfo = createConsumerInfo(sessionInfo, destination);
|
||||
connection.send(consumerInfo);
|
||||
|
||||
// Message should have been dropped due to broker restart.
|
||||
Message m = receiveMessage(connection);
|
||||
assertNotNull("Should have received a message by now!", m);
|
||||
assertEquals(m.getMessageId(), message.getMessageId());
|
||||
}
|
||||
|
||||
public void testQueueNonPersistentMessagesLostOnRestart() throws Exception {
|
||||
|
||||
ActiveMQDestination destination = new ActiveMQQueue("TEST");
|
||||
|
||||
// Setup the producer and send the message.
|
||||
StubConnection connection = createConnection();
|
||||
ConnectionInfo connectionInfo = createConnectionInfo();
|
||||
SessionInfo sessionInfo = createSessionInfo(connectionInfo);
|
||||
ProducerInfo producerInfo = createProducerInfo(sessionInfo);
|
||||
connection.send(connectionInfo);
|
||||
connection.send(sessionInfo);
|
||||
connection.send(producerInfo);
|
||||
Message message = createMessage(producerInfo, destination);
|
||||
message.setPersistent(false);
|
||||
connection.send(message);
|
||||
|
||||
// restart the broker.
|
||||
restartBroker();
|
||||
|
||||
// Setup the consumer and receive the message.
|
||||
connection = createConnection();
|
||||
connectionInfo = createConnectionInfo();
|
||||
sessionInfo = createSessionInfo(connectionInfo);
|
||||
connection.send(connectionInfo);
|
||||
connection.send(sessionInfo);
|
||||
ConsumerInfo consumerInfo = createConsumerInfo(sessionInfo, destination);
|
||||
connection.send(consumerInfo);
|
||||
|
||||
// Message should have been dropped due to broker restart.
|
||||
assertNoMessagesLeft(connection);
|
||||
}
|
||||
|
||||
public void testQueuePersistentCommittedMessagesNotLostOnRestart() throws Exception {
|
||||
|
||||
ActiveMQDestination destination = new ActiveMQQueue("TEST");
|
||||
|
||||
// Setup the producer and send the message.
|
||||
StubConnection connection = createConnection();
|
||||
ConnectionInfo connectionInfo = createConnectionInfo();
|
||||
SessionInfo sessionInfo = createSessionInfo(connectionInfo);
|
||||
ProducerInfo producerInfo = createProducerInfo(sessionInfo);
|
||||
connection.send(connectionInfo);
|
||||
connection.send(sessionInfo);
|
||||
connection.send(producerInfo);
|
||||
|
||||
// Begin the transaction.
|
||||
LocalTransactionId txid = createLocalTransaction(sessionInfo);
|
||||
connection.send(createBeginTransaction(connectionInfo, txid));
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Message message = createMessage(producerInfo, destination);
|
||||
message.setPersistent(true);
|
||||
message.setTransactionId(txid);
|
||||
connection.send(message);
|
||||
}
|
||||
|
||||
// Commit
|
||||
connection.send(createCommitTransaction1Phase(connectionInfo, txid));
|
||||
connection.request(closeConnectionInfo(connectionInfo));
|
||||
// restart the broker.
|
||||
restartBroker();
|
||||
|
||||
// Setup the consumer and receive the message.
|
||||
connection = createConnection();
|
||||
connectionInfo = createConnectionInfo();
|
||||
sessionInfo = createSessionInfo(connectionInfo);
|
||||
connection.send(connectionInfo);
|
||||
connection.send(sessionInfo);
|
||||
ConsumerInfo consumerInfo = createConsumerInfo(sessionInfo, destination);
|
||||
connection.send(consumerInfo);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Message m = receiveMessage(connection);
|
||||
assertNotNull(m);
|
||||
}
|
||||
|
||||
assertNoMessagesLeft(connection);
|
||||
}
|
||||
|
||||
public void testQueuePersistentCommittedAcksNotLostOnRestart() throws Exception {
|
||||
|
||||
ActiveMQDestination destination = new ActiveMQQueue("TEST");
|
||||
|
||||
// Setup the producer and send the message.
|
||||
StubConnection connection = createConnection();
|
||||
ConnectionInfo connectionInfo = createConnectionInfo();
|
||||
SessionInfo sessionInfo = createSessionInfo(connectionInfo);
|
||||
ProducerInfo producerInfo = createProducerInfo(sessionInfo);
|
||||
connection.send(connectionInfo);
|
||||
connection.send(sessionInfo);
|
||||
connection.send(producerInfo);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Message message = createMessage(producerInfo, destination);
|
||||
message.setPersistent(true);
|
||||
connection.send(message);
|
||||
}
|
||||
|
||||
// Setup the consumer and receive the message.
|
||||
ConsumerInfo consumerInfo = createConsumerInfo(sessionInfo, destination);
|
||||
connection.send(consumerInfo);
|
||||
|
||||
// Begin the transaction.
|
||||
LocalTransactionId txid = createLocalTransaction(sessionInfo);
|
||||
connection.send(createBeginTransaction(connectionInfo, txid));
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Message m = receiveMessage(connection);
|
||||
assertNotNull(m);
|
||||
MessageAck ack = createAck(consumerInfo, m, 1, MessageAck.STANDARD_ACK_TYPE);
|
||||
ack.setTransactionId(txid);
|
||||
connection.send(ack);
|
||||
}
|
||||
// Commit
|
||||
connection.send(createCommitTransaction1Phase(connectionInfo, txid));
|
||||
connection.request(closeConnectionInfo(connectionInfo));
|
||||
// restart the broker.
|
||||
restartBroker();
|
||||
|
||||
// Setup the consumer and receive the message.
|
||||
connection = createConnection();
|
||||
connectionInfo = createConnectionInfo();
|
||||
sessionInfo = createSessionInfo(connectionInfo);
|
||||
connection.send(connectionInfo);
|
||||
connection.send(sessionInfo);
|
||||
consumerInfo = createConsumerInfo(sessionInfo, destination);
|
||||
connection.send(consumerInfo);
|
||||
|
||||
// No messages should be delivered.
|
||||
Message m = receiveMessage(connection);
|
||||
assertNull(m);
|
||||
}
|
||||
|
||||
public void testQueuePersistentUncommitedAcksLostOnRestart() throws Exception {
|
||||
|
||||
ActiveMQDestination destination = new ActiveMQQueue("TEST");
|
||||
|
||||
// Setup the producer and send the message.
|
||||
StubConnection connection = createConnection();
|
||||
ConnectionInfo connectionInfo = createConnectionInfo();
|
||||
SessionInfo sessionInfo = createSessionInfo(connectionInfo);
|
||||
ProducerInfo producerInfo = createProducerInfo(sessionInfo);
|
||||
connection.send(connectionInfo);
|
||||
connection.send(sessionInfo);
|
||||
connection.send(producerInfo);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Message message = createMessage(producerInfo, destination);
|
||||
message.setPersistent(true);
|
||||
connection.send(message);
|
||||
}
|
||||
|
||||
// Setup the consumer and receive the message.
|
||||
ConsumerInfo consumerInfo = createConsumerInfo(sessionInfo, destination);
|
||||
connection.send(consumerInfo);
|
||||
|
||||
// Begin the transaction.
|
||||
LocalTransactionId txid = createLocalTransaction(sessionInfo);
|
||||
connection.send(createBeginTransaction(connectionInfo, txid));
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Message m = receiveMessage(connection);
|
||||
assertNotNull(m);
|
||||
MessageAck ack = createAck(consumerInfo, m, 1, MessageAck.STANDARD_ACK_TYPE);
|
||||
ack.setTransactionId(txid);
|
||||
connection.send(ack);
|
||||
}
|
||||
// Don't commit
|
||||
|
||||
// restart the broker.
|
||||
restartBroker();
|
||||
|
||||
// Setup the consumer and receive the message.
|
||||
connection = createConnection();
|
||||
connectionInfo = createConnectionInfo();
|
||||
sessionInfo = createSessionInfo(connectionInfo);
|
||||
connection.send(connectionInfo);
|
||||
connection.send(sessionInfo);
|
||||
consumerInfo = createConsumerInfo(sessionInfo, destination);
|
||||
connection.send(consumerInfo);
|
||||
|
||||
// All messages should be re-delivered.
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Message m = receiveMessage(connection);
|
||||
assertNotNull(m);
|
||||
}
|
||||
|
||||
assertNoMessagesLeft(connection);
|
||||
}
|
||||
|
||||
public void testQueuePersistentXAUncommitedAcksLostOnRestart() throws Exception {
|
||||
int NUMBER = 100;
|
||||
ActiveMQDestination destination = new ActiveMQQueue("TEST");
|
||||
|
||||
// Setup the producer and send the message.
|
||||
StubConnection connection = createConnection();
|
||||
ConnectionInfo connectionInfo = createConnectionInfo();
|
||||
SessionInfo sessionInfo = createSessionInfo(connectionInfo);
|
||||
ProducerInfo producerInfo = createProducerInfo(sessionInfo);
|
||||
connection.send(connectionInfo);
|
||||
connection.send(sessionInfo);
|
||||
connection.send(producerInfo);
|
||||
|
||||
for (int i = 0; i < NUMBER; i++) {
|
||||
Message message = createMessage(producerInfo, destination);
|
||||
message.setPersistent(true);
|
||||
connection.send(message);
|
||||
}
|
||||
|
||||
// Setup the consumer and receive the message.
|
||||
ConsumerInfo consumerInfo = createConsumerInfo(sessionInfo, destination);
|
||||
connection.send(consumerInfo);
|
||||
|
||||
// Begin the transaction.
|
||||
XATransactionId txid = createXATransaction(sessionInfo);
|
||||
connection.send(createBeginTransaction(connectionInfo, txid));
|
||||
Message m = null;
|
||||
for (int i = 0; i < NUMBER; i++) {
|
||||
m = receiveMessage(connection);
|
||||
assertNotNull(m);
|
||||
}
|
||||
MessageAck ack = createAck(consumerInfo, m, NUMBER, MessageAck.STANDARD_ACK_TYPE);
|
||||
ack.setTransactionId(txid);
|
||||
connection.send(ack);
|
||||
|
||||
// Don't commit
|
||||
|
||||
// restart the broker.
|
||||
restartBroker();
|
||||
|
||||
// Setup the consumer and receive the message.
|
||||
connection = createConnection();
|
||||
connectionInfo = createConnectionInfo();
|
||||
sessionInfo = createSessionInfo(connectionInfo);
|
||||
connection.send(connectionInfo);
|
||||
connection.send(sessionInfo);
|
||||
consumerInfo = createConsumerInfo(sessionInfo, destination);
|
||||
connection.send(consumerInfo);
|
||||
|
||||
// All messages should be re-delivered.
|
||||
for (int i = 0; i < NUMBER; i++) {
|
||||
m = receiveMessage(connection);
|
||||
assertNotNull(m);
|
||||
}
|
||||
|
||||
assertNoMessagesLeft(connection);
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return suite(RecoveryBrokerTest.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(suite());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,293 +0,0 @@
|
|||
/**
|
||||
* 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 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 javax.jms.TopicSubscriber;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnection;
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.TestSupport;
|
||||
import org.apache.activemq.broker.region.policy.PolicyEntry;
|
||||
import org.apache.activemq.broker.region.policy.PolicyMap;
|
||||
import org.apache.activemq.command.ActiveMQTopic;
|
||||
import org.apache.activemq.transport.failover.FailoverTransport;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@RunWith(value = Parameterized.class)
|
||||
public class RedeliveryRestartTest extends TestSupport {
|
||||
|
||||
private static final transient Logger LOG = LoggerFactory.getLogger(RedeliveryRestartTest.class);
|
||||
ActiveMQConnection connection;
|
||||
BrokerService broker = null;
|
||||
String queueName = "redeliveryRestartQ";
|
||||
|
||||
@Parameterized.Parameter
|
||||
public TestSupport.PersistenceAdapterChoice persistenceAdapterChoice = PersistenceAdapterChoice.KahaDB;
|
||||
|
||||
@Parameterized.Parameters(name = "Store={0}")
|
||||
public static Iterable<Object[]> data() {
|
||||
return Arrays.asList(new Object[][]{{TestSupport.PersistenceAdapterChoice.KahaDB}, {TestSupport.PersistenceAdapterChoice.JDBC}, {TestSupport.PersistenceAdapterChoice.LevelDB}});
|
||||
}
|
||||
|
||||
@Override
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
broker = new BrokerService();
|
||||
configureBroker(broker);
|
||||
broker.setDeleteAllMessagesOnStartup(true);
|
||||
broker.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
if (connection != null) {
|
||||
connection.close();
|
||||
}
|
||||
broker.stop();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
protected void configureBroker(BrokerService broker) throws Exception {
|
||||
PolicyMap policyMap = new PolicyMap();
|
||||
PolicyEntry policy = new PolicyEntry();
|
||||
policy.setPersistJMSRedelivered(true);
|
||||
policyMap.setDefaultEntry(policy);
|
||||
broker.setDestinationPolicy(policyMap);
|
||||
setPersistenceAdapter(broker, persistenceAdapterChoice);
|
||||
broker.addConnector("tcp://0.0.0.0:0");
|
||||
}
|
||||
|
||||
@org.junit.Test
|
||||
public void testValidateRedeliveryFlagAfterRestartNoTx() throws Exception {
|
||||
|
||||
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("failover:(" + broker.getTransportConnectors().get(0).getPublishableConnectString() + ")?jms.prefetchPolicy.all=0");
|
||||
connection = (ActiveMQConnection) connectionFactory.createConnection();
|
||||
connection.start();
|
||||
|
||||
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
|
||||
Destination destination = session.createQueue(queueName);
|
||||
populateDestination(10, destination, connection);
|
||||
|
||||
MessageConsumer consumer = session.createConsumer(destination);
|
||||
TextMessage msg = null;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
msg = (TextMessage) consumer.receive(20000);
|
||||
LOG.info("not redelivered? got: " + msg);
|
||||
assertNotNull("got the message", msg);
|
||||
assertEquals("first delivery", 1, msg.getLongProperty("JMSXDeliveryCount"));
|
||||
assertEquals("not a redelivery", false, msg.getJMSRedelivered());
|
||||
}
|
||||
consumer.close();
|
||||
|
||||
restartBroker();
|
||||
|
||||
// make failover aware of the restarted auto assigned port
|
||||
connection.getTransport().narrow(FailoverTransport.class).add(true, broker.getTransportConnectors().get(0).getPublishableConnectString());
|
||||
|
||||
consumer = session.createConsumer(destination);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
msg = (TextMessage) consumer.receive(4000);
|
||||
LOG.info("redelivered? got: " + msg);
|
||||
assertNotNull("got the message again", msg);
|
||||
assertEquals("re delivery flag", true, msg.getJMSRedelivered());
|
||||
assertEquals("redelivery count survives restart", 2, msg.getLongProperty("JMSXDeliveryCount"));
|
||||
msg.acknowledge();
|
||||
}
|
||||
|
||||
// consume the rest that were not redeliveries
|
||||
for (int i = 0; i < 5; i++) {
|
||||
msg = (TextMessage) consumer.receive(20000);
|
||||
LOG.info("not redelivered? got: " + msg);
|
||||
assertNotNull("got the message", msg);
|
||||
assertEquals("not a redelivery", false, msg.getJMSRedelivered());
|
||||
assertEquals("first delivery", 1, msg.getLongProperty("JMSXDeliveryCount"));
|
||||
msg.acknowledge();
|
||||
}
|
||||
connection.close();
|
||||
}
|
||||
|
||||
@org.junit.Test
|
||||
public void testDurableSubRedeliveryFlagAfterRestartNotSupported() throws Exception {
|
||||
|
||||
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("failover:(" + broker.getTransportConnectors().get(0).getPublishableConnectString() + ")?jms.prefetchPolicy.all=0");
|
||||
connection = (ActiveMQConnection) connectionFactory.createConnection();
|
||||
connection.setClientID("id");
|
||||
connection.start();
|
||||
|
||||
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
|
||||
ActiveMQTopic destination = new ActiveMQTopic(queueName);
|
||||
|
||||
TopicSubscriber durableSub = session.createDurableSubscriber(destination, "id");
|
||||
|
||||
populateDestination(10, destination, connection);
|
||||
|
||||
TextMessage msg = null;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
msg = (TextMessage) durableSub.receive(20000);
|
||||
LOG.info("not redelivered? got: " + msg);
|
||||
assertNotNull("got the message", msg);
|
||||
assertEquals("first delivery", 1, msg.getLongProperty("JMSXDeliveryCount"));
|
||||
assertEquals("not a redelivery", false, msg.getJMSRedelivered());
|
||||
}
|
||||
durableSub.close();
|
||||
|
||||
restartBroker();
|
||||
|
||||
// make failover aware of the restarted auto assigned port
|
||||
connection.getTransport().narrow(FailoverTransport.class).add(true, broker.getTransportConnectors().get(0).getPublishableConnectString());
|
||||
|
||||
durableSub = session.createDurableSubscriber(destination, "id");
|
||||
for (int i = 0; i < 10; i++) {
|
||||
msg = (TextMessage) durableSub.receive(4000);
|
||||
LOG.info("redelivered? got: " + msg);
|
||||
assertNotNull("got the message again", msg);
|
||||
assertEquals("no reDelivery flag", false, msg.getJMSRedelivered());
|
||||
msg.acknowledge();
|
||||
}
|
||||
connection.close();
|
||||
}
|
||||
|
||||
@org.junit.Test
|
||||
public void testValidateRedeliveryFlagAfterRestart() throws Exception {
|
||||
|
||||
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("failover:(" + broker.getTransportConnectors().get(0).getPublishableConnectString() + ")?jms.prefetchPolicy.all=0");
|
||||
connection = (ActiveMQConnection) connectionFactory.createConnection();
|
||||
connection.start();
|
||||
|
||||
Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
|
||||
Destination destination = session.createQueue(queueName);
|
||||
populateDestination(10, destination, connection);
|
||||
|
||||
MessageConsumer consumer = session.createConsumer(destination);
|
||||
TextMessage msg = null;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
msg = (TextMessage) consumer.receive(20000);
|
||||
LOG.info("not redelivered? got: " + msg);
|
||||
assertNotNull("got the message", msg);
|
||||
assertEquals("first delivery", 1, msg.getLongProperty("JMSXDeliveryCount"));
|
||||
assertEquals("not a redelivery", false, msg.getJMSRedelivered());
|
||||
}
|
||||
session.rollback();
|
||||
consumer.close();
|
||||
|
||||
restartBroker();
|
||||
|
||||
// make failover aware of the restarted auto assigned port
|
||||
connection.getTransport().narrow(FailoverTransport.class).add(true, broker.getTransportConnectors().get(0).getPublishableConnectString());
|
||||
|
||||
consumer = session.createConsumer(destination);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
msg = (TextMessage) consumer.receive(4000);
|
||||
LOG.info("redelivered? got: " + msg);
|
||||
assertNotNull("got the message again", msg);
|
||||
assertEquals("redelivery count survives restart", 2, msg.getLongProperty("JMSXDeliveryCount"));
|
||||
assertEquals("re delivery flag", true, msg.getJMSRedelivered());
|
||||
}
|
||||
session.commit();
|
||||
|
||||
// consume the rest that were not redeliveries
|
||||
for (int i = 0; i < 5; i++) {
|
||||
msg = (TextMessage) consumer.receive(20000);
|
||||
LOG.info("not redelivered? got: " + msg);
|
||||
assertNotNull("got the message", msg);
|
||||
assertEquals("first delivery", 1, msg.getLongProperty("JMSXDeliveryCount"));
|
||||
assertEquals("not a redelivery", false, msg.getJMSRedelivered());
|
||||
}
|
||||
session.commit();
|
||||
|
||||
connection.close();
|
||||
}
|
||||
|
||||
@org.junit.Test
|
||||
public void testValidateRedeliveryFlagAfterRecovery() throws Exception {
|
||||
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(broker.getTransportConnectors().get(0).getPublishableConnectString() + "?jms.prefetchPolicy.all=0");
|
||||
connection = (ActiveMQConnection) connectionFactory.createConnection();
|
||||
connection.start();
|
||||
|
||||
Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
|
||||
Destination destination = session.createQueue(queueName);
|
||||
populateDestination(1, destination, connection);
|
||||
|
||||
MessageConsumer consumer = session.createConsumer(destination);
|
||||
TextMessage msg = (TextMessage) consumer.receive(5000);
|
||||
LOG.info("got: " + msg);
|
||||
assertNotNull("got the message", msg);
|
||||
assertEquals("first delivery", 1, msg.getLongProperty("JMSXDeliveryCount"));
|
||||
assertEquals("not a redelivery", false, msg.getJMSRedelivered());
|
||||
|
||||
stopBrokerWithStoreFailure(broker, persistenceAdapterChoice);
|
||||
|
||||
broker = createRestartedBroker();
|
||||
broker.start();
|
||||
|
||||
connection.close();
|
||||
|
||||
connectionFactory = new ActiveMQConnectionFactory(broker.getTransportConnectors().get(0).getPublishableConnectString());
|
||||
connection = (ActiveMQConnection) connectionFactory.createConnection();
|
||||
connection.start();
|
||||
|
||||
session = connection.createSession(true, Session.SESSION_TRANSACTED);
|
||||
consumer = session.createConsumer(destination);
|
||||
msg = (TextMessage) consumer.receive(10000);
|
||||
assertNotNull("got the message again", msg);
|
||||
assertEquals("redelivery count survives restart", 2, msg.getLongProperty("JMSXDeliveryCount"));
|
||||
assertEquals("re delivery flag", true, msg.getJMSRedelivered());
|
||||
|
||||
session.commit();
|
||||
connection.close();
|
||||
}
|
||||
|
||||
private void restartBroker() throws Exception {
|
||||
broker.stop();
|
||||
broker.waitUntilStopped();
|
||||
broker = createRestartedBroker();
|
||||
broker.start();
|
||||
}
|
||||
|
||||
private BrokerService createRestartedBroker() throws Exception {
|
||||
broker = new BrokerService();
|
||||
configureBroker(broker);
|
||||
return broker;
|
||||
}
|
||||
|
||||
private void populateDestination(final int nbMessages,
|
||||
final Destination destination,
|
||||
javax.jms.Connection connection) throws JMSException {
|
||||
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
MessageProducer producer = session.createProducer(destination);
|
||||
for (int i = 1; i <= nbMessages; i++) {
|
||||
producer.send(session.createTextMessage("<hello id='" + i + "'/>"));
|
||||
}
|
||||
producer.close();
|
||||
session.close();
|
||||
}
|
||||
}
|
|
@ -1,468 +0,0 @@
|
|||
/**
|
||||
* 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 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 java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnection;
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.TestSupport;
|
||||
import org.apache.activemq.broker.region.policy.PolicyEntry;
|
||||
import org.apache.activemq.broker.region.policy.PolicyMap;
|
||||
import org.apache.activemq.broker.scheduler.JobSchedulerStore;
|
||||
import org.apache.activemq.command.ActiveMQDestination;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.apache.activemq.command.ActiveMQTopic;
|
||||
import org.apache.activemq.command.Message;
|
||||
import org.apache.activemq.command.ProducerId;
|
||||
import org.apache.activemq.store.MessageStore;
|
||||
import org.apache.activemq.store.PersistenceAdapter;
|
||||
import org.apache.activemq.store.ProxyMessageStore;
|
||||
import org.apache.activemq.store.ProxyTopicMessageStore;
|
||||
import org.apache.activemq.store.TopicMessageStore;
|
||||
import org.apache.activemq.store.TransactionStore;
|
||||
import org.apache.activemq.store.kahadb.KahaDBPersistenceAdapter;
|
||||
import org.apache.activemq.transport.tcp.TcpTransport;
|
||||
import org.apache.activemq.usage.SystemUsage;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class RedeliveryRestartWithExceptionTest extends TestSupport {
|
||||
|
||||
private static final transient Logger LOG = LoggerFactory.getLogger(RedeliveryRestartWithExceptionTest.class);
|
||||
ActiveMQConnection connection;
|
||||
BrokerService broker = null;
|
||||
String queueName = "redeliveryRestartQ";
|
||||
|
||||
@Override
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
broker = new BrokerService();
|
||||
configureBroker(broker, true);
|
||||
broker.setDeleteAllMessagesOnStartup(true);
|
||||
broker.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
if (connection != null) {
|
||||
connection.close();
|
||||
}
|
||||
broker.stop();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
protected void configureBroker(BrokerService broker, boolean throwExceptionOnUpdate) throws Exception {
|
||||
PolicyMap policyMap = new PolicyMap();
|
||||
PolicyEntry policy = new PolicyEntry();
|
||||
policy.setPersistJMSRedelivered(true);
|
||||
policyMap.setDefaultEntry(policy);
|
||||
broker.setDestinationPolicy(policyMap);
|
||||
broker.setPersistenceAdapter(new KahaDBWithUpdateExceptionPersistenceAdapter(throwExceptionOnUpdate));
|
||||
broker.addConnector("tcp://0.0.0.0:0");
|
||||
}
|
||||
|
||||
@org.junit.Test
|
||||
public void testValidateRedeliveryFlagAfterRestart() throws Exception {
|
||||
|
||||
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(broker.getTransportConnectors().get(0).getPublishableConnectString() + "?jms.prefetchPolicy.all=0");
|
||||
connection = (ActiveMQConnection) connectionFactory.createConnection();
|
||||
connection.start();
|
||||
|
||||
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
|
||||
Destination destination = session.createQueue(queueName);
|
||||
populateDestination(10, destination, connection, true);
|
||||
TextMessage msg = null;
|
||||
MessageConsumer consumer = session.createConsumer(destination);
|
||||
Exception expectedException = null;
|
||||
try {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
msg = (TextMessage) consumer.receive(5000);
|
||||
LOG.info("not redelivered? got: " + msg);
|
||||
assertNotNull("got the message", msg);
|
||||
assertTrue("Should not receive the 5th message", i < 4);
|
||||
//The first 4 messages will be ok but the 5th one should hit an exception in updateMessage and should not be delivered
|
||||
}
|
||||
} catch (Exception e) {
|
||||
//Expecting an exception and disconnect on the 5th message
|
||||
LOG.info("Got expected:", e);
|
||||
expectedException = e;
|
||||
}
|
||||
assertNotNull("Expecting an exception when updateMessage fails", expectedException);
|
||||
|
||||
consumer.close();
|
||||
connection.close();
|
||||
|
||||
restartBroker();
|
||||
|
||||
connectionFactory = new ActiveMQConnectionFactory(broker.getTransportConnectors().get(0).getPublishableConnectString() + "?jms.prefetchPolicy.all=0");
|
||||
connection = (ActiveMQConnection) connectionFactory.createConnection();
|
||||
connection.start();
|
||||
|
||||
session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
|
||||
destination = session.createQueue(queueName);
|
||||
consumer = session.createConsumer(destination);
|
||||
|
||||
// consume the messages that were previously delivered
|
||||
for (int i = 0; i < 4; i++) {
|
||||
msg = (TextMessage) consumer.receive(4000);
|
||||
LOG.info("redelivered? got: " + msg);
|
||||
assertNotNull("got the message again", msg);
|
||||
assertEquals("re delivery flag", true, msg.getJMSRedelivered());
|
||||
assertTrue("redelivery count survives restart", msg.getLongProperty("JMSXDeliveryCount") > 1);
|
||||
msg.acknowledge();
|
||||
}
|
||||
|
||||
// consume the rest that were not redeliveries
|
||||
for (int i = 0; i < 6; i++) {
|
||||
msg = (TextMessage) consumer.receive(4000);
|
||||
LOG.info("not redelivered? got: " + msg);
|
||||
assertNotNull("got the message", msg);
|
||||
assertEquals("not a redelivery", false, msg.getJMSRedelivered());
|
||||
assertEquals("first delivery", 1, msg.getLongProperty("JMSXDeliveryCount"));
|
||||
msg.acknowledge();
|
||||
}
|
||||
connection.close();
|
||||
}
|
||||
|
||||
@org.junit.Test
|
||||
public void testValidateRedeliveryFlagAfterTransientFailureConnectionDrop() throws Exception {
|
||||
|
||||
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(broker.getTransportConnectors().get(0).getPublishableConnectString() + "?jms.prefetchPolicy.all=0");
|
||||
connection = (ActiveMQConnection) connectionFactory.createConnection();
|
||||
connection.start();
|
||||
|
||||
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
|
||||
Destination destination = session.createQueue(queueName);
|
||||
populateDestination(10, destination, connection, true);
|
||||
TextMessage msg = null;
|
||||
MessageConsumer consumer = session.createConsumer(destination);
|
||||
Exception expectedException = null;
|
||||
try {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
msg = (TextMessage) consumer.receive(5000);
|
||||
LOG.info("not redelivered? got: " + msg);
|
||||
assertNotNull("got the message", msg);
|
||||
assertTrue("Should not receive the 5th message", i < 4);
|
||||
//The first 4 messages will be ok but the 5th one should hit an exception in updateMessage and should not be delivered
|
||||
}
|
||||
} catch (Exception e) {
|
||||
//Expecting an exception and disconnect on the 5th message
|
||||
LOG.info("Got expected:", e);
|
||||
expectedException = e;
|
||||
}
|
||||
assertNotNull("Expecting an exception when updateMessage fails", expectedException);
|
||||
|
||||
consumer.close();
|
||||
connection.close();
|
||||
|
||||
connection = (ActiveMQConnection) connectionFactory.createConnection();
|
||||
connection.start();
|
||||
|
||||
session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
|
||||
destination = session.createQueue(queueName);
|
||||
consumer = session.createConsumer(destination);
|
||||
|
||||
// consume the messages that were previously delivered
|
||||
for (int i = 0; i < 4; i++) {
|
||||
msg = (TextMessage) consumer.receive(4000);
|
||||
LOG.info("redelivered? got: " + msg);
|
||||
assertNotNull("got the message again", msg);
|
||||
assertEquals("re delivery flag on:" + i, true, msg.getJMSRedelivered());
|
||||
assertTrue("redelivery count survives reconnect for:" + i, msg.getLongProperty("JMSXDeliveryCount") > 1);
|
||||
msg.acknowledge();
|
||||
}
|
||||
|
||||
// consume the rest that were not redeliveries
|
||||
for (int i = 0; i < 6; i++) {
|
||||
msg = (TextMessage) consumer.receive(4000);
|
||||
LOG.info("not redelivered? got: " + msg);
|
||||
assertNotNull("got the message", msg);
|
||||
assertEquals("not a redelivery", false, msg.getJMSRedelivered());
|
||||
assertEquals("first delivery", 1, msg.getLongProperty("JMSXDeliveryCount"));
|
||||
msg.acknowledge();
|
||||
}
|
||||
connection.close();
|
||||
}
|
||||
|
||||
@org.junit.Test
|
||||
public void testValidateRedeliveryFlagOnNonPersistentAfterTransientFailureConnectionDrop() throws Exception {
|
||||
|
||||
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(broker.getTransportConnectors().get(0).getPublishableConnectString() + "?jms.prefetchPolicy.all=0");
|
||||
connection = (ActiveMQConnection) connectionFactory.createConnection();
|
||||
connection.start();
|
||||
|
||||
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
|
||||
Destination destination = session.createQueue(queueName);
|
||||
populateDestination(10, destination, connection, false);
|
||||
TextMessage msg = null;
|
||||
MessageConsumer consumer = session.createConsumer(destination);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
msg = (TextMessage) consumer.receive(5000);
|
||||
assertNotNull("got the message", msg);
|
||||
assertFalse("not redelivered", msg.getJMSRedelivered());
|
||||
}
|
||||
|
||||
connection.getTransport().narrow(TcpTransport.class).getTransportListener().onException(new IOException("Die"));
|
||||
|
||||
connection = (ActiveMQConnection) connectionFactory.createConnection();
|
||||
connection.start();
|
||||
|
||||
session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
|
||||
destination = session.createQueue(queueName);
|
||||
consumer = session.createConsumer(destination);
|
||||
|
||||
// consume the messages that were previously delivered
|
||||
for (int i = 0; i < 5; i++) {
|
||||
msg = (TextMessage) consumer.receive(4000);
|
||||
LOG.info("redelivered? got: " + msg);
|
||||
assertNotNull("got the message again", msg);
|
||||
assertEquals("redelivery flag set on:" + i, true, msg.getJMSRedelivered());
|
||||
assertTrue("redelivery count survives reconnect for:" + i, msg.getLongProperty("JMSXDeliveryCount") > 1);
|
||||
msg.acknowledge();
|
||||
}
|
||||
|
||||
// consume the rest that were not redeliveries
|
||||
for (int i = 0; i < 5; i++) {
|
||||
msg = (TextMessage) consumer.receive(4000);
|
||||
LOG.info("not redelivered? got: " + msg);
|
||||
assertNotNull("got the message", msg);
|
||||
assertEquals("not a redelivery", false, msg.getJMSRedelivered());
|
||||
assertEquals("first delivery", 1, msg.getLongProperty("JMSXDeliveryCount"));
|
||||
msg.acknowledge();
|
||||
}
|
||||
connection.close();
|
||||
}
|
||||
|
||||
private void restartBroker() throws Exception {
|
||||
broker.stop();
|
||||
broker.waitUntilStopped();
|
||||
broker = createRestartedBroker();
|
||||
broker.start();
|
||||
}
|
||||
|
||||
private BrokerService createRestartedBroker() throws Exception {
|
||||
broker = new BrokerService();
|
||||
configureBroker(broker, false);
|
||||
return broker;
|
||||
}
|
||||
|
||||
private void populateDestination(final int nbMessages,
|
||||
final Destination destination,
|
||||
javax.jms.Connection connection,
|
||||
boolean persistent) throws JMSException {
|
||||
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
MessageProducer producer = session.createProducer(destination);
|
||||
producer.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
|
||||
for (int i = 1; i <= nbMessages; i++) {
|
||||
producer.send(session.createTextMessage("<hello id='" + i + "'/>"));
|
||||
}
|
||||
producer.close();
|
||||
session.close();
|
||||
}
|
||||
|
||||
private class KahaDBWithUpdateExceptionPersistenceAdapter implements PersistenceAdapter {
|
||||
|
||||
private KahaDBPersistenceAdapter kahaDB = new KahaDBPersistenceAdapter();
|
||||
private boolean throwExceptionOnUpdate;
|
||||
|
||||
public KahaDBWithUpdateExceptionPersistenceAdapter(boolean throwExceptionOnUpdate) {
|
||||
this.throwExceptionOnUpdate = throwExceptionOnUpdate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() throws Exception {
|
||||
kahaDB.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() throws Exception {
|
||||
kahaDB.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ActiveMQDestination> getDestinations() {
|
||||
return kahaDB.getDestinations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageStore createQueueMessageStore(ActiveMQQueue destination) throws IOException {
|
||||
MessageStore proxyMessageStoreWithException = new ProxyMessageStoreWithUpdateException(kahaDB.createQueueMessageStore(destination), throwExceptionOnUpdate);
|
||||
return proxyMessageStoreWithException;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TopicMessageStore createTopicMessageStore(ActiveMQTopic destination) throws IOException {
|
||||
TopicMessageStore proxyMessageStoreWithException = new ProxyTopicMessageStoreWithUpdateException(kahaDB.createTopicMessageStore(destination), throwExceptionOnUpdate);
|
||||
return proxyMessageStoreWithException;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JobSchedulerStore createJobSchedulerStore() throws IOException, UnsupportedOperationException {
|
||||
return kahaDB.createJobSchedulerStore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeQueueMessageStore(ActiveMQQueue destination) {
|
||||
kahaDB.removeQueueMessageStore(destination);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTopicMessageStore(ActiveMQTopic destination) {
|
||||
kahaDB.removeTopicMessageStore(destination);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionStore createTransactionStore() throws IOException {
|
||||
return kahaDB.createTransactionStore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginTransaction(ConnectionContext context) throws IOException {
|
||||
kahaDB.beginTransaction(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commitTransaction(ConnectionContext context) throws IOException {
|
||||
kahaDB.commitTransaction(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollbackTransaction(ConnectionContext context) throws IOException {
|
||||
kahaDB.rollbackTransaction(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastMessageBrokerSequenceId() throws IOException {
|
||||
return kahaDB.getLastMessageBrokerSequenceId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAllMessages() throws IOException {
|
||||
kahaDB.deleteAllMessages();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUsageManager(SystemUsage usageManager) {
|
||||
kahaDB.setUsageManager(usageManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBrokerName(String brokerName) {
|
||||
kahaDB.setBrokerName(brokerName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirectory(File dir) {
|
||||
kahaDB.setDirectory(dir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getDirectory() {
|
||||
return kahaDB.getDirectory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkpoint(boolean sync) throws IOException {
|
||||
kahaDB.checkpoint(sync);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long size() {
|
||||
return kahaDB.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastProducerSequenceId(ProducerId id) throws IOException {
|
||||
return kahaDB.getLastProducerSequenceId(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void allowIOResumption() {
|
||||
kahaDB.allowIOResumption();
|
||||
}
|
||||
}
|
||||
|
||||
private class ProxyMessageStoreWithUpdateException extends ProxyMessageStore {
|
||||
|
||||
private boolean throwExceptionOnUpdate;
|
||||
private int numBeforeException = 4;
|
||||
|
||||
public ProxyMessageStoreWithUpdateException(MessageStore delegate, boolean throwExceptionOnUpdate) {
|
||||
super(delegate);
|
||||
this.throwExceptionOnUpdate = throwExceptionOnUpdate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMessage(Message message) throws IOException {
|
||||
if (throwExceptionOnUpdate) {
|
||||
if (numBeforeException > 0) {
|
||||
numBeforeException--;
|
||||
super.updateMessage(message);
|
||||
} else {
|
||||
// lets only do it once so we can validate transient store failure
|
||||
throwExceptionOnUpdate = false;
|
||||
|
||||
//A message that has never been delivered will hit this exception
|
||||
throw new IOException("Hit our simulated exception writing the update to disk");
|
||||
}
|
||||
} else {
|
||||
super.updateMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ProxyTopicMessageStoreWithUpdateException extends ProxyTopicMessageStore {
|
||||
|
||||
private boolean throwExceptionOnUpdate;
|
||||
private int numBeforeException = 4;
|
||||
|
||||
public ProxyTopicMessageStoreWithUpdateException(TopicMessageStore delegate, boolean throwExceptionOnUpdate) {
|
||||
super(delegate);
|
||||
this.throwExceptionOnUpdate = throwExceptionOnUpdate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMessage(Message message) throws IOException {
|
||||
if (throwExceptionOnUpdate) {
|
||||
if (numBeforeException > 0) {
|
||||
numBeforeException--;
|
||||
super.updateMessage(message);
|
||||
} else {
|
||||
//A message that has never been delivered will hit this exception
|
||||
throw new IOException("Hit our simulated exception writing the update to disk");
|
||||
}
|
||||
} else {
|
||||
super.updateMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
/**
|
||||
* 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 javax.jms.Message;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.activemq.spring.SpringConsumer;
|
||||
import org.apache.activemq.spring.SpringProducer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.support.AbstractApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
public class SpringTest extends TestCase {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SpringTest.class);
|
||||
|
||||
protected AbstractApplicationContext context;
|
||||
protected SpringConsumer consumer;
|
||||
protected SpringProducer producer;
|
||||
|
||||
public void testSenderWithSpringXml() throws Exception {
|
||||
assertSenderConfig("org/apache/activemq/broker/spring.xml");
|
||||
}
|
||||
|
||||
/**
|
||||
* assert method that is used by all the test method to send and receive messages
|
||||
* based on each spring configuration.
|
||||
*
|
||||
* @param config
|
||||
* @throws Exception
|
||||
*/
|
||||
protected void assertSenderConfig(String config) throws Exception {
|
||||
context = new ClassPathXmlApplicationContext(config);
|
||||
|
||||
consumer = (SpringConsumer) context.getBean("consumer");
|
||||
assertTrue("Found a valid consumer", consumer != null);
|
||||
|
||||
consumer.start();
|
||||
|
||||
producer = (SpringProducer) context.getBean("producer");
|
||||
assertTrue("Found a valid producer", producer != null);
|
||||
|
||||
consumer.flushMessages();
|
||||
producer.start();
|
||||
|
||||
// lets sleep a little to give the JMS time to dispatch stuff
|
||||
consumer.waitForMessagesToArrive(producer.getMessageCount());
|
||||
|
||||
// now lets check that the consumer has received some messages
|
||||
List<Message> messages = consumer.flushMessages();
|
||||
LOG.info("Consumer has received messages....");
|
||||
for (Message message : messages) {
|
||||
LOG.info("Received: " + message);
|
||||
}
|
||||
|
||||
assertEquals("Message count", producer.getMessageCount(), messages.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up method.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
if (consumer != null) {
|
||||
consumer.stop();
|
||||
}
|
||||
if (producer != null) {
|
||||
producer.stop();
|
||||
}
|
||||
|
||||
if (context != null) {
|
||||
context.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
if (System.getProperty("basedir") == null) {
|
||||
File file = new File(".");
|
||||
System.setProperty("basedir", file.getAbsolutePath());
|
||||
}
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,163 +0,0 @@
|
|||
/**
|
||||
* 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.util.ThreadTracker;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.BlockJUnit4ClassRunner;
|
||||
|
||||
@RunWith(BlockJUnit4ClassRunner.class)
|
||||
public class TopicSubscriptionTest extends QueueSubscriptionTest {
|
||||
|
||||
@Override
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
durable = true;
|
||||
topic = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
ThreadTracker.result();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testManyProducersManyConsumers() throws Exception {
|
||||
consumerCount = 40;
|
||||
producerCount = 20;
|
||||
messageCount = 100;
|
||||
messageSize = 1;
|
||||
prefetchCount = 10;
|
||||
|
||||
doMultipleClientsTest();
|
||||
|
||||
assertTotalMessagesReceived(messageCount * producerCount * consumerCount);
|
||||
assertDestinationMemoryUsageGoesToZero();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testOneProducerTwoConsumersLargeMessagesOnePrefetch() throws Exception {
|
||||
consumerCount = 2;
|
||||
producerCount = 1;
|
||||
messageCount = 10;
|
||||
messageSize = 1024 * 1024 * 1; // 1 MB
|
||||
prefetchCount = 1;
|
||||
|
||||
doMultipleClientsTest();
|
||||
|
||||
assertTotalMessagesReceived(messageCount * consumerCount * producerCount);
|
||||
assertDestinationMemoryUsageGoesToZero();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testOneProducerTwoConsumersSmallMessagesOnePrefetch() throws Exception {
|
||||
consumerCount = 2;
|
||||
producerCount = 1;
|
||||
prefetchCount = 1;
|
||||
messageSize = 1024;
|
||||
messageCount = 1000;
|
||||
|
||||
doMultipleClientsTest();
|
||||
|
||||
assertTotalMessagesReceived(messageCount * consumerCount * producerCount);
|
||||
assertDestinationMemoryUsageGoesToZero();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testOneProducerTwoConsumersSmallMessagesLargePrefetch() throws Exception {
|
||||
consumerCount = 2;
|
||||
producerCount = 1;
|
||||
messageCount = 1000;
|
||||
messageSize = 1024;
|
||||
prefetchCount = messageCount * 2;
|
||||
|
||||
doMultipleClientsTest();
|
||||
|
||||
assertTotalMessagesReceived(messageCount * consumerCount * producerCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testOneProducerTwoConsumersLargeMessagesLargePrefetch() throws Exception {
|
||||
consumerCount = 2;
|
||||
producerCount = 1;
|
||||
messageCount = 10;
|
||||
messageSize = 1024 * 1024 * 1; // 1 MB
|
||||
prefetchCount = messageCount * 2;
|
||||
|
||||
doMultipleClientsTest();
|
||||
|
||||
assertTotalMessagesReceived(messageCount * consumerCount * producerCount);
|
||||
assertDestinationMemoryUsageGoesToZero();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testOneProducerManyConsumersFewMessages() throws Exception {
|
||||
consumerCount = 50;
|
||||
producerCount = 1;
|
||||
messageCount = 10;
|
||||
messageSize = 1; // 1 byte
|
||||
prefetchCount = 10;
|
||||
|
||||
doMultipleClientsTest();
|
||||
|
||||
assertTotalMessagesReceived(messageCount * consumerCount * producerCount);
|
||||
assertDestinationMemoryUsageGoesToZero();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testOneProducerManyConsumersManyMessages() throws Exception {
|
||||
consumerCount = 50;
|
||||
producerCount = 1;
|
||||
messageCount = 100;
|
||||
messageSize = 1; // 1 byte
|
||||
prefetchCount = 10;
|
||||
|
||||
doMultipleClientsTest();
|
||||
|
||||
assertTotalMessagesReceived(messageCount * consumerCount * producerCount);
|
||||
assertDestinationMemoryUsageGoesToZero();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testManyProducersOneConsumer() throws Exception {
|
||||
consumerCount = 1;
|
||||
producerCount = 20;
|
||||
messageCount = 100;
|
||||
messageSize = 1; // 1 byte
|
||||
prefetchCount = 10;
|
||||
|
||||
doMultipleClientsTest();
|
||||
|
||||
assertTotalMessagesReceived(messageCount * producerCount * consumerCount);
|
||||
assertDestinationMemoryUsageGoesToZero();
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,329 +0,0 @@
|
|||
/**
|
||||
* 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.advisory;
|
||||
|
||||
import junit.framework.Test;
|
||||
|
||||
import org.apache.activemq.advisory.AdvisorySupport;
|
||||
import org.apache.activemq.broker.BrokerTestSupport;
|
||||
import org.apache.activemq.broker.StubConnection;
|
||||
import org.apache.activemq.command.ActiveMQDestination;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.apache.activemq.command.ConnectionInfo;
|
||||
import org.apache.activemq.command.ConsumerInfo;
|
||||
import org.apache.activemq.command.Message;
|
||||
import org.apache.activemq.command.ProducerInfo;
|
||||
import org.apache.activemq.command.RemoveInfo;
|
||||
import org.apache.activemq.command.SessionInfo;
|
||||
|
||||
public class AdvisoryBrokerTest extends BrokerTestSupport {
|
||||
|
||||
public void testConnectionAdvisories() throws Exception {
|
||||
|
||||
ActiveMQDestination destination = AdvisorySupport.getConnectionAdvisoryTopic();
|
||||
|
||||
// Setup a first connection
|
||||
StubConnection connection1 = createConnection();
|
||||
ConnectionInfo connectionInfo1 = createConnectionInfo();
|
||||
SessionInfo sessionInfo1 = createSessionInfo(connectionInfo1);
|
||||
ConsumerInfo consumerInfo1 = createConsumerInfo(sessionInfo1, destination);
|
||||
consumerInfo1.setPrefetchSize(100);
|
||||
|
||||
connection1.send(connectionInfo1);
|
||||
connection1.send(sessionInfo1);
|
||||
connection1.send(consumerInfo1);
|
||||
|
||||
// We should get an advisory of our own connection.
|
||||
Message m1 = receiveMessage(connection1);
|
||||
assertNotNull(m1);
|
||||
assertNotNull(m1.getDataStructure());
|
||||
assertEquals(((ConnectionInfo) m1.getDataStructure()).getConnectionId(), connectionInfo1.getConnectionId());
|
||||
|
||||
// Setup a second connection
|
||||
StubConnection connection2 = createConnection();
|
||||
ConnectionInfo connectionInfo2 = createConnectionInfo();
|
||||
connection2.send(connectionInfo2);
|
||||
|
||||
// We should get an advisory of the second connection.
|
||||
m1 = receiveMessage(connection1);
|
||||
assertNotNull(m1);
|
||||
assertNotNull(m1.getDataStructure());
|
||||
assertEquals(((ConnectionInfo) m1.getDataStructure()).getConnectionId(), connectionInfo2.getConnectionId());
|
||||
|
||||
// Close the second connection.
|
||||
connection2.send(closeConnectionInfo(connectionInfo2));
|
||||
connection2.stop();
|
||||
|
||||
// We should get an advisory of the second connection closing
|
||||
m1 = receiveMessage(connection1);
|
||||
assertNotNull(m1);
|
||||
assertNotNull(m1.getDataStructure());
|
||||
RemoveInfo r = (RemoveInfo) m1.getDataStructure();
|
||||
assertEquals(r.getObjectId(), connectionInfo2.getConnectionId());
|
||||
|
||||
assertNoMessagesLeft(connection1);
|
||||
}
|
||||
|
||||
public void testConsumerAdvisories() throws Exception {
|
||||
|
||||
ActiveMQDestination queue = new ActiveMQQueue("test");
|
||||
ActiveMQDestination destination = AdvisorySupport.getConsumerAdvisoryTopic(queue);
|
||||
|
||||
// Setup a first connection
|
||||
StubConnection connection1 = createConnection();
|
||||
ConnectionInfo connectionInfo1 = createConnectionInfo();
|
||||
SessionInfo sessionInfo1 = createSessionInfo(connectionInfo1);
|
||||
ConsumerInfo consumerInfo1 = createConsumerInfo(sessionInfo1, destination);
|
||||
consumerInfo1.setPrefetchSize(100);
|
||||
|
||||
connection1.send(connectionInfo1);
|
||||
connection1.send(sessionInfo1);
|
||||
connection1.send(consumerInfo1);
|
||||
|
||||
// We should not see and advisory for the advisory consumer.
|
||||
assertNoMessagesLeft(connection1);
|
||||
|
||||
// Setup a second consumer.
|
||||
StubConnection connection2 = createConnection();
|
||||
ConnectionInfo connectionInfo2 = createConnectionInfo();
|
||||
SessionInfo sessionInfo2 = createSessionInfo(connectionInfo2);
|
||||
ConsumerInfo consumerInfo2 = createConsumerInfo(sessionInfo2, queue);
|
||||
consumerInfo1.setPrefetchSize(100);
|
||||
|
||||
connection2.send(connectionInfo2);
|
||||
connection2.send(sessionInfo2);
|
||||
connection2.send(consumerInfo2);
|
||||
|
||||
// We should get an advisory of the new consumer.
|
||||
Message m1 = receiveMessage(connection1);
|
||||
assertNotNull(m1);
|
||||
assertNotNull(m1.getDataStructure());
|
||||
assertEquals(((ConsumerInfo) m1.getDataStructure()).getConsumerId(), consumerInfo2.getConsumerId());
|
||||
|
||||
// Close the second connection.
|
||||
connection2.request(closeConnectionInfo(connectionInfo2));
|
||||
connection2.stop();
|
||||
|
||||
// We should get an advisory of the consumer closing
|
||||
m1 = receiveMessage(connection1);
|
||||
assertNotNull(m1);
|
||||
assertNotNull(m1.getDataStructure());
|
||||
RemoveInfo r = (RemoveInfo) m1.getDataStructure();
|
||||
assertEquals(r.getObjectId(), consumerInfo2.getConsumerId());
|
||||
|
||||
assertNoMessagesLeft(connection2);
|
||||
}
|
||||
|
||||
public void testConsumerAdvisoriesReplayed() throws Exception {
|
||||
|
||||
ActiveMQDestination queue = new ActiveMQQueue("test");
|
||||
ActiveMQDestination destination = AdvisorySupport.getConsumerAdvisoryTopic(queue);
|
||||
|
||||
// Setup a first connection
|
||||
StubConnection connection1 = createConnection();
|
||||
ConnectionInfo connectionInfo1 = createConnectionInfo();
|
||||
SessionInfo sessionInfo1 = createSessionInfo(connectionInfo1);
|
||||
|
||||
connection1.send(connectionInfo1);
|
||||
connection1.send(sessionInfo1);
|
||||
|
||||
// Setup a second consumer.
|
||||
StubConnection connection2 = createConnection();
|
||||
ConnectionInfo connectionInfo2 = createConnectionInfo();
|
||||
SessionInfo sessionInfo2 = createSessionInfo(connectionInfo2);
|
||||
ConsumerInfo consumerInfo2 = createConsumerInfo(sessionInfo2, queue);
|
||||
consumerInfo2.setPrefetchSize(100);
|
||||
connection2.send(connectionInfo2);
|
||||
connection2.send(sessionInfo2);
|
||||
connection2.send(consumerInfo2);
|
||||
|
||||
// We should get an advisory of the previous consumer.
|
||||
ConsumerInfo consumerInfo1 = createConsumerInfo(sessionInfo1, destination);
|
||||
consumerInfo1.setPrefetchSize(100);
|
||||
connection1.send(consumerInfo1);
|
||||
|
||||
Message m1 = receiveMessage(connection1);
|
||||
assertNotNull(m1);
|
||||
assertNotNull(m1.getDataStructure());
|
||||
assertEquals(((ConsumerInfo) m1.getDataStructure()).getConsumerId(), consumerInfo2.getConsumerId());
|
||||
|
||||
// Close the second connection.
|
||||
connection2.request(closeConnectionInfo(connectionInfo2));
|
||||
connection2.stop();
|
||||
|
||||
// We should get an advisory of the consumer closing
|
||||
m1 = receiveMessage(connection1);
|
||||
assertNotNull(m1);
|
||||
assertNotNull(m1.getDataStructure());
|
||||
RemoveInfo r = (RemoveInfo) m1.getDataStructure();
|
||||
assertEquals(r.getObjectId(), consumerInfo2.getConsumerId());
|
||||
|
||||
assertNoMessagesLeft(connection2);
|
||||
}
|
||||
|
||||
public void testProducerAdvisories() throws Exception {
|
||||
|
||||
ActiveMQDestination queue = new ActiveMQQueue("test");
|
||||
ActiveMQDestination destination = AdvisorySupport.getProducerAdvisoryTopic(queue);
|
||||
|
||||
// Setup a first connection
|
||||
StubConnection connection1 = createConnection();
|
||||
ConnectionInfo connectionInfo1 = createConnectionInfo();
|
||||
SessionInfo sessionInfo1 = createSessionInfo(connectionInfo1);
|
||||
ConsumerInfo consumerInfo1 = createConsumerInfo(sessionInfo1, destination);
|
||||
consumerInfo1.setPrefetchSize(100);
|
||||
|
||||
connection1.send(connectionInfo1);
|
||||
connection1.send(sessionInfo1);
|
||||
connection1.send(consumerInfo1);
|
||||
|
||||
assertNoMessagesLeft(connection1);
|
||||
|
||||
// Setup a producer.
|
||||
StubConnection connection2 = createConnection();
|
||||
ConnectionInfo connectionInfo2 = createConnectionInfo();
|
||||
SessionInfo sessionInfo2 = createSessionInfo(connectionInfo2);
|
||||
ProducerInfo producerInfo2 = createProducerInfo(sessionInfo2);
|
||||
producerInfo2.setDestination(queue);
|
||||
|
||||
connection2.send(connectionInfo2);
|
||||
connection2.send(sessionInfo2);
|
||||
connection2.send(producerInfo2);
|
||||
|
||||
// We should get an advisory of the new producer.
|
||||
Message m1 = receiveMessage(connection1);
|
||||
assertNotNull(m1);
|
||||
assertNotNull(m1.getDataStructure());
|
||||
assertEquals(((ProducerInfo) m1.getDataStructure()).getProducerId(), producerInfo2.getProducerId());
|
||||
|
||||
// Close the second connection.
|
||||
connection2.request(closeConnectionInfo(connectionInfo2));
|
||||
connection2.stop();
|
||||
|
||||
// We should get an advisory of the producer closing
|
||||
m1 = receiveMessage(connection1);
|
||||
assertNotNull(m1);
|
||||
assertNotNull(m1.getDataStructure());
|
||||
RemoveInfo r = (RemoveInfo) m1.getDataStructure();
|
||||
assertEquals(r.getObjectId(), producerInfo2.getProducerId());
|
||||
|
||||
assertNoMessagesLeft(connection2);
|
||||
}
|
||||
|
||||
public void testProducerAdvisoriesReplayed() throws Exception {
|
||||
|
||||
ActiveMQDestination queue = new ActiveMQQueue("test");
|
||||
ActiveMQDestination destination = AdvisorySupport.getProducerAdvisoryTopic(queue);
|
||||
|
||||
// Setup a first connection
|
||||
StubConnection connection1 = createConnection();
|
||||
ConnectionInfo connectionInfo1 = createConnectionInfo();
|
||||
SessionInfo sessionInfo1 = createSessionInfo(connectionInfo1);
|
||||
|
||||
connection1.send(connectionInfo1);
|
||||
connection1.send(sessionInfo1);
|
||||
|
||||
// Setup a producer.
|
||||
StubConnection connection2 = createConnection();
|
||||
ConnectionInfo connectionInfo2 = createConnectionInfo();
|
||||
SessionInfo sessionInfo2 = createSessionInfo(connectionInfo2);
|
||||
ProducerInfo producerInfo2 = createProducerInfo(sessionInfo2);
|
||||
producerInfo2.setDestination(queue);
|
||||
|
||||
connection2.send(connectionInfo2);
|
||||
connection2.send(sessionInfo2);
|
||||
connection2.send(producerInfo2);
|
||||
|
||||
// Create the advisory consumer.. it should see the previous producer
|
||||
ConsumerInfo consumerInfo1 = createConsumerInfo(sessionInfo1, destination);
|
||||
consumerInfo1.setPrefetchSize(100);
|
||||
connection1.send(consumerInfo1);
|
||||
|
||||
Message m1 = receiveMessage(connection1);
|
||||
assertNotNull(m1);
|
||||
assertNotNull(m1.getDataStructure());
|
||||
assertEquals(((ProducerInfo) m1.getDataStructure()).getProducerId(), producerInfo2.getProducerId());
|
||||
|
||||
// Close the second connection.
|
||||
connection2.request(closeConnectionInfo(connectionInfo2));
|
||||
connection2.stop();
|
||||
|
||||
// We should get an advisory of the producer closing
|
||||
m1 = receiveMessage(connection1);
|
||||
assertNotNull(m1);
|
||||
assertNotNull(m1.getDataStructure());
|
||||
RemoveInfo r = (RemoveInfo) m1.getDataStructure();
|
||||
assertEquals(r.getObjectId(), producerInfo2.getProducerId());
|
||||
|
||||
assertNoMessagesLeft(connection2);
|
||||
}
|
||||
|
||||
public void testProducerAdvisoriesReplayedOnlyTargetNewConsumer() throws Exception {
|
||||
|
||||
ActiveMQDestination queue = new ActiveMQQueue("test");
|
||||
ActiveMQDestination destination = AdvisorySupport.getProducerAdvisoryTopic(queue);
|
||||
|
||||
// Setup a first connection
|
||||
StubConnection connection1 = createConnection();
|
||||
ConnectionInfo connectionInfo1 = createConnectionInfo();
|
||||
SessionInfo sessionInfo1 = createSessionInfo(connectionInfo1);
|
||||
connection1.send(connectionInfo1);
|
||||
connection1.send(sessionInfo1);
|
||||
// Create the first consumer..
|
||||
ConsumerInfo consumerInfo1 = createConsumerInfo(sessionInfo1, destination);
|
||||
consumerInfo1.setPrefetchSize(100);
|
||||
connection1.send(consumerInfo1);
|
||||
|
||||
// Setup a producer.
|
||||
StubConnection connection2 = createConnection();
|
||||
ConnectionInfo connectionInfo2 = createConnectionInfo();
|
||||
SessionInfo sessionInfo2 = createSessionInfo(connectionInfo2);
|
||||
ProducerInfo producerInfo2 = createProducerInfo(sessionInfo2);
|
||||
producerInfo2.setDestination(queue);
|
||||
connection2.send(connectionInfo2);
|
||||
connection2.send(sessionInfo2);
|
||||
connection2.send(producerInfo2);
|
||||
|
||||
Message m1 = receiveMessage(connection1);
|
||||
assertNotNull(m1);
|
||||
assertNotNull(m1.getDataStructure());
|
||||
assertEquals(((ProducerInfo) m1.getDataStructure()).getProducerId(), producerInfo2.getProducerId());
|
||||
|
||||
// Create the 2nd consumer..
|
||||
ConsumerInfo consumerInfo2 = createConsumerInfo(sessionInfo2, destination);
|
||||
consumerInfo2.setPrefetchSize(100);
|
||||
connection2.send(consumerInfo2);
|
||||
|
||||
// The second consumer should se a replay
|
||||
m1 = receiveMessage(connection2);
|
||||
assertNotNull(m1);
|
||||
assertNotNull(m1.getDataStructure());
|
||||
assertEquals(((ProducerInfo) m1.getDataStructure()).getProducerId(), producerInfo2.getProducerId());
|
||||
|
||||
// But the first consumer should not see the replay.
|
||||
assertNoMessagesLeft(connection1);
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return suite(AdvisoryBrokerTest.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(suite());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/**
|
||||
* 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.advisory;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.apache.activemq.broker.BrokerFactory;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
|
||||
public class AdvisoryDuplexNetworkBridgeTest extends AdvisoryNetworkBridgeTest {
|
||||
|
||||
@Override
|
||||
public void createBroker1() throws Exception {
|
||||
broker1 = new BrokerService();
|
||||
broker1.setBrokerName("broker1");
|
||||
broker1.addConnector("tcp://localhost:61617");
|
||||
broker1.setUseJmx(false);
|
||||
broker1.setPersistent(false);
|
||||
broker1.start();
|
||||
broker1.waitUntilStarted();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createBroker2() throws Exception {
|
||||
broker2 = BrokerFactory.createBroker(new URI("xbean:org/apache/activemq/network/duplexLocalBroker.xml"));
|
||||
broker2.start();
|
||||
broker2.waitUntilStarted();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assertCreatedByDuplex(boolean createdByDuplex) {
|
||||
assertTrue(createdByDuplex);
|
||||
}
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
/**
|
||||
* 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.advisory;
|
||||
|
||||
import javax.jms.Connection;
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.MessageConsumer;
|
||||
import javax.jms.Session;
|
||||
import javax.management.MBeanServerConnection;
|
||||
import javax.management.MBeanServerInvocationHandler;
|
||||
import javax.management.ObjectName;
|
||||
import javax.management.remote.JMXConnector;
|
||||
import javax.management.remote.JMXConnectorFactory;
|
||||
import javax.management.remote.JMXServiceURL;
|
||||
|
||||
import org.apache.activemq.EmbeddedBrokerTestSupport;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.jmx.BrokerViewMBean;
|
||||
import org.apache.activemq.broker.jmx.ManagementContext;
|
||||
import org.apache.activemq.command.ActiveMQMessage;
|
||||
import org.apache.activemq.command.DestinationInfo;
|
||||
|
||||
public class AdvisoryJmxTest extends EmbeddedBrokerTestSupport {
|
||||
|
||||
@Override
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerService answer = new BrokerService();
|
||||
answer.setPersistent(isPersistent());
|
||||
answer.addConnector(bindAddress);
|
||||
ManagementContext context = new ManagementContext();
|
||||
context.setConnectorPort(1199);
|
||||
answer.setManagementContext(context);
|
||||
return answer;
|
||||
}
|
||||
|
||||
public void testCreateDeleteDestinations() throws Exception {
|
||||
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1199/jmxrmi");
|
||||
JMXConnector connector = JMXConnectorFactory.connect(url, null);
|
||||
connector.connect();
|
||||
MBeanServerConnection connection = connector.getMBeanServerConnection();
|
||||
ObjectName name = new ObjectName("org.apache.activemq:type=Broker,brokerName=localhost");
|
||||
BrokerViewMBean brokerMbean = MBeanServerInvocationHandler.newProxyInstance(connection, name, BrokerViewMBean.class, true);
|
||||
Connection conn = createConnection();
|
||||
Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
MessageConsumer consumer = sess.createConsumer(sess.createTopic("ActiveMQ.Advisory.Queue"));
|
||||
conn.start();
|
||||
Destination dest = sess.createQueue("test");
|
||||
|
||||
brokerMbean.addQueue("test");
|
||||
|
||||
ActiveMQMessage msg = (ActiveMQMessage) consumer.receive(1000);
|
||||
assertNotNull(msg);
|
||||
assertTrue(msg.getDataStructure() instanceof DestinationInfo);
|
||||
assertEquals(((DestinationInfo) msg.getDataStructure()).getDestination(), dest);
|
||||
assertEquals(((DestinationInfo) msg.getDataStructure()).getOperationType(), 0);
|
||||
|
||||
brokerMbean.removeQueue("test");
|
||||
|
||||
msg = (ActiveMQMessage) consumer.receive(1000);
|
||||
assertNotNull(msg);
|
||||
assertTrue(msg.getDataStructure() instanceof DestinationInfo);
|
||||
assertEquals(((DestinationInfo) msg.getDataStructure()).getDestination(), dest);
|
||||
assertEquals(((DestinationInfo) msg.getDataStructure()).getOperationType(), 1);
|
||||
|
||||
brokerMbean.addQueue("test");
|
||||
msg = (ActiveMQMessage) consumer.receive(1000);
|
||||
assertNotNull(msg);
|
||||
assertTrue(msg.getDataStructure() instanceof DestinationInfo);
|
||||
assertEquals(((DestinationInfo) msg.getDataStructure()).getDestination(), dest);
|
||||
assertEquals(((DestinationInfo) msg.getDataStructure()).getOperationType(), 0);
|
||||
assertEquals(((DestinationInfo) msg.getDataStructure()).getOperationType(), 0);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,127 +0,0 @@
|
|||
/**
|
||||
* 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.advisory;
|
||||
|
||||
import javax.jms.Connection;
|
||||
import javax.jms.MessageConsumer;
|
||||
import javax.jms.Session;
|
||||
import java.net.URI;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.advisory.AdvisorySupport;
|
||||
import org.apache.activemq.broker.BrokerFactory;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.command.ActiveMQMessage;
|
||||
import org.apache.activemq.command.BrokerInfo;
|
||||
|
||||
public class AdvisoryNetworkBridgeTest extends TestCase {
|
||||
|
||||
BrokerService broker1;
|
||||
BrokerService broker2;
|
||||
|
||||
public void testAdvisory() throws Exception {
|
||||
createBroker1();
|
||||
|
||||
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://broker1");
|
||||
Connection conn = factory.createConnection();
|
||||
Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
conn.start();
|
||||
MessageConsumer consumer = sess.createConsumer(AdvisorySupport.getNetworkBridgeAdvisoryTopic());
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
createBroker2();
|
||||
|
||||
ActiveMQMessage advisory = (ActiveMQMessage) consumer.receive(2000);
|
||||
assertNotNull(advisory);
|
||||
assertTrue(advisory.getDataStructure() instanceof BrokerInfo);
|
||||
assertTrue(advisory.getBooleanProperty("started"));
|
||||
assertCreatedByDuplex(advisory.getBooleanProperty("createdByDuplex"));
|
||||
|
||||
broker2.stop();
|
||||
broker2.waitUntilStopped();
|
||||
|
||||
advisory = (ActiveMQMessage) consumer.receive(2000);
|
||||
assertNotNull(advisory);
|
||||
assertTrue(advisory.getDataStructure() instanceof BrokerInfo);
|
||||
assertFalse(advisory.getBooleanProperty("started"));
|
||||
|
||||
conn.close();
|
||||
}
|
||||
|
||||
public void testAddConsumerLater() throws Exception {
|
||||
createBroker1();
|
||||
|
||||
createBroker2();
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://broker1");
|
||||
Connection conn = factory.createConnection();
|
||||
Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
conn.start();
|
||||
MessageConsumer consumer = sess.createConsumer(AdvisorySupport.getNetworkBridgeAdvisoryTopic());
|
||||
|
||||
ActiveMQMessage advisory = (ActiveMQMessage) consumer.receive(2000);
|
||||
assertNotNull(advisory);
|
||||
assertTrue(advisory.getDataStructure() instanceof BrokerInfo);
|
||||
assertTrue(advisory.getBooleanProperty("started"));
|
||||
assertCreatedByDuplex(advisory.getBooleanProperty("createdByDuplex"));
|
||||
|
||||
broker2.stop();
|
||||
broker2.waitUntilStopped();
|
||||
|
||||
advisory = (ActiveMQMessage) consumer.receive(2000);
|
||||
assertNotNull(advisory);
|
||||
assertTrue(advisory.getDataStructure() instanceof BrokerInfo);
|
||||
assertFalse(advisory.getBooleanProperty("started"));
|
||||
|
||||
consumer = sess.createConsumer(AdvisorySupport.getNetworkBridgeAdvisoryTopic());
|
||||
advisory = (ActiveMQMessage) consumer.receive(1000);
|
||||
assertNull(advisory);
|
||||
|
||||
conn.close();
|
||||
|
||||
}
|
||||
|
||||
public void assertCreatedByDuplex(boolean createdByDuplex) {
|
||||
assertFalse(createdByDuplex);
|
||||
}
|
||||
|
||||
public void createBroker1() throws Exception {
|
||||
broker1 = BrokerFactory.createBroker(new URI("xbean:org/apache/activemq/network/reconnect-broker1.xml"));
|
||||
broker1.start();
|
||||
broker1.waitUntilStarted();
|
||||
}
|
||||
|
||||
public void createBroker2() throws Exception {
|
||||
broker2 = BrokerFactory.createBroker(new URI("xbean:org/apache/activemq/network/reconnect-broker2.xml"));
|
||||
broker2.start();
|
||||
broker2.waitUntilStarted();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
broker1.stop();
|
||||
broker1.waitUntilStopped();
|
||||
|
||||
broker2.stop();
|
||||
broker2.waitUntilStopped();
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
<?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.
|
||||
-->
|
||||
|
||||
<!-- this file can only be parsed using the xbean-spring library -->
|
||||
<!-- START SNIPPET: xbean -->
|
||||
<beans
|
||||
xmlns="http://www.springframework.org/schema/beans"
|
||||
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
|
||||
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
||||
|
||||
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />
|
||||
|
||||
<broker xmlns="http://activemq.apache.org/schema/core">
|
||||
<destinations>
|
||||
<queue physicalName="FOO.BAR" />
|
||||
<topic physicalName="SOME.TOPIC" />
|
||||
</destinations>
|
||||
|
||||
</broker>
|
||||
|
||||
</beans>
|
||||
<!-- END SNIPPET: xbean -->
|
|
@ -1,46 +0,0 @@
|
|||
<?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.
|
||||
-->
|
||||
|
||||
<!-- this file can only be parsed using the xbean-spring library -->
|
||||
<!-- START SNIPPET: xbean -->
|
||||
<beans
|
||||
xmlns="http://www.springframework.org/schema/beans"
|
||||
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
|
||||
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
||||
|
||||
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />
|
||||
|
||||
<broker xmlns="http://activemq.apache.org/schema/core">
|
||||
<destinationPolicy>
|
||||
<policyMap>
|
||||
<policyEntries>
|
||||
<policyEntry queue="TEST.>" allConsumersExclusiveByDefault="true"/>
|
||||
</policyEntries>
|
||||
</policyMap>
|
||||
</destinationPolicy>
|
||||
<destinations>
|
||||
<queue physicalName="TEST.QUEUE1"/>
|
||||
<queue physicalName="TEST.QUEUE2"/>
|
||||
<queue physicalName="TEST.QUEUE3"/>
|
||||
</destinations>
|
||||
</broker>
|
||||
|
||||
</beans>
|
||||
<!-- END SNIPPET: xbean -->
|
|
@ -1,84 +0,0 @@
|
|||
/**
|
||||
* 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.ft;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnection;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.util.LeaseLockerIOExceptionHandler;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class DbRestartJDBCQueueMasterSlaveLeaseQuiesceTest extends DbRestartJDBCQueueMasterSlaveLeaseTest {
|
||||
|
||||
private static final transient Logger LOG = LoggerFactory.getLogger(DbRestartJDBCQueueMasterSlaveLeaseQuiesceTest.class);
|
||||
|
||||
private long restartDelay = 2000;
|
||||
|
||||
@Override
|
||||
protected void configureBroker(BrokerService brokerService) {
|
||||
// master and slave survive db restart and retain master/slave status
|
||||
LeaseLockerIOExceptionHandler stopConnectors = new LeaseLockerIOExceptionHandler();
|
||||
brokerService.setIoExceptionHandler(stopConnectors);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void delayTillRestartRequired() {
|
||||
if (restartDelay > 2000) {
|
||||
LOG.info("delay for more than lease quantum. While Db is offline, master should stay alive but could loose lease");
|
||||
} else {
|
||||
LOG.info("delay for less than lease quantum. While Db is offline, master should stay alive");
|
||||
}
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(restartDelay);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void verifyExpectedBroker(int inflightMessageCount) {
|
||||
if (inflightMessageCount == 0 || (inflightMessageCount == failureCount + 10 && restartDelay <= 500)) {
|
||||
assertEquals("connected to master", master.getBrokerName(), ((ActiveMQConnection) sendConnection).getBrokerName());
|
||||
} else {
|
||||
// lease expired while DB was offline, either or master/slave can grab it so assert is not deterministic
|
||||
// but we still need to validate sent == received
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
restartDelay = 2000;
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public void testSendReceiveWithLeaseExpiry() throws Exception {
|
||||
restartDelay = 10000;
|
||||
testSendReceive();
|
||||
}
|
||||
|
||||
// ignore this test case
|
||||
@Override
|
||||
public void testAdvisory() throws Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testSendReceive() throws Exception {
|
||||
// Ignore this test for now, see AMQ-4975
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
/**
|
||||
* 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.ft;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.store.jdbc.JDBCPersistenceAdapter;
|
||||
import org.apache.activemq.store.jdbc.LeaseDatabaseLocker;
|
||||
import org.apache.activemq.util.LeaseLockerIOExceptionHandler;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class DbRestartJDBCQueueMasterSlaveLeaseTest extends DbRestartJDBCQueueMasterSlaveTest {
|
||||
|
||||
private static final transient Logger LOG = LoggerFactory.getLogger(DbRestartJDBCQueueMasterSlaveLeaseTest.class);
|
||||
|
||||
@Override
|
||||
protected void configureJdbcPersistenceAdapter(JDBCPersistenceAdapter persistenceAdapter) throws IOException {
|
||||
super.configureJdbcPersistenceAdapter(persistenceAdapter);
|
||||
persistenceAdapter.setLocker(new LeaseDatabaseLocker());
|
||||
persistenceAdapter.getLocker().setLockAcquireSleepInterval(getLockAcquireSleepInterval());
|
||||
persistenceAdapter.setLockKeepAlivePeriod(getLockKeepAlivePeriod());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureBroker(BrokerService brokerService) {
|
||||
//let the brokers die on exception and master should have lease on restart
|
||||
// which will delay slave start till it expires
|
||||
LeaseLockerIOExceptionHandler ioExceptionHandler = new LeaseLockerIOExceptionHandler();
|
||||
ioExceptionHandler.setIgnoreSQLExceptions(false);
|
||||
ioExceptionHandler.setStopStartConnectors(false);
|
||||
ioExceptionHandler.setResumeCheckSleepPeriod(500L);
|
||||
brokerService.setIoExceptionHandler(ioExceptionHandler);
|
||||
}
|
||||
|
||||
private long getLockKeepAlivePeriod() {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
private long getLockAcquireSleepInterval() {
|
||||
return 8000;
|
||||
}
|
||||
}
|
|
@ -1,155 +0,0 @@
|
|||
/**
|
||||
* 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.ft;
|
||||
|
||||
import javax.jms.Connection;
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageProducer;
|
||||
import javax.jms.Session;
|
||||
import javax.jms.TransactionRolledBackException;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnection;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.command.ActiveMQMessage;
|
||||
import org.apache.activemq.command.MessageId;
|
||||
import org.apache.activemq.store.jdbc.JDBCPersistenceAdapter;
|
||||
import org.apache.derby.jdbc.EmbeddedDataSource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class DbRestartJDBCQueueMasterSlaveTest extends JDBCQueueMasterSlaveTest {
|
||||
|
||||
private static final transient Logger LOG = LoggerFactory.getLogger(DbRestartJDBCQueueMasterSlaveTest.class);
|
||||
|
||||
@Override
|
||||
protected void messageSent() throws Exception {
|
||||
verifyExpectedBroker(inflightMessageCount);
|
||||
if (++inflightMessageCount == failureCount) {
|
||||
LOG.info("STOPPING DB!@!!!!");
|
||||
final EmbeddedDataSource ds = ((SyncCreateDataSource) getExistingDataSource()).getDelegate();
|
||||
ds.setShutdownDatabase("shutdown");
|
||||
LOG.info("DB STOPPED!@!!!!");
|
||||
|
||||
Thread dbRestartThread = new Thread("db-re-start-thread") {
|
||||
@Override
|
||||
public void run() {
|
||||
delayTillRestartRequired();
|
||||
ds.setShutdownDatabase("false");
|
||||
LOG.info("DB RESTARTED!@!!!!");
|
||||
}
|
||||
};
|
||||
dbRestartThread.start();
|
||||
}
|
||||
verifyExpectedBroker(inflightMessageCount);
|
||||
}
|
||||
|
||||
protected void verifyExpectedBroker(int inflightMessageCount) {
|
||||
if (inflightMessageCount == 0) {
|
||||
assertEquals("connected to master", master.getBrokerName(), ((ActiveMQConnection) sendConnection).getBrokerName());
|
||||
} else if (inflightMessageCount == failureCount + 10) {
|
||||
assertEquals("connected to slave, count:" + inflightMessageCount, slave.get().getBrokerName(), ((ActiveMQConnection) sendConnection).getBrokerName());
|
||||
}
|
||||
}
|
||||
|
||||
protected void delayTillRestartRequired() {
|
||||
LOG.info("Waiting for master broker to Stop");
|
||||
master.waitUntilStopped();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendToProducer(MessageProducer producer,
|
||||
Destination producerDestination,
|
||||
Message message) throws JMSException {
|
||||
producer.send(producerDestination, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Session createReceiveSession(Connection receiveConnection) throws Exception {
|
||||
return receiveConnection.createSession(true, Session.SESSION_TRANSACTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void consumeMessage(Message message, List<Message> messageList) {
|
||||
try {
|
||||
receiveSession.commit();
|
||||
super.consumeMessage(message, messageList);
|
||||
} catch (JMSException e) {
|
||||
LOG.info("Failed to commit message receipt: " + message, e);
|
||||
try {
|
||||
receiveSession.rollback();
|
||||
} catch (JMSException ignored) {
|
||||
}
|
||||
|
||||
if (e instanceof TransactionRolledBackException) {
|
||||
TransactionRolledBackException transactionRolledBackException = (TransactionRolledBackException) e;
|
||||
if (transactionRolledBackException.getMessage().indexOf("in doubt") != -1) {
|
||||
// failover chucked bc there is a missing reply to a commit.
|
||||
// failover is involved b/c the store exception is handled broker side and the client just
|
||||
// sees a disconnect (socket.close()).
|
||||
// If the client needs to be aware of the failure then it should not use IOExceptionHandler
|
||||
// so that the exception will propagate back
|
||||
|
||||
// for this test case:
|
||||
// the commit may have got there and the reply is lost "or" the commit may be lost.
|
||||
// so we may or may not get a resend.
|
||||
//
|
||||
// At the application level we need to determine if the message is there or not which is not trivial
|
||||
// for this test we assert received == sent
|
||||
// so we need to know whether the message will be replayed.
|
||||
// we can ask the store b/c we know it is jdbc - guess we could go through a destination
|
||||
// message store interface also or use jmx
|
||||
java.sql.Connection dbConnection = null;
|
||||
try {
|
||||
ActiveMQMessage mqMessage = (ActiveMQMessage) message;
|
||||
MessageId id = mqMessage.getMessageId();
|
||||
dbConnection = sharedDs.getConnection();
|
||||
PreparedStatement s = dbConnection.prepareStatement(((JDBCPersistenceAdapter) connectedToBroker().getPersistenceAdapter()).getStatements().getFindMessageStatement());
|
||||
s.setString(1, id.getProducerId().toString());
|
||||
s.setLong(2, id.getProducerSequenceId());
|
||||
ResultSet rs = s.executeQuery();
|
||||
|
||||
if (!rs.next()) {
|
||||
// message is gone, so lets count it as consumed
|
||||
LOG.info("On TransactionRolledBackException we know that the ack/commit got there b/c message is gone so we count it: " + mqMessage);
|
||||
super.consumeMessage(message, messageList);
|
||||
} else {
|
||||
LOG.info("On TransactionRolledBackException we know that the ack/commit was lost so we expect a replay of: " + mqMessage);
|
||||
}
|
||||
} catch (Exception dbe) {
|
||||
dbe.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
dbConnection.close();
|
||||
} catch (SQLException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BrokerService connectedToBroker() {
|
||||
return ((ActiveMQConnection) receiveConnection).getBrokerInfo().getBrokerName().equals("master") ? master : slave.get();
|
||||
}
|
||||
}
|
|
@ -1,165 +0,0 @@
|
|||
/**
|
||||
* 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.ft;
|
||||
|
||||
import javax.jms.Connection;
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.ExceptionListener;
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageProducer;
|
||||
import javax.jms.Session;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.JmsTopicSendReceiveWithTwoConnectionsTest;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.store.jdbc.DataSourceServiceSupport;
|
||||
import org.apache.activemq.store.jdbc.JDBCPersistenceAdapter;
|
||||
import org.apache.activemq.util.DefaultIOExceptionHandler;
|
||||
import org.apache.activemq.util.IOHelper;
|
||||
import org.apache.derby.jdbc.EmbeddedDataSource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class DbRestartJDBCQueueTest extends JmsTopicSendReceiveWithTwoConnectionsTest implements ExceptionListener {
|
||||
|
||||
private static final transient Logger LOG = LoggerFactory.getLogger(DbRestartJDBCQueueTest.class);
|
||||
|
||||
public boolean transactedSends = false;
|
||||
public int failureCount = 25; // or 20 for even tx batch boundary
|
||||
|
||||
int inflightMessageCount = 0;
|
||||
EmbeddedDataSource sharedDs;
|
||||
BrokerService broker;
|
||||
final CountDownLatch restartDBLatch = new CountDownLatch(1);
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
setAutoFail(true);
|
||||
topic = false;
|
||||
verbose = true;
|
||||
// startup db
|
||||
sharedDs = (EmbeddedDataSource) DataSourceServiceSupport.createDataSource(IOHelper.getDefaultDataDirectory());
|
||||
|
||||
broker = new BrokerService();
|
||||
|
||||
DefaultIOExceptionHandler handler = new DefaultIOExceptionHandler();
|
||||
handler.setIgnoreSQLExceptions(false);
|
||||
handler.setStopStartConnectors(true);
|
||||
broker.setIoExceptionHandler(handler);
|
||||
broker.addConnector("tcp://localhost:0");
|
||||
broker.setUseJmx(false);
|
||||
broker.setPersistent(true);
|
||||
broker.setDeleteAllMessagesOnStartup(true);
|
||||
JDBCPersistenceAdapter persistenceAdapter = new JDBCPersistenceAdapter();
|
||||
persistenceAdapter.setDataSource(sharedDs);
|
||||
persistenceAdapter.setUseLock(false);
|
||||
persistenceAdapter.setLockKeepAlivePeriod(500);
|
||||
persistenceAdapter.getLocker().setLockAcquireSleepInterval(500);
|
||||
broker.setPersistenceAdapter(persistenceAdapter);
|
||||
broker.start();
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
broker.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Session createSendSession(Connection sendConnection) throws Exception {
|
||||
if (transactedSends) {
|
||||
return sendConnection.createSession(true, Session.SESSION_TRANSACTED);
|
||||
} else {
|
||||
return sendConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ActiveMQConnectionFactory createConnectionFactory() throws Exception {
|
||||
ActiveMQConnectionFactory f = new ActiveMQConnectionFactory("failover://" + broker.getTransportConnectors().get(0).getPublishableConnectString());
|
||||
f.setExceptionListener(this);
|
||||
return f;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void messageSent() throws Exception {
|
||||
if (++inflightMessageCount == failureCount) {
|
||||
LOG.info("STOPPING DB!@!!!!");
|
||||
final EmbeddedDataSource ds = sharedDs;
|
||||
ds.setShutdownDatabase("shutdown");
|
||||
try {
|
||||
ds.getConnection();
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
LOG.info("DB STOPPED!@!!!!");
|
||||
|
||||
Thread dbRestartThread = new Thread("db-re-start-thread") {
|
||||
@Override
|
||||
public void run() {
|
||||
LOG.info("Sleeping for 10 seconds before allowing db restart");
|
||||
try {
|
||||
restartDBLatch.await(10, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
ds.setShutdownDatabase("false");
|
||||
LOG.info("DB RESTARTED!@!!!!");
|
||||
}
|
||||
};
|
||||
dbRestartThread.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendToProducer(MessageProducer producer,
|
||||
Destination producerDestination,
|
||||
Message message) throws JMSException {
|
||||
{
|
||||
// do some retries as db failures filter back to the client until broker sees
|
||||
// db lock failure and shuts down
|
||||
boolean sent = false;
|
||||
do {
|
||||
try {
|
||||
producer.send(producerDestination, message);
|
||||
|
||||
if (transactedSends && ((inflightMessageCount + 1) % 10 == 0 || (inflightMessageCount + 1) >= messageCount)) {
|
||||
LOG.info("committing on send: " + inflightMessageCount + " message: " + message);
|
||||
session.commit();
|
||||
}
|
||||
|
||||
sent = true;
|
||||
} catch (JMSException e) {
|
||||
LOG.info("Exception on producer send:", e);
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
}
|
||||
} while (!sent);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(JMSException exception) {
|
||||
LOG.error("exception on connection: ", exception);
|
||||
}
|
||||
}
|
|
@ -1,111 +0,0 @@
|
|||
/**
|
||||
* 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.ft;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.TransportConnector;
|
||||
import org.apache.activemq.store.jdbc.DataSourceServiceSupport;
|
||||
import org.apache.activemq.store.jdbc.JDBCPersistenceAdapter;
|
||||
import org.apache.activemq.util.DefaultIOExceptionHandler;
|
||||
import org.apache.activemq.util.IOHelper;
|
||||
import org.apache.derby.jdbc.EmbeddedDataSource;
|
||||
|
||||
public class JDBCQueueMasterSlaveTest extends QueueMasterSlaveTestSupport {
|
||||
|
||||
protected DataSource sharedDs;
|
||||
protected String MASTER_URL = "tcp://localhost:62001";
|
||||
protected String SLAVE_URL = "tcp://localhost:62002";
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
// startup db
|
||||
sharedDs = new SyncCreateDataSource((EmbeddedDataSource) DataSourceServiceSupport.createDataSource(IOHelper.getDefaultDataDirectory()));
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createMaster() throws Exception {
|
||||
master = new BrokerService();
|
||||
master.setBrokerName("master");
|
||||
master.addConnector(MASTER_URL);
|
||||
master.setUseJmx(false);
|
||||
master.setPersistent(true);
|
||||
master.setDeleteAllMessagesOnStartup(true);
|
||||
JDBCPersistenceAdapter persistenceAdapter = new JDBCPersistenceAdapter();
|
||||
persistenceAdapter.setDataSource(getExistingDataSource());
|
||||
configureJdbcPersistenceAdapter(persistenceAdapter);
|
||||
master.setPersistenceAdapter(persistenceAdapter);
|
||||
configureBroker(master);
|
||||
master.start();
|
||||
}
|
||||
|
||||
protected void configureBroker(BrokerService brokerService) {
|
||||
DefaultIOExceptionHandler stopBrokerOnStoreException = new DefaultIOExceptionHandler();
|
||||
// we want any store io exception to stop the broker
|
||||
stopBrokerOnStoreException.setIgnoreSQLExceptions(false);
|
||||
brokerService.setIoExceptionHandler(stopBrokerOnStoreException);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createSlave() throws Exception {
|
||||
// use a separate thread as the slave will block waiting for
|
||||
// the exclusive db lock
|
||||
Thread t = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
BrokerService broker = new BrokerService();
|
||||
broker.setBrokerName("slave");
|
||||
TransportConnector connector = new TransportConnector();
|
||||
connector.setUri(new URI(SLAVE_URL));
|
||||
broker.addConnector(connector);
|
||||
// no need for broker.setMasterConnectorURI(masterConnectorURI)
|
||||
// as the db lock provides the slave/master initialisation
|
||||
broker.setUseJmx(false);
|
||||
broker.setPersistent(true);
|
||||
JDBCPersistenceAdapter persistenceAdapter = new JDBCPersistenceAdapter();
|
||||
persistenceAdapter.setDataSource(getExistingDataSource());
|
||||
persistenceAdapter.setCreateTablesOnStartup(false);
|
||||
broker.setPersistenceAdapter(persistenceAdapter);
|
||||
configureJdbcPersistenceAdapter(persistenceAdapter);
|
||||
configureBroker(broker);
|
||||
broker.start();
|
||||
slave.set(broker);
|
||||
slaveStarted.countDown();
|
||||
} catch (IllegalStateException expectedOnShutdown) {
|
||||
} catch (Exception e) {
|
||||
fail("failed to start slave broker, reason:" + e);
|
||||
}
|
||||
}
|
||||
};
|
||||
t.start();
|
||||
}
|
||||
|
||||
protected void configureJdbcPersistenceAdapter(JDBCPersistenceAdapter persistenceAdapter) throws IOException {
|
||||
persistenceAdapter.setLockKeepAlivePeriod(500);
|
||||
persistenceAdapter.getLocker().setLockAcquireSleepInterval(500);
|
||||
}
|
||||
|
||||
protected DataSource getExistingDataSource() throws Exception {
|
||||
return sharedDs;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
/**
|
||||
* 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.ft;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.TransportConnector;
|
||||
import org.apache.activemq.leveldb.LevelDBStore;
|
||||
import org.junit.Ignore;
|
||||
|
||||
public class QueueMasterSlaveSingleUrlTest extends QueueMasterSlaveTestSupport {
|
||||
|
||||
private final String brokerUrl = "tcp://localhost:62001";
|
||||
private final String singleUriString = "failover://(" + brokerUrl + ")?randomize=false";
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
setAutoFail(true);
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ActiveMQConnectionFactory createConnectionFactory() throws Exception {
|
||||
return new ActiveMQConnectionFactory(singleUriString);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createMaster() throws Exception {
|
||||
master = new BrokerService();
|
||||
master.setBrokerName("shared-master");
|
||||
configureSharedPersistenceAdapter(master);
|
||||
master.addConnector(brokerUrl);
|
||||
master.start();
|
||||
}
|
||||
|
||||
private void configureSharedPersistenceAdapter(BrokerService broker) throws Exception {
|
||||
LevelDBStore adapter = new LevelDBStore();
|
||||
adapter.setDirectory(new File("shared"));
|
||||
broker.setPersistenceAdapter(adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createSlave() throws Exception {
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
BrokerService broker = new BrokerService();
|
||||
broker.setBrokerName("shared-slave");
|
||||
configureSharedPersistenceAdapter(broker);
|
||||
// add transport as a service so that it is bound on start, after store started
|
||||
final TransportConnector tConnector = new TransportConnector();
|
||||
tConnector.setUri(new URI(brokerUrl));
|
||||
broker.addConnector(tConnector);
|
||||
|
||||
broker.start();
|
||||
slave.set(broker);
|
||||
slaveStarted.countDown();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}).start();
|
||||
}
|
||||
|
||||
// The @Ignore is just here for documentation, since this is a JUnit3 test
|
||||
// I added the sleep because without it the two other test cases fail. I haven't looked into it, but
|
||||
// my guess whatever setUp does isn't really finished when the teardown runs.
|
||||
@Ignore("See https://issues.apache.org/jira/browse/AMQ-5164")
|
||||
@Override
|
||||
public void testAdvisory() throws Exception {
|
||||
Thread.sleep(5 * 1000);
|
||||
//super.testAdvisory();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,156 +0,0 @@
|
|||
/**
|
||||
* 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.ft;
|
||||
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageConsumer;
|
||||
import javax.jms.TextMessage;
|
||||
import java.io.File;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.JmsTopicSendReceiveWithTwoConnectionsTest;
|
||||
import org.apache.activemq.advisory.AdvisorySupport;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.apache.activemq.command.ActiveMQTopic;
|
||||
import org.apache.activemq.xbean.BrokerFactoryBean;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
/**
|
||||
* Test failover for Queues
|
||||
*/
|
||||
abstract public class QueueMasterSlaveTestSupport extends JmsTopicSendReceiveWithTwoConnectionsTest {
|
||||
|
||||
private static final transient Logger LOG = LoggerFactory.getLogger(QueueMasterSlaveTestSupport.class);
|
||||
|
||||
protected BrokerService master;
|
||||
protected AtomicReference<BrokerService> slave = new AtomicReference<>();
|
||||
protected CountDownLatch slaveStarted = new CountDownLatch(1);
|
||||
protected int inflightMessageCount;
|
||||
protected int failureCount = 50;
|
||||
protected String uriString = "failover://(tcp://localhost:62001,tcp://localhost:62002)?randomize=false&useExponentialBackOff=false";
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
setMaxTestTime(TimeUnit.MINUTES.toMillis(10));
|
||||
setAutoFail(true);
|
||||
if (System.getProperty("basedir") == null) {
|
||||
File file = new File(".");
|
||||
System.setProperty("basedir", file.getAbsolutePath());
|
||||
}
|
||||
super.messageCount = 500;
|
||||
failureCount = super.messageCount / 2;
|
||||
super.topic = isTopic();
|
||||
createMaster();
|
||||
createSlave();
|
||||
// wait for thing to connect
|
||||
Thread.sleep(1000);
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
protected String getSlaveXml() {
|
||||
return "org/apache/activemq/broker/ft/slave.xml";
|
||||
}
|
||||
|
||||
protected String getMasterXml() {
|
||||
return "org/apache/activemq/broker/ft/master.xml";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
master.stop();
|
||||
master.waitUntilStopped();
|
||||
slaveStarted.await(60, TimeUnit.SECONDS);
|
||||
BrokerService brokerService = slave.get();
|
||||
if (brokerService != null) {
|
||||
brokerService.stop();
|
||||
}
|
||||
master.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ActiveMQConnectionFactory createConnectionFactory() throws Exception {
|
||||
return new ActiveMQConnectionFactory(uriString);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void messageSent() throws Exception {
|
||||
if (++inflightMessageCount == failureCount) {
|
||||
Thread.sleep(1000);
|
||||
LOG.error("MASTER STOPPED!@!!!!");
|
||||
master.stop();
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isTopic() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void createMaster() throws Exception {
|
||||
BrokerFactoryBean brokerFactory = new BrokerFactoryBean(new ClassPathResource(getMasterXml()));
|
||||
brokerFactory.afterPropertiesSet();
|
||||
master = brokerFactory.getBroker();
|
||||
master.start();
|
||||
}
|
||||
|
||||
protected void createSlave() throws Exception {
|
||||
BrokerFactoryBean brokerFactory = new BrokerFactoryBean(new ClassPathResource(getSlaveXml()));
|
||||
brokerFactory.afterPropertiesSet();
|
||||
BrokerService broker = brokerFactory.getBroker();
|
||||
broker.start();
|
||||
slave.set(broker);
|
||||
slaveStarted.countDown();
|
||||
}
|
||||
|
||||
public void testVirtualTopicFailover() throws Exception {
|
||||
|
||||
MessageConsumer qConsumer = session.createConsumer(new ActiveMQQueue("Consumer.A.VirtualTopic.TA1"));
|
||||
assertNull("No message there yet", qConsumer.receive(1000));
|
||||
qConsumer.close();
|
||||
assertTrue(!master.isSlave());
|
||||
master.stop();
|
||||
assertTrue("slave started", slaveStarted.await(60, TimeUnit.SECONDS));
|
||||
assertTrue(!slave.get().isSlave());
|
||||
|
||||
final String text = "ForUWhenSlaveKicksIn";
|
||||
producer.send(new ActiveMQTopic("VirtualTopic.TA1"), session.createTextMessage(text));
|
||||
|
||||
qConsumer = session.createConsumer(new ActiveMQQueue("Consumer.A.VirtualTopic.TA1"));
|
||||
|
||||
javax.jms.Message message = qConsumer.receive(4000);
|
||||
assertNotNull("Get message after failover", message);
|
||||
assertEquals("correct message", text, ((TextMessage) message).getText());
|
||||
}
|
||||
|
||||
public void testAdvisory() throws Exception {
|
||||
MessageConsumer advConsumer = session.createConsumer(AdvisorySupport.getMasterBrokerAdvisoryTopic());
|
||||
|
||||
master.stop();
|
||||
assertTrue("slave started", slaveStarted.await(60, TimeUnit.SECONDS));
|
||||
LOG.info("slave started");
|
||||
Message advisoryMessage = advConsumer.receive(5000);
|
||||
LOG.info("received " + advisoryMessage);
|
||||
assertNotNull("Didn't received advisory", advisoryMessage);
|
||||
|
||||
}
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
/**
|
||||
* 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.ft;
|
||||
|
||||
public class QueueMasterSlaveTestUsingSharedFileTest extends QueueMasterSlaveTestSupport {
|
||||
|
||||
@Override
|
||||
protected String getSlaveXml() {
|
||||
return "org/apache/activemq/broker/ft/sharedFileSlave.xml";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getMasterXml() {
|
||||
return "org/apache/activemq/broker/ft/sharedFileMaster.xml";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createSlave() throws Exception {
|
||||
// Start the Brokers async since starting them up could be a blocking operation..
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
QueueMasterSlaveTestUsingSharedFileTest.super.createSlave();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}).start();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
/**
|
||||
* 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.ft;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.io.PrintWriter;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLFeatureNotSupportedException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.apache.derby.jdbc.EmbeddedDataSource;
|
||||
|
||||
// prevent concurrent calls from attempting to create the db at the same time
|
||||
// can result in "already exists in this jvm" errors
|
||||
|
||||
public class SyncCreateDataSource implements DataSource {
|
||||
|
||||
final EmbeddedDataSource delegate;
|
||||
|
||||
SyncCreateDataSource(EmbeddedDataSource dataSource) {
|
||||
this.delegate = dataSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection() throws SQLException {
|
||||
synchronized (this) {
|
||||
return delegate.getConnection();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection(String username, String password) throws SQLException {
|
||||
synchronized (this) {
|
||||
return delegate.getConnection();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrintWriter getLogWriter() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogWriter(PrintWriter out) throws SQLException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLoginTimeout() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLoginTimeout(int seconds) throws SQLException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
EmbeddedDataSource getDelegate() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
/**
|
||||
* 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.ft;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.TransportConnector;
|
||||
import org.apache.activemq.store.jdbc.DataSourceServiceSupport;
|
||||
import org.apache.activemq.store.jdbc.LeaseDatabaseLocker;
|
||||
import org.apache.activemq.store.jdbc.Statements;
|
||||
import org.apache.activemq.store.kahadb.KahaDBPersistenceAdapter;
|
||||
import org.apache.activemq.util.DefaultIOExceptionHandler;
|
||||
import org.apache.activemq.util.IOHelper;
|
||||
import org.apache.derby.jdbc.EmbeddedDataSource;
|
||||
|
||||
public class kahaDbJdbcLeaseQueueMasterSlaveTest extends QueueMasterSlaveTestSupport {
|
||||
|
||||
protected DataSource sharedDs;
|
||||
protected String MASTER_URL = "tcp://localhost:62001";
|
||||
protected String SLAVE_URL = "tcp://localhost:62002";
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
// startup db
|
||||
sharedDs = new SyncCreateDataSource((EmbeddedDataSource) DataSourceServiceSupport.createDataSource(IOHelper.getDefaultDataDirectory()));
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createMaster() throws Exception {
|
||||
master = new BrokerService();
|
||||
master.setBrokerName("master");
|
||||
master.addConnector(MASTER_URL);
|
||||
master.setUseJmx(false);
|
||||
master.setPersistent(true);
|
||||
master.setDeleteAllMessagesOnStartup(true);
|
||||
KahaDBPersistenceAdapter kahaDBPersistenceAdapter = (KahaDBPersistenceAdapter) master.getPersistenceAdapter();
|
||||
LeaseDatabaseLocker leaseDatabaseLocker = new LeaseDatabaseLocker();
|
||||
leaseDatabaseLocker.setCreateTablesOnStartup(true);
|
||||
leaseDatabaseLocker.setDataSource(getExistingDataSource());
|
||||
leaseDatabaseLocker.setStatements(new Statements());
|
||||
kahaDBPersistenceAdapter.setLocker(leaseDatabaseLocker);
|
||||
configureLocker(kahaDBPersistenceAdapter);
|
||||
configureBroker(master);
|
||||
master.start();
|
||||
}
|
||||
|
||||
protected void configureBroker(BrokerService brokerService) {
|
||||
DefaultIOExceptionHandler stopBrokerOnStoreException = new DefaultIOExceptionHandler();
|
||||
// we want any store io exception to stop the broker
|
||||
stopBrokerOnStoreException.setIgnoreSQLExceptions(false);
|
||||
brokerService.setIoExceptionHandler(stopBrokerOnStoreException);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createSlave() throws Exception {
|
||||
// use a separate thread as the slave will block waiting for
|
||||
// the exclusive db lock
|
||||
Thread t = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
BrokerService broker = new BrokerService();
|
||||
broker.setBrokerName("slave");
|
||||
TransportConnector connector = new TransportConnector();
|
||||
connector.setUri(new URI(SLAVE_URL));
|
||||
broker.addConnector(connector);
|
||||
broker.setUseJmx(false);
|
||||
broker.setPersistent(true);
|
||||
KahaDBPersistenceAdapter kahaDBPersistenceAdapter = (KahaDBPersistenceAdapter) broker.getPersistenceAdapter();
|
||||
LeaseDatabaseLocker leaseDatabaseLocker = new LeaseDatabaseLocker();
|
||||
leaseDatabaseLocker.setDataSource(getExistingDataSource());
|
||||
leaseDatabaseLocker.setStatements(new Statements());
|
||||
kahaDBPersistenceAdapter.setLocker(leaseDatabaseLocker);
|
||||
configureLocker(kahaDBPersistenceAdapter);
|
||||
configureBroker(broker);
|
||||
broker.start();
|
||||
slave.set(broker);
|
||||
slaveStarted.countDown();
|
||||
} catch (IllegalStateException expectedOnShutdown) {
|
||||
} catch (Exception e) {
|
||||
fail("failed to start slave broker, reason:" + e);
|
||||
}
|
||||
}
|
||||
};
|
||||
t.start();
|
||||
}
|
||||
|
||||
protected void configureLocker(KahaDBPersistenceAdapter kahaDBPersistenceAdapter) throws IOException {
|
||||
kahaDBPersistenceAdapter.setLockKeepAlivePeriod(500);
|
||||
kahaDBPersistenceAdapter.getLocker().setLockAcquireSleepInterval(500);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testVirtualTopicFailover() throws Exception {
|
||||
// Ignoring for now, see AMQ-4842
|
||||
}
|
||||
|
||||
protected DataSource getExistingDataSource() throws Exception {
|
||||
return sharedDs;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
/**
|
||||
* 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.ft;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.TransportConnector;
|
||||
import org.apache.activemq.store.kahadb.FilteredKahaDBPersistenceAdapter;
|
||||
import org.apache.activemq.store.kahadb.KahaDBPersistenceAdapter;
|
||||
import org.apache.activemq.store.kahadb.MultiKahaDBPersistenceAdapter;
|
||||
|
||||
public class mKahaDbQueueMasterSlaveTest extends QueueMasterSlaveTestSupport {
|
||||
|
||||
protected String MASTER_URL = "tcp://localhost:62001";
|
||||
protected String SLAVE_URL = "tcp://localhost:62002";
|
||||
|
||||
@Override
|
||||
protected void createMaster() throws Exception {
|
||||
master = new BrokerService();
|
||||
master.setBrokerName("master");
|
||||
master.addConnector(MASTER_URL);
|
||||
master.setUseJmx(false);
|
||||
master.setPersistent(true);
|
||||
master.setDeleteAllMessagesOnStartup(true);
|
||||
|
||||
MultiKahaDBPersistenceAdapter mKahaDB = new MultiKahaDBPersistenceAdapter();
|
||||
List<FilteredKahaDBPersistenceAdapter> adapters = new LinkedList<>();
|
||||
FilteredKahaDBPersistenceAdapter defaultEntry = new FilteredKahaDBPersistenceAdapter();
|
||||
defaultEntry.setPersistenceAdapter(new KahaDBPersistenceAdapter());
|
||||
defaultEntry.setPerDestination(true);
|
||||
adapters.add(defaultEntry);
|
||||
|
||||
mKahaDB.setFilteredPersistenceAdapters(adapters);
|
||||
master.setPersistenceAdapter(mKahaDB);
|
||||
|
||||
master.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createSlave() throws Exception {
|
||||
// use a separate thread as the slave will block waiting for
|
||||
// the exclusive db lock
|
||||
Thread t = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
BrokerService broker = new BrokerService();
|
||||
broker.setBrokerName("slave");
|
||||
TransportConnector connector = new TransportConnector();
|
||||
connector.setUri(new URI(SLAVE_URL));
|
||||
broker.addConnector(connector);
|
||||
// no need for broker.setMasterConnectorURI(masterConnectorURI)
|
||||
// as the db lock provides the slave/master initialisation
|
||||
broker.setUseJmx(false);
|
||||
broker.setPersistent(true);
|
||||
|
||||
MultiKahaDBPersistenceAdapter mKahaDB = new MultiKahaDBPersistenceAdapter();
|
||||
List<FilteredKahaDBPersistenceAdapter> adapters = new LinkedList<>();
|
||||
FilteredKahaDBPersistenceAdapter defaultEntry = new FilteredKahaDBPersistenceAdapter();
|
||||
defaultEntry.setPersistenceAdapter(new KahaDBPersistenceAdapter());
|
||||
defaultEntry.setPerDestination(true);
|
||||
adapters.add(defaultEntry);
|
||||
|
||||
mKahaDB.setFilteredPersistenceAdapters(adapters);
|
||||
broker.setPersistenceAdapter(mKahaDB);
|
||||
broker.start();
|
||||
slave.set(broker);
|
||||
slaveStarted.countDown();
|
||||
} catch (IllegalStateException expectedOnShutdown) {
|
||||
} catch (Exception e) {
|
||||
fail("failed to start slave broker, reason:" + e);
|
||||
}
|
||||
}
|
||||
};
|
||||
t.start();
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
<?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.
|
||||
-->
|
||||
<beans
|
||||
xmlns="http://www.springframework.org/schema/beans"
|
||||
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
|
||||
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
||||
|
||||
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
|
||||
|
||||
<broker brokerName="shared" useJmx="false" deleteAllMessagesOnStartup="true" xmlns="http://activemq.apache.org/schema/core">
|
||||
<transportConnectors>
|
||||
<transportConnector uri="tcp://localhost:62001"/>
|
||||
</transportConnectors>
|
||||
|
||||
</broker>
|
||||
|
||||
</beans>
|
|
@ -1,35 +0,0 @@
|
|||
<?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.
|
||||
-->
|
||||
<beans
|
||||
xmlns="http://www.springframework.org/schema/beans"
|
||||
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
|
||||
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
||||
|
||||
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
|
||||
|
||||
<broker brokerName="shared" useJmx="false" deleteAllMessagesOnStartup="false" xmlns="http://activemq.apache.org/schema/core">
|
||||
<transportConnectors>
|
||||
<transportConnector uri="tcp://localhost:62002"/>
|
||||
</transportConnectors>
|
||||
|
||||
|
||||
</broker>
|
||||
|
||||
</beans>
|
|
@ -1,64 +0,0 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.broker;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.Test;
|
||||
|
||||
import org.apache.activemq.command.ActiveMQDestination;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.apache.activemq.store.kahadb.FilteredKahaDBPersistenceAdapter;
|
||||
import org.apache.activemq.store.kahadb.KahaDBPersistenceAdapter;
|
||||
import org.apache.activemq.store.kahadb.MultiKahaDBPersistenceAdapter;
|
||||
|
||||
public class mKahaDBXARecoveryBrokerTest extends XARecoveryBrokerTest {
|
||||
|
||||
@Override
|
||||
protected void configureBroker(BrokerService broker) throws Exception {
|
||||
super.configureBroker(broker);
|
||||
|
||||
MultiKahaDBPersistenceAdapter mKahaDB = new MultiKahaDBPersistenceAdapter();
|
||||
List<FilteredKahaDBPersistenceAdapter> adapters = new LinkedList<>();
|
||||
FilteredKahaDBPersistenceAdapter defaultEntry = new FilteredKahaDBPersistenceAdapter();
|
||||
defaultEntry.setPersistenceAdapter(new KahaDBPersistenceAdapter());
|
||||
adapters.add(defaultEntry);
|
||||
|
||||
FilteredKahaDBPersistenceAdapter special = new FilteredKahaDBPersistenceAdapter();
|
||||
special.setDestination(new ActiveMQQueue("special"));
|
||||
special.setPersistenceAdapter(new KahaDBPersistenceAdapter());
|
||||
adapters.add(special);
|
||||
|
||||
mKahaDB.setFilteredPersistenceAdapters(adapters);
|
||||
broker.setPersistenceAdapter(mKahaDB);
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return suite(mKahaDBXARecoveryBrokerTest.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(suite());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ActiveMQDestination createDestination() {
|
||||
return new ActiveMQQueue("test,special");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.broker;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.Test;
|
||||
|
||||
import org.apache.activemq.command.ActiveMQDestination;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.apache.activemq.store.kahadb.FilteredKahaDBPersistenceAdapter;
|
||||
import org.apache.activemq.store.kahadb.MultiKahaDBPersistenceAdapter;
|
||||
import org.apache.activemq.store.leveldb.LevelDBPersistenceAdapter;
|
||||
|
||||
public class mLevelDBXARecoveryBrokerTest extends XARecoveryBrokerTest {
|
||||
|
||||
@Override
|
||||
protected void configureBroker(BrokerService broker) throws Exception {
|
||||
super.configureBroker(broker);
|
||||
|
||||
MultiKahaDBPersistenceAdapter mKahaDB = new MultiKahaDBPersistenceAdapter();
|
||||
List<FilteredKahaDBPersistenceAdapter> adapters = new LinkedList<>();
|
||||
FilteredKahaDBPersistenceAdapter defaultEntry = new FilteredKahaDBPersistenceAdapter();
|
||||
defaultEntry.setPersistenceAdapter(new LevelDBPersistenceAdapter());
|
||||
adapters.add(defaultEntry);
|
||||
|
||||
FilteredKahaDBPersistenceAdapter special = new FilteredKahaDBPersistenceAdapter();
|
||||
special.setDestination(new ActiveMQQueue("special"));
|
||||
special.setPersistenceAdapter(new LevelDBPersistenceAdapter());
|
||||
adapters.add(special);
|
||||
|
||||
mKahaDB.setFilteredPersistenceAdapters(adapters);
|
||||
broker.setPersistenceAdapter(mKahaDB);
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return suite(mLevelDBXARecoveryBrokerTest.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(suite());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ActiveMQDestination createDestination() {
|
||||
return new ActiveMQQueue("test,special");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testQueuePersistentPreparedAcksAvailableAfterRestartAndRollback() throws Exception {
|
||||
// super.testQueuePersistentPreparedAcksAvailableAfterRestartAndRollback();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testQueuePersistentUncommittedAcksLostOnRestart() throws Exception {
|
||||
// super.testQueuePersistentUncommittedAcksLostOnRestart();
|
||||
}
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
/**
|
||||
* 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.message.security;
|
||||
|
||||
import javax.jms.Connection;
|
||||
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 java.io.IOException;
|
||||
|
||||
import org.apache.activemq.EmbeddedBrokerTestSupport;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.ConnectionContext;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.apache.activemq.command.Message;
|
||||
import org.apache.activemq.security.MessageAuthorizationPolicy;
|
||||
import org.apache.activemq.spring.ConsumerBean;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class MessageAuthenticationTest extends EmbeddedBrokerTestSupport {
|
||||
|
||||
private Connection connection;
|
||||
|
||||
public void testSendInvalidMessage() throws Exception {
|
||||
if (connection == null) {
|
||||
connection = createConnection();
|
||||
}
|
||||
connection.start();
|
||||
|
||||
ConsumerBean messageList = new ConsumerBean();
|
||||
messageList.setVerbose(true);
|
||||
|
||||
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
|
||||
Destination destination = new ActiveMQQueue("MyQueue");
|
||||
|
||||
MessageConsumer c1 = session.createConsumer(destination);
|
||||
|
||||
c1.setMessageListener(messageList);
|
||||
|
||||
MessageProducer producer = session.createProducer(destination);
|
||||
assertNotNull(producer);
|
||||
|
||||
producer.send(createMessage(session, "invalidBody", "myHeader", "xyz"));
|
||||
producer.send(createMessage(session, "validBody", "myHeader", "abc"));
|
||||
|
||||
messageList.assertMessagesArrived(1);
|
||||
assertEquals("validBody", ((TextMessage) messageList.flushMessages().get(0)).getText());
|
||||
}
|
||||
|
||||
private javax.jms.Message createMessage(Session session,
|
||||
String body,
|
||||
String header,
|
||||
String value) throws JMSException {
|
||||
TextMessage msg = session.createTextMessage(body);
|
||||
msg.setStringProperty(header, value);
|
||||
return msg;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerService answer = new BrokerService();
|
||||
answer.setPersistent(false);
|
||||
answer.setMessageAuthorizationPolicy(new MessageAuthorizationPolicy() {
|
||||
@Override
|
||||
public boolean isAllowedToConsume(ConnectionContext context, Message message) {
|
||||
try {
|
||||
Object value = message.getProperty("myHeader");
|
||||
return "abc".equals(value);
|
||||
} catch (IOException e) {
|
||||
System.out.println("Caught: " + e);
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
answer.addConnector(bindAddress);
|
||||
return answer;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
<?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.
|
||||
-->
|
||||
|
||||
<!-- this file can only be parsed using the xbean-spring library with validation off -->
|
||||
<beans
|
||||
xmlns="http://www.springframework.org/schema/beans"
|
||||
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
|
||||
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
||||
|
||||
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />
|
||||
|
||||
<broker xmlns="http://activemq.apache.org/schema/core">
|
||||
<systemUsage>
|
||||
<systemUsage>
|
||||
<memoryUsage>
|
||||
<memoryUsage limit="20 mb"/>
|
||||
</memoryUsage>
|
||||
<storeUsage>
|
||||
<storeUsage limit="1 gb" name="foo"/>
|
||||
</storeUsage>
|
||||
<tempUsage>
|
||||
<tempUsage limit="100 mb"/>
|
||||
</tempUsage>
|
||||
</systemUsage>
|
||||
</systemUsage>
|
||||
<destinations>
|
||||
<queue physicalName="FOO.BAR"/>
|
||||
<topic physicalName="SOME.TOPIC"/>
|
||||
</destinations>
|
||||
|
||||
</broker>
|
||||
|
||||
</beans>
|
|
@ -1,53 +0,0 @@
|
|||
/**
|
||||
* 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.partition;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.activemq.broker.BrokerFactory;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.partition.PartitionBrokerPlugin;
|
||||
import org.apache.activemq.partition.dto.Partitioning;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class SpringPartitionBrokerTest extends TestCase {
|
||||
|
||||
public void testCreatePartitionBroker() throws Exception {
|
||||
|
||||
BrokerService broker = BrokerFactory.createBroker("xbean:activemq-partition.xml");
|
||||
assertEquals(1, broker.getPlugins().length);
|
||||
PartitionBrokerPlugin plugin = (PartitionBrokerPlugin) broker.getPlugins()[0];
|
||||
Partitioning config = plugin.getConfig();
|
||||
assertEquals(2, config.getBrokers().size());
|
||||
|
||||
String json = "{\n" +
|
||||
" \"by_client_id\":{\n" +
|
||||
" \"client1\":{\"ids\":[\"broker1\"]},\n" +
|
||||
" \"client2\":{\"ids\":[\"broker1\",\"broker2\"]}\n" +
|
||||
" },\n" +
|
||||
" \"brokers\":{\n" +
|
||||
" \"broker1\":\"tcp://localhost:61616\",\n" +
|
||||
" \"broker2\":\"tcp://localhost:61616\"\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
Partitioning expected = Partitioning.MAPPER.readValue(json, Partitioning.class);
|
||||
assertEquals(expected.toString(), config.toString());
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,177 +0,0 @@
|
|||
/**
|
||||
* 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.policy;
|
||||
|
||||
import javax.jms.ConnectionFactory;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageConsumer;
|
||||
import javax.jms.Session;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnection;
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.region.policy.AbortSlowAckConsumerStrategy;
|
||||
import org.apache.activemq.broker.region.policy.PolicyEntry;
|
||||
import org.apache.activemq.broker.region.policy.PolicyMap;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
@RunWith(value = Parameterized.class)
|
||||
public class AbortSlowAckConsumer0Test extends AbortSlowConsumer0Test {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AbortSlowAckConsumer0Test.class);
|
||||
protected long maxTimeSinceLastAck = 5 * 1000;
|
||||
|
||||
AbortSlowAckConsumerStrategy strategy;
|
||||
|
||||
public AbortSlowAckConsumer0Test(Boolean isTopic) {
|
||||
super(isTopic);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbortSlowAckConsumerStrategy createSlowConsumerStrategy() {
|
||||
AbortSlowAckConsumerStrategy strategy = new AbortSlowAckConsumerStrategy();
|
||||
strategy.setAbortConnection(abortConnection);
|
||||
strategy.setCheckPeriod(checkPeriod);
|
||||
strategy.setMaxSlowDuration(maxSlowDuration);
|
||||
strategy.setMaxTimeSinceLastAck(maxTimeSinceLastAck);
|
||||
|
||||
return strategy;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerService broker = super.createBroker();
|
||||
PolicyEntry policy = new PolicyEntry();
|
||||
|
||||
strategy = createSlowConsumerStrategy();
|
||||
underTest = strategy;
|
||||
|
||||
policy.setSlowConsumerStrategy(strategy);
|
||||
policy.setQueuePrefetch(10);
|
||||
policy.setTopicPrefetch(10);
|
||||
PolicyMap pMap = new PolicyMap();
|
||||
pMap.setDefaultEntry(policy);
|
||||
broker.setDestinationPolicy(pMap);
|
||||
return broker;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConnectionFactory createConnectionFactory() throws Exception {
|
||||
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://localhost");
|
||||
factory.getPrefetchPolicy().setAll(1);
|
||||
return factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
public void testSlowConsumerIsAbortedViaJmx() throws Exception {
|
||||
strategy.setMaxTimeSinceLastAck(500); // so jmx does the abort
|
||||
super.testSlowConsumerIsAbortedViaJmx();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZeroPrefetchConsumerIsAborted() throws Exception {
|
||||
strategy.setMaxTimeSinceLastAck(2000); // Make it shorter
|
||||
|
||||
ActiveMQConnection conn = (ActiveMQConnection) createConnectionFactory().createConnection();
|
||||
conn.setExceptionListener(this);
|
||||
connections.add(conn);
|
||||
|
||||
Session sess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
|
||||
final MessageConsumer consumer = sess.createConsumer(destination);
|
||||
assertNotNull(consumer);
|
||||
conn.start();
|
||||
startProducers(destination, 20);
|
||||
|
||||
Message message = consumer.receive(5000);
|
||||
assertNotNull(message);
|
||||
|
||||
TimeUnit.SECONDS.sleep(15);
|
||||
|
||||
try {
|
||||
consumer.receive(5000);
|
||||
fail("Slow consumer not aborted.");
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdleConsumerCanBeAbortedNoMessages() throws Exception {
|
||||
strategy.setIgnoreIdleConsumers(false);
|
||||
strategy.setMaxTimeSinceLastAck(2000); // Make it shorter
|
||||
|
||||
ActiveMQConnection conn = (ActiveMQConnection) createConnectionFactory().createConnection();
|
||||
conn.setExceptionListener(this);
|
||||
connections.add(conn);
|
||||
|
||||
Session sess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
|
||||
final MessageConsumer consumer = sess.createConsumer(destination);
|
||||
assertNotNull(consumer);
|
||||
conn.start();
|
||||
|
||||
startProducers(destination, 1);
|
||||
|
||||
Message message = consumer.receive(5000);
|
||||
assertNotNull(message);
|
||||
|
||||
// Consumer needs to be closed before the receive call.
|
||||
TimeUnit.SECONDS.sleep(15);
|
||||
|
||||
try {
|
||||
consumer.receive(5000);
|
||||
fail("Idle consumer not aborted.");
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdleConsumerCanBeAborted() throws Exception {
|
||||
strategy.setIgnoreIdleConsumers(false);
|
||||
strategy.setMaxTimeSinceLastAck(2000); // Make it shorter
|
||||
|
||||
ActiveMQConnection conn = (ActiveMQConnection) createConnectionFactory().createConnection();
|
||||
conn.setExceptionListener(this);
|
||||
connections.add(conn);
|
||||
|
||||
Session sess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
|
||||
final MessageConsumer consumer = sess.createConsumer(destination);
|
||||
assertNotNull(consumer);
|
||||
conn.start();
|
||||
startProducers(destination, 1);
|
||||
|
||||
Message message = consumer.receive(5000);
|
||||
assertNotNull(message);
|
||||
message.acknowledge();
|
||||
|
||||
// Consumer needs to be closed before the receive call.
|
||||
TimeUnit.SECONDS.sleep(15);
|
||||
|
||||
try {
|
||||
consumer.receive(5000);
|
||||
fail("Idle consumer not aborted.");
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
/**
|
||||
* 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.policy;
|
||||
|
||||
import javax.jms.ConnectionFactory;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.region.policy.AbortSlowAckConsumerStrategy;
|
||||
import org.apache.activemq.broker.region.policy.AbortSlowConsumerStrategy;
|
||||
import org.apache.activemq.broker.region.policy.PolicyEntry;
|
||||
import org.apache.activemq.broker.region.policy.PolicyMap;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
@RunWith(value = Parameterized.class)
|
||||
public class AbortSlowAckConsumer1Test extends AbortSlowConsumer1Test {
|
||||
|
||||
protected long maxTimeSinceLastAck = 5 * 1000;
|
||||
|
||||
public AbortSlowAckConsumer1Test(Boolean abortConnection, Boolean topic) {
|
||||
super(abortConnection, topic);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbortSlowConsumerStrategy createSlowConsumerStrategy() {
|
||||
return new AbortSlowConsumerStrategy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerService broker = super.createBroker();
|
||||
PolicyEntry policy = new PolicyEntry();
|
||||
|
||||
AbortSlowAckConsumerStrategy strategy = new AbortSlowAckConsumerStrategy();
|
||||
strategy.setAbortConnection(abortConnection);
|
||||
strategy.setCheckPeriod(checkPeriod);
|
||||
strategy.setMaxSlowDuration(maxSlowDuration);
|
||||
strategy.setMaxTimeSinceLastAck(maxTimeSinceLastAck);
|
||||
|
||||
policy.setSlowConsumerStrategy(strategy);
|
||||
policy.setQueuePrefetch(10);
|
||||
policy.setTopicPrefetch(10);
|
||||
PolicyMap pMap = new PolicyMap();
|
||||
pMap.setDefaultEntry(policy);
|
||||
broker.setDestinationPolicy(pMap);
|
||||
return broker;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConnectionFactory createConnectionFactory() throws Exception {
|
||||
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://localhost");
|
||||
factory.getPrefetchPolicy().setAll(1);
|
||||
return factory;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
/**
|
||||
* 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.policy;
|
||||
|
||||
import javax.jms.ConnectionFactory;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.region.policy.AbortSlowAckConsumerStrategy;
|
||||
import org.apache.activemq.broker.region.policy.AbortSlowConsumerStrategy;
|
||||
import org.apache.activemq.broker.region.policy.PolicyEntry;
|
||||
import org.apache.activemq.broker.region.policy.PolicyMap;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
@RunWith(value = Parameterized.class)
|
||||
public class AbortSlowAckConsumer2Test extends AbortSlowConsumer2Test {
|
||||
|
||||
protected long maxTimeSinceLastAck = 5 * 1000;
|
||||
|
||||
public AbortSlowAckConsumer2Test(Boolean topic) {
|
||||
super(topic);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbortSlowConsumerStrategy createSlowConsumerStrategy() {
|
||||
return new AbortSlowConsumerStrategy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerService broker = super.createBroker();
|
||||
PolicyEntry policy = new PolicyEntry();
|
||||
|
||||
AbortSlowAckConsumerStrategy strategy = new AbortSlowAckConsumerStrategy();
|
||||
strategy.setAbortConnection(abortConnection);
|
||||
strategy.setCheckPeriod(checkPeriod);
|
||||
strategy.setMaxSlowDuration(maxSlowDuration);
|
||||
strategy.setMaxTimeSinceLastAck(maxTimeSinceLastAck);
|
||||
|
||||
policy.setSlowConsumerStrategy(strategy);
|
||||
policy.setQueuePrefetch(10);
|
||||
policy.setTopicPrefetch(10);
|
||||
PolicyMap pMap = new PolicyMap();
|
||||
pMap.setDefaultEntry(policy);
|
||||
broker.setDestinationPolicy(pMap);
|
||||
return broker;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConnectionFactory createConnectionFactory() throws Exception {
|
||||
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://localhost");
|
||||
factory.getPrefetchPolicy().setAll(1);
|
||||
return factory;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,240 +0,0 @@
|
|||
/**
|
||||
* 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.policy;
|
||||
|
||||
import javax.jms.Connection;
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.MessageConsumer;
|
||||
import javax.jms.Session;
|
||||
import javax.management.InstanceNotFoundException;
|
||||
import javax.management.ObjectName;
|
||||
import javax.management.openmbean.CompositeData;
|
||||
import javax.management.openmbean.TabularData;
|
||||
import java.lang.reflect.UndeclaredThrowableException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.ActiveMQMessageConsumer;
|
||||
import org.apache.activemq.ActiveMQPrefetchPolicy;
|
||||
import org.apache.activemq.broker.TransportConnector;
|
||||
import org.apache.activemq.broker.jmx.AbortSlowConsumerStrategyViewMBean;
|
||||
import org.apache.activemq.broker.jmx.DestinationViewMBean;
|
||||
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.apache.activemq.util.SocketProxy;
|
||||
import org.apache.activemq.util.Wait;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
@RunWith(value = Parameterized.class)
|
||||
public class AbortSlowConsumer0Test extends AbortSlowConsumerBase {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AbortSlowConsumer0Test.class);
|
||||
|
||||
@Parameterized.Parameters(name = "isTopic({0})")
|
||||
public static Collection<Object[]> getTestParameters() {
|
||||
return Arrays.asList(new Object[][]{{Boolean.TRUE}, {Boolean.FALSE}});
|
||||
}
|
||||
|
||||
public AbortSlowConsumer0Test(Boolean isTopic) {
|
||||
this.topic = isTopic;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegularConsumerIsNotAborted() throws Exception {
|
||||
startConsumers(destination);
|
||||
for (Connection c : connections) {
|
||||
c.setExceptionListener(this);
|
||||
}
|
||||
startProducers(destination, 100);
|
||||
allMessagesList.waitForMessagesToArrive(10);
|
||||
allMessagesList.assertAtLeastMessagesReceived(10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSlowConsumerIsAbortedViaJmx() throws Exception {
|
||||
underTest.setMaxSlowDuration(60 * 1000); // so jmx does the abort
|
||||
startConsumers(withPrefetch(2, destination));
|
||||
Entry<MessageConsumer, MessageIdList> consumertoAbort = consumers.entrySet().iterator().next();
|
||||
consumertoAbort.getValue().setProcessingDelay(8 * 1000);
|
||||
for (Connection c : connections) {
|
||||
c.setExceptionListener(this);
|
||||
}
|
||||
startProducers(destination, 100);
|
||||
|
||||
consumertoAbort.getValue().assertMessagesReceived(1);
|
||||
|
||||
ActiveMQDestination amqDest = (ActiveMQDestination) destination;
|
||||
ObjectName destinationViewMBean = new ObjectName("org.apache.activemq:destinationType=" +
|
||||
(amqDest.isTopic() ? "Topic" : "Queue") + ",destinationName=" + amqDest.getPhysicalName() + ",type=Broker,brokerName=localhost");
|
||||
|
||||
DestinationViewMBean queue = (DestinationViewMBean) broker.getManagementContext().newProxyInstance(destinationViewMBean, DestinationViewMBean.class, true);
|
||||
ObjectName slowConsumerPolicyMBeanName = queue.getSlowConsumerStrategy();
|
||||
|
||||
assertNotNull(slowConsumerPolicyMBeanName);
|
||||
|
||||
AbortSlowConsumerStrategyViewMBean abortPolicy = (AbortSlowConsumerStrategyViewMBean) broker.getManagementContext().newProxyInstance(slowConsumerPolicyMBeanName, AbortSlowConsumerStrategyViewMBean.class, true);
|
||||
|
||||
TimeUnit.SECONDS.sleep(3);
|
||||
|
||||
TabularData slowOnes = abortPolicy.getSlowConsumers();
|
||||
assertEquals("one slow consumers", 1, slowOnes.size());
|
||||
|
||||
LOG.info("slow ones:" + slowOnes);
|
||||
|
||||
CompositeData slowOne = (CompositeData) slowOnes.values().iterator().next();
|
||||
LOG.info("Slow one: " + slowOne);
|
||||
|
||||
assertTrue("we have an object name", slowOne.get("subscription") instanceof ObjectName);
|
||||
abortPolicy.abortConsumer((ObjectName) slowOne.get("subscription"));
|
||||
|
||||
consumertoAbort.getValue().assertAtMostMessagesReceived(1);
|
||||
|
||||
slowOnes = abortPolicy.getSlowConsumers();
|
||||
assertEquals("no slow consumers left", 0, slowOnes.size());
|
||||
|
||||
// verify mbean gone with destination
|
||||
broker.getAdminView().removeTopic(amqDest.getPhysicalName());
|
||||
|
||||
try {
|
||||
abortPolicy.getSlowConsumers();
|
||||
fail("expect not found post destination removal");
|
||||
} catch (UndeclaredThrowableException expected) {
|
||||
assertTrue("correct exception: " + expected.getCause(), expected.getCause() instanceof InstanceNotFoundException);
|
||||
}
|
||||
}
|
||||
|
||||
private Destination withPrefetch(int i, Destination destination) {
|
||||
String destWithPrefetch = ((ActiveMQDestination) destination).getPhysicalName() + "?consumer.prefetchSize=" + i;
|
||||
return topic ? new ActiveMQTopic(destWithPrefetch) : new ActiveMQQueue(destWithPrefetch);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnlyOneSlowConsumerIsAborted() throws Exception {
|
||||
consumerCount = 10;
|
||||
startConsumers(destination);
|
||||
Entry<MessageConsumer, MessageIdList> consumertoAbort = consumers.entrySet().iterator().next();
|
||||
consumertoAbort.getValue().setProcessingDelay(8 * 1000);
|
||||
for (Connection c : connections) {
|
||||
c.setExceptionListener(this);
|
||||
}
|
||||
startProducers(destination, 100);
|
||||
|
||||
allMessagesList.waitForMessagesToArrive(99);
|
||||
allMessagesList.assertAtLeastMessagesReceived(99);
|
||||
|
||||
consumertoAbort.getValue().assertMessagesReceived(1);
|
||||
TimeUnit.SECONDS.sleep(5);
|
||||
consumertoAbort.getValue().assertAtMostMessagesReceived(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAbortAlreadyClosingConsumers() throws Exception {
|
||||
consumerCount = 1;
|
||||
startConsumers(withPrefetch(2, destination));
|
||||
for (MessageIdList list : consumers.values()) {
|
||||
list.setProcessingDelay(6 * 1000);
|
||||
}
|
||||
for (Connection c : connections) {
|
||||
c.setExceptionListener(this);
|
||||
}
|
||||
startProducers(destination, 100);
|
||||
allMessagesList.waitForMessagesToArrive(consumerCount);
|
||||
|
||||
for (MessageConsumer consumer : consumers.keySet()) {
|
||||
LOG.info("closing consumer: " + consumer);
|
||||
/// will block waiting for on message till 6secs expire
|
||||
consumer.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAbortConsumerOnDeadConnection() throws Exception {
|
||||
TransportConnector transportConnector = broker.addConnector("tcp://0.0.0.0:0");
|
||||
transportConnector.setBrokerService(broker);
|
||||
transportConnector.setTaskRunnerFactory(broker.getTaskRunnerFactory());
|
||||
transportConnector.start();
|
||||
SocketProxy socketProxy = new SocketProxy(transportConnector.getPublishableConnectURI());
|
||||
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(socketProxy.getUrl());
|
||||
ActiveMQPrefetchPolicy prefetchPolicy = new ActiveMQPrefetchPolicy();
|
||||
prefetchPolicy.setAll(4);
|
||||
connectionFactory.setPrefetchPolicy(prefetchPolicy);
|
||||
Connection c = connectionFactory.createConnection();
|
||||
connections.add(c);
|
||||
c.start();
|
||||
Session session = c.createSession(false, Session.CLIENT_ACKNOWLEDGE);
|
||||
final ActiveMQMessageConsumer messageconsumer = (ActiveMQMessageConsumer) session.createConsumer(destination);
|
||||
startProducers(destination, 10);
|
||||
|
||||
messageconsumer.receive(4000).acknowledge();
|
||||
assertNotNull(messageconsumer.receive(4000));
|
||||
assertNotNull(messageconsumer.receive(4000));
|
||||
assertNotNull(messageconsumer.receive(4000));
|
||||
|
||||
// close control command won't get through
|
||||
socketProxy.pause();
|
||||
|
||||
ActiveMQDestination amqDest = (ActiveMQDestination) destination;
|
||||
ObjectName destinationViewMBean = new ObjectName("org.apache.activemq:destinationType=" +
|
||||
(amqDest.isTopic() ? "Topic" : "Queue") + ",destinationName=" + amqDest.getPhysicalName() + ",type=Broker,brokerName=localhost");
|
||||
|
||||
final DestinationViewMBean destView = (DestinationViewMBean) broker.getManagementContext().newProxyInstance(destinationViewMBean, DestinationViewMBean.class, true);
|
||||
|
||||
assertTrue("Consumer gone from broker view", Wait.waitFor(new Wait.Condition() {
|
||||
@Override
|
||||
public boolean isSatisified() throws Exception {
|
||||
LOG.info("DestView {} consumerCount {}", destView, destView.getConsumerCount());
|
||||
return 0 == destView.getConsumerCount();
|
||||
}
|
||||
}));
|
||||
|
||||
socketProxy.goOn();
|
||||
|
||||
assertTrue("consumer was closed", Wait.waitFor(new Wait.Condition() {
|
||||
@Override
|
||||
public boolean isSatisified() throws Exception {
|
||||
boolean closed = false;
|
||||
try {
|
||||
messageconsumer.receive(400);
|
||||
} catch (javax.jms.IllegalStateException expected) {
|
||||
closed = expected.toString().contains("closed");
|
||||
}
|
||||
return closed;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(JMSException exception) {
|
||||
exceptions.add(exception);
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
/**
|
||||
* 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.policy;
|
||||
|
||||
import javax.jms.Connection;
|
||||
import javax.jms.MessageConsumer;
|
||||
import javax.jms.Session;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.activemq.util.MessageIdList;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@RunWith(value = Parameterized.class)
|
||||
public class AbortSlowConsumer1Test extends AbortSlowConsumerBase {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AbortSlowConsumer1Test.class);
|
||||
|
||||
@Parameterized.Parameters(name = "abortConnection({0})-isTopic({1})")
|
||||
public static Collection<Object[]> getTestParameters() {
|
||||
return Arrays.asList(new Object[][]{{Boolean.TRUE, Boolean.TRUE}, {Boolean.TRUE, Boolean.FALSE}, {Boolean.FALSE, Boolean.TRUE}, {Boolean.FALSE, Boolean.FALSE}});
|
||||
}
|
||||
|
||||
public AbortSlowConsumer1Test(Boolean abortConnection, Boolean topic) {
|
||||
this.abortConnection = abortConnection;
|
||||
this.topic = topic;
|
||||
}
|
||||
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testSlowConsumerIsAborted() throws Exception {
|
||||
startConsumers(destination);
|
||||
Entry<MessageConsumer, MessageIdList> consumertoAbort = consumers.entrySet().iterator().next();
|
||||
consumertoAbort.getValue().setProcessingDelay(8 * 1000);
|
||||
for (Connection c : connections) {
|
||||
c.setExceptionListener(this);
|
||||
}
|
||||
startProducers(destination, 100);
|
||||
|
||||
consumertoAbort.getValue().assertMessagesReceived(1);
|
||||
TimeUnit.SECONDS.sleep(5);
|
||||
consumertoAbort.getValue().assertAtMostMessagesReceived(1);
|
||||
}
|
||||
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testAbortAlreadyClosedConsumers() throws Exception {
|
||||
Connection conn = createConnectionFactory().createConnection();
|
||||
conn.setExceptionListener(this);
|
||||
connections.add(conn);
|
||||
|
||||
Session sess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
|
||||
final MessageConsumer consumer = sess.createConsumer(destination);
|
||||
conn.start();
|
||||
startProducers(destination, 20);
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
LOG.info("closing consumer: " + consumer);
|
||||
consumer.close();
|
||||
|
||||
TimeUnit.SECONDS.sleep(5);
|
||||
assertTrue("no exceptions : " + exceptions, exceptions.isEmpty());
|
||||
}
|
||||
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testAbortAlreadyClosedConnection() throws Exception {
|
||||
Connection conn = createConnectionFactory().createConnection();
|
||||
conn.setExceptionListener(this);
|
||||
|
||||
Session sess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
|
||||
sess.createConsumer(destination);
|
||||
conn.start();
|
||||
startProducers(destination, 20);
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
LOG.info("closing connection: " + conn);
|
||||
conn.close();
|
||||
|
||||
TimeUnit.SECONDS.sleep(5);
|
||||
assertTrue("no exceptions : " + exceptions, exceptions.isEmpty());
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
/**
|
||||
* 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.policy;
|
||||
|
||||
import javax.jms.Connection;
|
||||
import javax.jms.MessageConsumer;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.activemq.util.MessageIdList;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
@RunWith(value = Parameterized.class)
|
||||
public class AbortSlowConsumer2Test extends AbortSlowConsumerBase {
|
||||
|
||||
@Parameterized.Parameters(name = "isTopic({0})")
|
||||
public static Collection<Object[]> getTestParameters() {
|
||||
return Arrays.asList(new Object[][]{{Boolean.TRUE}, {Boolean.FALSE}});
|
||||
}
|
||||
|
||||
public AbortSlowConsumer2Test(Boolean isTopic) {
|
||||
this.topic = isTopic;
|
||||
}
|
||||
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testLittleSlowConsumerIsNotAborted() throws Exception {
|
||||
startConsumers(destination);
|
||||
Entry<MessageConsumer, MessageIdList> consumertoAbort = consumers.entrySet().iterator().next();
|
||||
consumertoAbort.getValue().setProcessingDelay(500);
|
||||
for (Connection c : connections) {
|
||||
c.setExceptionListener(this);
|
||||
}
|
||||
startProducers(destination, 12);
|
||||
allMessagesList.waitForMessagesToArrive(10);
|
||||
allMessagesList.assertAtLeastMessagesReceived(10);
|
||||
}
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
/**
|
||||
* 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.policy;
|
||||
|
||||
import javax.jms.ExceptionListener;
|
||||
import javax.jms.JMSException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.activemq.JmsMultipleClientsTestSupport;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.region.policy.AbortSlowConsumerStrategy;
|
||||
import org.apache.activemq.broker.region.policy.PolicyEntry;
|
||||
import org.apache.activemq.broker.region.policy.PolicyMap;
|
||||
import org.junit.Before;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class AbortSlowConsumerBase extends JmsMultipleClientsTestSupport implements ExceptionListener {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AbortSlowConsumerBase.class);
|
||||
|
||||
protected AbortSlowConsumerStrategy underTest;
|
||||
protected boolean abortConnection = false;
|
||||
protected long checkPeriod = 2 * 1000;
|
||||
protected long maxSlowDuration = 5 * 1000;
|
||||
protected final List<Throwable> exceptions = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
exceptions.clear();
|
||||
topic = true;
|
||||
underTest = createSlowConsumerStrategy();
|
||||
super.setUp();
|
||||
createDestination();
|
||||
}
|
||||
|
||||
protected AbortSlowConsumerStrategy createSlowConsumerStrategy() {
|
||||
return new AbortSlowConsumerStrategy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerService broker = super.createBroker();
|
||||
PolicyEntry policy = new PolicyEntry();
|
||||
underTest.setAbortConnection(abortConnection);
|
||||
underTest.setCheckPeriod(checkPeriod);
|
||||
underTest.setMaxSlowDuration(maxSlowDuration);
|
||||
|
||||
policy.setSlowConsumerStrategy(underTest);
|
||||
policy.setQueuePrefetch(10);
|
||||
policy.setTopicPrefetch(10);
|
||||
PolicyMap pMap = new PolicyMap();
|
||||
pMap.setDefaultEntry(policy);
|
||||
broker.setDestinationPolicy(pMap);
|
||||
return broker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(JMSException exception) {
|
||||
exceptions.add(exception);
|
||||
exception.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
/**
|
||||
* 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.policy;
|
||||
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.Message;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnection;
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.RedeliveryPolicy;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class DeadLetterTest extends DeadLetterTestSupport {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DeadLetterTest.class);
|
||||
|
||||
protected int rollbackCount;
|
||||
|
||||
@Override
|
||||
protected void doTest() throws Exception {
|
||||
connection.start();
|
||||
|
||||
ActiveMQConnection amqConnection = (ActiveMQConnection) connection;
|
||||
rollbackCount = amqConnection.getRedeliveryPolicy().getMaximumRedeliveries() + 1;
|
||||
LOG.info("Will redeliver messages: " + rollbackCount + " times");
|
||||
|
||||
makeConsumer();
|
||||
makeDlqConsumer();
|
||||
|
||||
sendMessages();
|
||||
|
||||
// now lets receive and rollback N times
|
||||
for (int i = 0; i < messageCount; i++) {
|
||||
consumeAndRollback(i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < messageCount; i++) {
|
||||
Message msg = dlqConsumer.receive(1000);
|
||||
assertMessage(msg, i);
|
||||
assertNotNull("Should be a DLQ message for loop: " + i, msg);
|
||||
}
|
||||
session.commit();
|
||||
}
|
||||
|
||||
protected void consumeAndRollback(int messageCounter) throws Exception {
|
||||
for (int i = 0; i < rollbackCount; i++) {
|
||||
Message message = consumer.receive(5000);
|
||||
assertNotNull("No message received for message: " + messageCounter + " and rollback loop: " + i, message);
|
||||
assertMessage(message, messageCounter);
|
||||
|
||||
session.rollback();
|
||||
}
|
||||
LOG.info("Rolled back: " + rollbackCount + " times");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
transactedMode = true;
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ActiveMQConnectionFactory createConnectionFactory() throws Exception {
|
||||
ActiveMQConnectionFactory answer = super.createConnectionFactory();
|
||||
RedeliveryPolicy policy = new RedeliveryPolicy();
|
||||
policy.setMaximumRedeliveries(3);
|
||||
policy.setBackOffMultiplier((short) 1);
|
||||
policy.setInitialRedeliveryDelay(10);
|
||||
policy.setUseExponentialBackOff(false);
|
||||
answer.setRedeliveryPolicy(policy);
|
||||
return answer;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Destination createDlqDestination() {
|
||||
return new ActiveMQQueue("ActiveMQ.DLQ");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,213 +0,0 @@
|
|||
/**
|
||||
* 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.policy;
|
||||
|
||||
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.QueueBrowser;
|
||||
import javax.jms.Session;
|
||||
import javax.jms.TextMessage;
|
||||
import javax.jms.Topic;
|
||||
|
||||
import org.apache.activemq.TestSupport;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.region.DestinationStatistics;
|
||||
import org.apache.activemq.broker.region.RegionBroker;
|
||||
import org.apache.activemq.broker.region.policy.DeadLetterStrategy;
|
||||
import org.apache.activemq.broker.region.policy.PolicyEntry;
|
||||
import org.apache.activemq.broker.region.policy.PolicyMap;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public abstract class DeadLetterTestSupport extends TestSupport {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DeadLetterTestSupport.class);
|
||||
|
||||
protected int messageCount = 10;
|
||||
protected long timeToLive;
|
||||
protected Connection connection;
|
||||
protected Session session;
|
||||
protected MessageConsumer consumer;
|
||||
protected MessageProducer producer;
|
||||
protected int deliveryMode = DeliveryMode.PERSISTENT;
|
||||
protected boolean durableSubscriber;
|
||||
protected Destination dlqDestination;
|
||||
protected MessageConsumer dlqConsumer;
|
||||
protected QueueBrowser dlqBrowser;
|
||||
protected BrokerService broker;
|
||||
protected boolean transactedMode;
|
||||
protected int acknowledgeMode = Session.CLIENT_ACKNOWLEDGE;
|
||||
private Destination destination;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
broker = createBroker();
|
||||
broker.start();
|
||||
connection = createConnection();
|
||||
connection.setClientID(createClientId());
|
||||
|
||||
session = connection.createSession(transactedMode, acknowledgeMode);
|
||||
connection.start();
|
||||
}
|
||||
|
||||
protected String createClientId() {
|
||||
return toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
if (connection != null) {
|
||||
connection.close();
|
||||
}
|
||||
if (broker != null) {
|
||||
broker.stop();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void doTest() throws Exception;
|
||||
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerService broker = new BrokerService();
|
||||
broker.setPersistent(false);
|
||||
PolicyEntry policy = new PolicyEntry();
|
||||
DeadLetterStrategy defaultDeadLetterStrategy = policy.getDeadLetterStrategy();
|
||||
if (defaultDeadLetterStrategy != null) {
|
||||
defaultDeadLetterStrategy.setProcessNonPersistent(true);
|
||||
}
|
||||
PolicyMap pMap = new PolicyMap();
|
||||
pMap.setDefaultEntry(policy);
|
||||
broker.setDestinationPolicy(pMap);
|
||||
return broker;
|
||||
}
|
||||
|
||||
protected void makeConsumer() throws JMSException {
|
||||
Destination destination = getDestination();
|
||||
LOG.info("Consuming from: " + destination);
|
||||
if (durableSubscriber) {
|
||||
consumer = session.createDurableSubscriber((Topic) destination, destination.toString());
|
||||
} else {
|
||||
consumer = session.createConsumer(destination);
|
||||
}
|
||||
}
|
||||
|
||||
protected void makeDlqConsumer() throws Exception {
|
||||
dlqDestination = createDlqDestination();
|
||||
|
||||
LOG.info("Consuming from dead letter on: " + dlqDestination);
|
||||
dlqConsumer = session.createConsumer(dlqDestination);
|
||||
}
|
||||
|
||||
protected void makeDlqBrowser() throws JMSException {
|
||||
dlqDestination = createDlqDestination();
|
||||
|
||||
LOG.info("Browsing dead letter on: " + dlqDestination);
|
||||
dlqBrowser = session.createBrowser((Queue) dlqDestination);
|
||||
}
|
||||
|
||||
protected void sendMessages() throws JMSException {
|
||||
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
producer = session.createProducer(getDestination());
|
||||
producer.setDeliveryMode(deliveryMode);
|
||||
producer.setTimeToLive(timeToLive);
|
||||
|
||||
LOG.info("Sending " + messageCount + " messages to: " + getDestination());
|
||||
for (int i = 0; i < messageCount; i++) {
|
||||
Message message = createMessage(session, i);
|
||||
producer.send(message);
|
||||
}
|
||||
}
|
||||
|
||||
protected TextMessage createMessage(Session session, int i) throws JMSException {
|
||||
return session.createTextMessage(getMessageText(i));
|
||||
}
|
||||
|
||||
protected String getMessageText(int i) {
|
||||
return "message: " + i;
|
||||
}
|
||||
|
||||
protected void assertMessage(Message message, int i) throws Exception {
|
||||
LOG.info("Received message: " + message);
|
||||
assertNotNull("No message received for index: " + i, message);
|
||||
assertTrue("Should be a TextMessage not: " + message, message instanceof TextMessage);
|
||||
TextMessage textMessage = (TextMessage) message;
|
||||
assertEquals("text of message: " + i, getMessageText(i), textMessage.getText());
|
||||
}
|
||||
|
||||
protected abstract Destination createDlqDestination();
|
||||
|
||||
public void testTransientTopicMessage() throws Exception {
|
||||
super.topic = true;
|
||||
deliveryMode = DeliveryMode.NON_PERSISTENT;
|
||||
durableSubscriber = true;
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testDurableTopicMessage() throws Exception {
|
||||
super.topic = true;
|
||||
deliveryMode = DeliveryMode.PERSISTENT;
|
||||
durableSubscriber = true;
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testTransientQueueMessage() throws Exception {
|
||||
super.topic = false;
|
||||
deliveryMode = DeliveryMode.NON_PERSISTENT;
|
||||
durableSubscriber = false;
|
||||
doTest();
|
||||
validateConsumerPrefetch(this.getDestinationString(), 0);
|
||||
}
|
||||
|
||||
public void testDurableQueueMessage() throws Exception {
|
||||
super.topic = false;
|
||||
deliveryMode = DeliveryMode.PERSISTENT;
|
||||
durableSubscriber = false;
|
||||
doTest();
|
||||
validateConsumerPrefetch(this.getDestinationString(), 0);
|
||||
}
|
||||
|
||||
public Destination getDestination() {
|
||||
if (destination == null) {
|
||||
destination = createDestination();
|
||||
}
|
||||
return destination;
|
||||
}
|
||||
|
||||
private void validateConsumerPrefetch(String destination, long expectedCount) {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
RegionBroker regionBroker = (RegionBroker) broker.getRegionBroker();
|
||||
for (org.apache.activemq.broker.region.Destination dest : regionBroker.getQueueRegion().getDestinationMap().values()) {
|
||||
if (dest.getName().equals(destination)) {
|
||||
DestinationStatistics stats = dest.getDestinationStatistics();
|
||||
LOG.info(">>>> inflight for : " + dest.getName() + ": " + stats.getInflight().getCount());
|
||||
assertEquals("inflight for: " + dest.getName() + ": " + stats.getInflight().getCount() + " matches", expectedCount, stats.getInflight().getCount());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
/**
|
||||
* 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.policy;
|
||||
|
||||
import org.apache.activemq.TestSupport;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.region.policy.PendingQueueMessageStoragePolicy;
|
||||
import org.apache.activemq.broker.region.policy.PendingSubscriberMessageStoragePolicy;
|
||||
import org.apache.activemq.broker.region.policy.PolicyEntry;
|
||||
import org.apache.activemq.broker.region.policy.VMPendingQueueMessageStoragePolicy;
|
||||
import org.apache.activemq.broker.region.policy.VMPendingSubscriberMessageStoragePolicy;
|
||||
import org.apache.activemq.command.ActiveMQDestination;
|
||||
import org.apache.activemq.xbean.BrokerFactoryBean;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class DestinationCursorConfigTest extends TestSupport {
|
||||
|
||||
protected BrokerService broker;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
broker = createBroker();
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
broker.stop();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerFactoryBean factory = new BrokerFactoryBean(new ClassPathResource("org/apache/activemq/broker/policy/cursor.xml"));
|
||||
factory.afterPropertiesSet();
|
||||
BrokerService answer = factory.getBroker();
|
||||
return answer;
|
||||
}
|
||||
|
||||
public void testQueueConfiguration() throws Exception {
|
||||
super.topic = false;
|
||||
ActiveMQDestination destination = (ActiveMQDestination) createDestination("org.apache.foo");
|
||||
PolicyEntry entry = broker.getDestinationPolicy().getEntryFor(destination);
|
||||
PendingQueueMessageStoragePolicy policy = entry.getPendingQueuePolicy();
|
||||
assertNotNull(policy);
|
||||
assertTrue("Policy is: " + policy, policy instanceof VMPendingQueueMessageStoragePolicy);
|
||||
}
|
||||
|
||||
public void testTopicConfiguration() throws Exception {
|
||||
super.topic = true;
|
||||
ActiveMQDestination destination = (ActiveMQDestination) createDestination("org.apache.foo");
|
||||
PolicyEntry entry = broker.getDestinationPolicy().getEntryFor(destination);
|
||||
PendingSubscriberMessageStoragePolicy policy = entry.getPendingSubscriberPolicy();
|
||||
assertNotNull(policy);
|
||||
assertFalse(entry.isProducerFlowControl());
|
||||
assertTrue(entry.getMemoryLimit() == (1024 * 1024));
|
||||
assertTrue("subscriberPolicy is: " + policy, policy instanceof VMPendingSubscriberMessageStoragePolicy);
|
||||
}
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
/**
|
||||
* 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.policy;
|
||||
|
||||
import javax.jms.Message;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnection;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.region.policy.DeadLetterStrategy;
|
||||
import org.apache.activemq.broker.region.policy.DiscardingDeadLetterStrategy;
|
||||
import org.apache.activemq.broker.region.policy.PolicyEntry;
|
||||
import org.apache.activemq.broker.region.policy.PolicyMap;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class DiscardingDeadLetterPolicyTest extends DeadLetterTest {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DiscardingDeadLetterPolicyTest.class);
|
||||
|
||||
@Override
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerService broker = super.createBroker();
|
||||
|
||||
PolicyEntry policy = new PolicyEntry();
|
||||
DeadLetterStrategy strategy = new DiscardingDeadLetterStrategy();
|
||||
strategy.setProcessNonPersistent(true);
|
||||
policy.setDeadLetterStrategy(strategy);
|
||||
|
||||
PolicyMap pMap = new PolicyMap();
|
||||
pMap.setDefaultEntry(policy);
|
||||
|
||||
broker.setDestinationPolicy(pMap);
|
||||
|
||||
return broker;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doTest() throws Exception {
|
||||
connection.start();
|
||||
|
||||
ActiveMQConnection amqConnection = (ActiveMQConnection) connection;
|
||||
rollbackCount = amqConnection.getRedeliveryPolicy().getMaximumRedeliveries() + 1;
|
||||
LOG.info("Will redeliver messages: " + rollbackCount + " times");
|
||||
|
||||
makeConsumer();
|
||||
makeDlqConsumer();
|
||||
|
||||
sendMessages();
|
||||
|
||||
// now lets receive and rollback N times
|
||||
for (int i = 0; i < messageCount; i++) {
|
||||
consumeAndRollback(i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < messageCount; i++) {
|
||||
Message msg = dlqConsumer.receive(1000);
|
||||
assertNull("Should not be a DLQ message for loop: " + i, msg);
|
||||
}
|
||||
session.commit();
|
||||
}
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
/**
|
||||
* 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.policy;
|
||||
|
||||
import javax.jms.DeliveryMode;
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageConsumer;
|
||||
import javax.jms.Queue;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnection;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.region.policy.DeadLetterStrategy;
|
||||
import org.apache.activemq.broker.region.policy.IndividualDeadLetterStrategy;
|
||||
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 IndividualDeadLetterTest extends DeadLetterTest {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(IndividualDeadLetterTest.class);
|
||||
|
||||
@Override
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerService broker = super.createBroker();
|
||||
|
||||
PolicyEntry policy = new PolicyEntry();
|
||||
DeadLetterStrategy strategy = new IndividualDeadLetterStrategy();
|
||||
strategy.setProcessNonPersistent(true);
|
||||
policy.setDeadLetterStrategy(strategy);
|
||||
|
||||
PolicyMap pMap = new PolicyMap();
|
||||
pMap.setDefaultEntry(policy);
|
||||
|
||||
broker.setDestinationPolicy(pMap);
|
||||
|
||||
return broker;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Destination createDlqDestination() {
|
||||
String prefix = topic ? "ActiveMQ.DLQ.Topic." : "ActiveMQ.DLQ.Queue.";
|
||||
return new ActiveMQQueue(prefix + getClass().getName() + "." + getName());
|
||||
}
|
||||
|
||||
public void testDLQBrowsing() throws Exception {
|
||||
super.topic = false;
|
||||
deliveryMode = DeliveryMode.PERSISTENT;
|
||||
durableSubscriber = false;
|
||||
messageCount = 1;
|
||||
|
||||
connection.start();
|
||||
|
||||
ActiveMQConnection amqConnection = (ActiveMQConnection) connection;
|
||||
rollbackCount = amqConnection.getRedeliveryPolicy().getMaximumRedeliveries() + 1;
|
||||
LOG.info("Will redeliver messages: " + rollbackCount + " times");
|
||||
|
||||
sendMessages();
|
||||
|
||||
// now lets receive and rollback N times
|
||||
for (int i = 0; i < rollbackCount; i++) {
|
||||
makeConsumer();
|
||||
Message message = consumer.receive(5000);
|
||||
assertNotNull("No message received: ", message);
|
||||
|
||||
session.rollback();
|
||||
LOG.info("Rolled back: " + rollbackCount + " times");
|
||||
consumer.close();
|
||||
}
|
||||
|
||||
makeDlqBrowser();
|
||||
browseDlq();
|
||||
dlqBrowser.close();
|
||||
session.close();
|
||||
Thread.sleep(1000);
|
||||
session = connection.createSession(transactedMode, acknowledgeMode);
|
||||
Queue testQueue = new ActiveMQQueue("ActiveMQ.DLQ.Queue.ActiveMQ.DLQ.Queue." + getClass().getName() + "." + getName());
|
||||
MessageConsumer testConsumer = session.createConsumer(testQueue);
|
||||
assertNull("The message shouldn't be sent to another DLQ", testConsumer.receive(1000));
|
||||
|
||||
}
|
||||
|
||||
protected void browseDlq() throws Exception {
|
||||
Enumeration<?> messages = dlqBrowser.getEnumeration();
|
||||
while (messages.hasMoreElements()) {
|
||||
LOG.info("Browsing: " + messages.nextElement());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/**
|
||||
* 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.policy;
|
||||
|
||||
import javax.jms.Destination;
|
||||
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.apache.activemq.xbean.BrokerFactoryBean;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class IndividualDeadLetterViaXmlTest extends DeadLetterTest {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(IndividualDeadLetterViaXmlTest.class);
|
||||
|
||||
@Override
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerFactoryBean factory = new BrokerFactoryBean(new ClassPathResource("org/apache/activemq/broker/policy/individual-dlq.xml"));
|
||||
factory.afterPropertiesSet();
|
||||
BrokerService answer = factory.getBroker();
|
||||
return answer;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Destination createDlqDestination() {
|
||||
String queueName = "Test.DLQ." + getClass().getName() + "." + getName();
|
||||
LOG.info("Using queue name: " + queueName);
|
||||
return new ActiveMQQueue(queueName);
|
||||
}
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
/**
|
||||
* 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.policy;
|
||||
|
||||
import org.apache.activemq.TestSupport;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.region.Queue;
|
||||
import org.apache.activemq.broker.region.group.CachedMessageGroupMap;
|
||||
import org.apache.activemq.broker.region.group.MessageGroupHashBucket;
|
||||
import org.apache.activemq.broker.region.group.MessageGroupMap;
|
||||
import org.apache.activemq.broker.region.group.SimpleMessageGroupMap;
|
||||
import org.apache.activemq.broker.region.policy.PolicyEntry;
|
||||
import org.apache.activemq.broker.region.policy.PolicyMap;
|
||||
import org.apache.activemq.command.ActiveMQDestination;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class MessageGroupConfigTest extends TestSupport {
|
||||
|
||||
protected BrokerService broker;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
broker.stop();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
public void testCachedGroupConfiguration() throws Exception {
|
||||
doTestGroupConfiguration("cached", CachedMessageGroupMap.class);
|
||||
}
|
||||
|
||||
public void testCachedGroupConfigurationWithCacheSize() throws Exception {
|
||||
CachedMessageGroupMap result = (CachedMessageGroupMap) doTestGroupConfiguration("cached?cacheSize=10", CachedMessageGroupMap.class);
|
||||
assertEquals(10, result.getMaximumCacheSize());
|
||||
|
||||
}
|
||||
|
||||
public void testSimpleGroupConfiguration() throws Exception {
|
||||
doTestGroupConfiguration("simple", SimpleMessageGroupMap.class);
|
||||
}
|
||||
|
||||
public void testBucketGroupConfiguration() throws Exception {
|
||||
doTestGroupConfiguration("bucket", MessageGroupHashBucket.class);
|
||||
}
|
||||
|
||||
public void testBucketGroupConfigurationWithBucketCount() throws Exception {
|
||||
MessageGroupHashBucket result = (MessageGroupHashBucket) doTestGroupConfiguration("bucket?bucketCount=2", MessageGroupHashBucket.class);
|
||||
assertEquals(2, result.getBucketCount());
|
||||
}
|
||||
|
||||
public MessageGroupMap doTestGroupConfiguration(String type, Class classType) throws Exception {
|
||||
broker = new BrokerService();
|
||||
|
||||
PolicyEntry defaultEntry = new PolicyEntry();
|
||||
defaultEntry.setMessageGroupMapFactoryType(type);
|
||||
PolicyMap policyMap = new PolicyMap();
|
||||
policyMap.setDefaultEntry(defaultEntry);
|
||||
broker.setDestinationPolicy(policyMap);
|
||||
broker.start();
|
||||
super.topic = false;
|
||||
ActiveMQDestination destination = (ActiveMQDestination) createDestination("org.apache.foo");
|
||||
Queue brokerDestination = (Queue) broker.getDestination(destination);
|
||||
|
||||
assertNotNull(brokerDestination);
|
||||
MessageGroupMap messageGroupMap = brokerDestination.getMessageGroupOwners();
|
||||
assertNotNull(messageGroupMap);
|
||||
assertTrue(messageGroupMap.getClass().isAssignableFrom(classType));
|
||||
return messageGroupMap;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,153 +0,0 @@
|
|||
/**
|
||||
* 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.policy;
|
||||
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageListener;
|
||||
import javax.jms.Session;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnection;
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.RedeliveryPolicy;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class MessageListenerDeadLetterTest extends DeadLetterTestSupport {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MessageListenerDeadLetterTest.class);
|
||||
|
||||
private int rollbackCount;
|
||||
|
||||
private Session dlqSession;
|
||||
|
||||
private final Error[] error = new Error[1];
|
||||
|
||||
@Override
|
||||
protected void doTest() throws Exception {
|
||||
messageCount = 200;
|
||||
connection.start();
|
||||
|
||||
ActiveMQConnection amqConnection = (ActiveMQConnection) connection;
|
||||
rollbackCount = amqConnection.getRedeliveryPolicy().getMaximumRedeliveries() + 1;
|
||||
LOG.info("Will redeliver messages: " + rollbackCount + " times");
|
||||
|
||||
makeConsumer();
|
||||
makeDlqConsumer();
|
||||
|
||||
sendMessages();
|
||||
|
||||
// now lets receive and rollback N times
|
||||
int maxRollbacks = messageCount * rollbackCount;
|
||||
consumer.setMessageListener(new RollbackMessageListener(maxRollbacks, rollbackCount));
|
||||
|
||||
for (int i = 0; i < messageCount; i++) {
|
||||
Message msg = dlqConsumer.receive(4000);
|
||||
if (error[0] != null) {
|
||||
// error from message listener
|
||||
throw error[0];
|
||||
}
|
||||
assertMessage(msg, i);
|
||||
assertNotNull("Should be a DLQ message for loop: " + i, msg);
|
||||
}
|
||||
if (error[0] != null) {
|
||||
throw error[0];
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void makeDlqConsumer() throws JMSException {
|
||||
dlqDestination = createDlqDestination();
|
||||
|
||||
LOG.info("Consuming from dead letter on: " + dlqDestination);
|
||||
dlqConsumer = dlqSession.createConsumer(dlqDestination);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
transactedMode = true;
|
||||
super.setUp();
|
||||
dlqSession = connection.createSession(transactedMode, acknowledgeMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
dlqConsumer.close();
|
||||
dlqSession.close();
|
||||
session.close();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ActiveMQConnectionFactory createConnectionFactory() throws Exception {
|
||||
ActiveMQConnectionFactory answer = super.createConnectionFactory();
|
||||
RedeliveryPolicy policy = new RedeliveryPolicy();
|
||||
policy.setMaximumRedeliveries(3);
|
||||
policy.setBackOffMultiplier((short) 1);
|
||||
policy.setRedeliveryDelay(0);
|
||||
policy.setInitialRedeliveryDelay(0);
|
||||
policy.setUseExponentialBackOff(false);
|
||||
answer.setRedeliveryPolicy(policy);
|
||||
return answer;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Destination createDlqDestination() {
|
||||
return new ActiveMQQueue("ActiveMQ.DLQ");
|
||||
}
|
||||
|
||||
class RollbackMessageListener implements MessageListener {
|
||||
|
||||
final int maxRollbacks;
|
||||
|
||||
final int deliveryCount;
|
||||
|
||||
AtomicInteger rollbacks = new AtomicInteger();
|
||||
|
||||
RollbackMessageListener(int c, int delvery) {
|
||||
maxRollbacks = c;
|
||||
deliveryCount = delvery;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(Message message) {
|
||||
try {
|
||||
int expectedMessageId = rollbacks.get() / deliveryCount;
|
||||
LOG.info("expecting messageId: " + expectedMessageId);
|
||||
assertMessage(message, expectedMessageId);
|
||||
if (rollbacks.incrementAndGet() > maxRollbacks) {
|
||||
fail("received too many messages, already done too many rollbacks: " + rollbacks);
|
||||
}
|
||||
session.rollback();
|
||||
|
||||
} catch (Throwable e) {
|
||||
LOG.error("unexpected exception:" + e, e);
|
||||
// propagating assertError to execution task will cause a hang
|
||||
// at shutdown
|
||||
if (e instanceof Error) {
|
||||
error[0] = (Error) e;
|
||||
} else {
|
||||
fail("unexpected exception: " + e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,116 +0,0 @@
|
|||
/**
|
||||
* 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.policy;
|
||||
|
||||
import javax.jms.DeliveryMode;
|
||||
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.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.advisory.AdvisorySupport;
|
||||
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.ActiveMQDestination;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class NoConsumerDeadLetterTest extends DeadLetterTestSupport {
|
||||
|
||||
// lets disable the inapplicable tests
|
||||
@Override
|
||||
public void testDurableQueueMessage() throws Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testDurableTopicMessage() throws Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doTest() throws Exception {
|
||||
makeDlqConsumer();
|
||||
sendMessages();
|
||||
|
||||
for (int i = 0; i < messageCount; i++) {
|
||||
Message msg = dlqConsumer.receive(1000);
|
||||
assertNotNull("Should be a message for loop: " + i, msg);
|
||||
}
|
||||
}
|
||||
|
||||
public void testConsumerReceivesMessages() throws Exception {
|
||||
this.topic = false;
|
||||
ActiveMQConnectionFactory factory = createConnectionFactory();
|
||||
connection = factory.createConnection();
|
||||
connection.start();
|
||||
|
||||
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
MessageProducer producer = session.createProducer(getDestination());
|
||||
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
|
||||
|
||||
Topic advisoryTopic = AdvisorySupport.getNoQueueConsumersAdvisoryTopic(getDestination());
|
||||
MessageConsumer advisoryConsumer = session.createConsumer(advisoryTopic);
|
||||
|
||||
TextMessage msg = session.createTextMessage("Message: x");
|
||||
producer.send(msg);
|
||||
|
||||
Message advisoryMessage = advisoryConsumer.receive(1000);
|
||||
assertNotNull("Advisory message not received", advisoryMessage);
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
factory = createConnectionFactory();
|
||||
connection = factory.createConnection();
|
||||
connection.start();
|
||||
|
||||
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
|
||||
MessageConsumer consumer = session.createConsumer(getDestination());
|
||||
Message received = consumer.receive(1000);
|
||||
assertNotNull("Message not received", received);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerService broker = super.createBroker();
|
||||
|
||||
PolicyEntry policy = new PolicyEntry();
|
||||
policy.setSendAdvisoryIfNoConsumers(true);
|
||||
|
||||
PolicyMap pMap = new PolicyMap();
|
||||
pMap.setDefaultEntry(policy);
|
||||
|
||||
broker.setDestinationPolicy(pMap);
|
||||
|
||||
return broker;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Destination createDlqDestination() {
|
||||
if (this.topic) {
|
||||
return AdvisorySupport.getNoTopicConsumersAdvisoryTopic((ActiveMQDestination) getDestination());
|
||||
} else {
|
||||
return AdvisorySupport.getNoQueueConsumersAdvisoryTopic((ActiveMQDestination) getDestination());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/**
|
||||
* 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.policy;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.RedeliveryPolicy;
|
||||
|
||||
public class NoRetryDeadLetterTest extends DeadLetterTest {
|
||||
|
||||
@Override
|
||||
protected ActiveMQConnectionFactory createConnectionFactory() throws Exception {
|
||||
ActiveMQConnectionFactory connectionFactory = super.createConnectionFactory();
|
||||
RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
|
||||
redeliveryPolicy.setMaximumRedeliveries(0);
|
||||
connectionFactory.setRedeliveryPolicy(redeliveryPolicy);
|
||||
return connectionFactory;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
/**
|
||||
* 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.policy;
|
||||
|
||||
import javax.jms.Destination;
|
||||
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.region.policy.IndividualDeadLetterStrategy;
|
||||
import org.apache.activemq.broker.region.policy.PolicyEntry;
|
||||
import org.apache.activemq.broker.region.policy.PolicyMap;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
|
||||
/**
|
||||
* for durable subs, allow a dlq per subscriber such that poison messages are not duplicates
|
||||
* on the dlq and such that rejecting consumers can be identified
|
||||
* https://issues.apache.org/jira/browse/AMQ-3003
|
||||
*/
|
||||
public class PerDurableConsumerDeadLetterTest extends DeadLetterTest {
|
||||
|
||||
private static final String CLIENT_ID = "george";
|
||||
|
||||
@Override
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerService broker = super.createBroker();
|
||||
|
||||
PolicyEntry policy = new PolicyEntry();
|
||||
IndividualDeadLetterStrategy strategy = new IndividualDeadLetterStrategy();
|
||||
strategy.setProcessNonPersistent(true);
|
||||
strategy.setDestinationPerDurableSubscriber(true);
|
||||
policy.setDeadLetterStrategy(strategy);
|
||||
|
||||
PolicyMap pMap = new PolicyMap();
|
||||
pMap.setDefaultEntry(policy);
|
||||
|
||||
broker.setDestinationPolicy(pMap);
|
||||
|
||||
return broker;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String createClientId() {
|
||||
return CLIENT_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Destination createDlqDestination() {
|
||||
String prefix = topic ? "ActiveMQ.DLQ.Topic." : "ActiveMQ.DLQ.Queue.";
|
||||
String destinationName = prefix + getClass().getName() + "." + getName();
|
||||
if (durableSubscriber) {
|
||||
String subName = // connectionId:SubName
|
||||
CLIENT_ID + ":" + getDestination().toString();
|
||||
destinationName += "." + subName;
|
||||
}
|
||||
return new ActiveMQQueue(destinationName);
|
||||
}
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
/**
|
||||
* 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.policy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.ConnectionContext;
|
||||
import org.apache.activemq.broker.region.Subscription;
|
||||
import org.apache.activemq.broker.region.TopicSubscription;
|
||||
import org.apache.activemq.broker.region.policy.PriorityNetworkDispatchPolicy;
|
||||
import org.apache.activemq.command.ActiveMQDestination;
|
||||
import org.apache.activemq.command.ActiveMQMessage;
|
||||
import org.apache.activemq.command.ConsumerId;
|
||||
import org.apache.activemq.command.ConsumerInfo;
|
||||
import org.apache.activemq.command.MessageId;
|
||||
import org.apache.activemq.usage.SystemUsage;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class PriorityNetworkDispatchPolicyTest {
|
||||
|
||||
PriorityNetworkDispatchPolicy underTest = new PriorityNetworkDispatchPolicy();
|
||||
SystemUsage usageManager = new SystemUsage();
|
||||
ConsumerInfo info = new ConsumerInfo();
|
||||
ActiveMQMessage node = new ActiveMQMessage();
|
||||
ConsumerId id = new ConsumerId();
|
||||
ConnectionContext context = new ConnectionContext();
|
||||
BrokerService brokerService = new BrokerService();
|
||||
|
||||
@Before
|
||||
public void init() throws Exception {
|
||||
info.setDestination(ActiveMQDestination.createDestination("test", ActiveMQDestination.TOPIC_TYPE));
|
||||
info.setConsumerId(id);
|
||||
info.setNetworkSubscription(true);
|
||||
info.setNetworkConsumerPath(new ConsumerId[]{id});
|
||||
node.setMessageId(new MessageId("test:1:1:1:1"));
|
||||
}
|
||||
|
||||
@After
|
||||
public void stopBroker() throws Exception {
|
||||
brokerService.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveLowerPriorityDup() throws Exception {
|
||||
|
||||
List<Subscription> consumers = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
ConsumerInfo instance = info.copy();
|
||||
instance.setPriority((byte) i);
|
||||
consumers.add(new TopicSubscription(brokerService.getBroker(), context, instance, usageManager));
|
||||
}
|
||||
underTest.dispatch(node, null, consumers);
|
||||
|
||||
long count = 0;
|
||||
for (Subscription consumer : consumers) {
|
||||
count += consumer.getEnqueueCounter();
|
||||
}
|
||||
assertEquals("only one sub got message", 1, count);
|
||||
}
|
||||
}
|
|
@ -1,135 +0,0 @@
|
|||
/**
|
||||
* 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.policy;
|
||||
|
||||
import javax.jms.Connection;
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.MessageConsumer;
|
||||
import javax.jms.Session;
|
||||
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.QueueSubscriptionTest;
|
||||
import org.apache.activemq.broker.region.policy.PolicyEntry;
|
||||
import org.apache.activemq.broker.region.policy.PolicyMap;
|
||||
import org.apache.activemq.broker.region.policy.RoundRobinDispatchPolicy;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.BlockJUnit4ClassRunner;
|
||||
|
||||
@RunWith(BlockJUnit4ClassRunner.class)
|
||||
public class RoundRobinDispatchPolicyTest extends QueueSubscriptionTest {
|
||||
|
||||
@Override
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerService broker = super.createBroker();
|
||||
|
||||
PolicyEntry policy = new PolicyEntry();
|
||||
policy.setDispatchPolicy(new RoundRobinDispatchPolicy());
|
||||
|
||||
PolicyMap pMap = new PolicyMap();
|
||||
pMap.setDefaultEntry(policy);
|
||||
|
||||
broker.setDestinationPolicy(pMap);
|
||||
|
||||
return broker;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testOneProducerTwoConsumersSmallMessagesOnePrefetch() throws Exception {
|
||||
super.testOneProducerTwoConsumersSmallMessagesOnePrefetch();
|
||||
|
||||
// Ensure that each consumer should have received at least one message
|
||||
// We cannot guarantee that messages will be equally divided, since
|
||||
// prefetch is one
|
||||
assertEachConsumerReceivedAtLeastXMessages(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testOneProducerTwoConsumersSmallMessagesLargePrefetch() throws Exception {
|
||||
super.testOneProducerTwoConsumersSmallMessagesLargePrefetch();
|
||||
assertMessagesDividedAmongConsumers();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testOneProducerTwoConsumersLargeMessagesOnePrefetch() throws Exception {
|
||||
super.testOneProducerTwoConsumersLargeMessagesOnePrefetch();
|
||||
|
||||
// Ensure that each consumer should have received at least one message
|
||||
// We cannot guarantee that messages will be equally divided, since
|
||||
// prefetch is one
|
||||
assertEachConsumerReceivedAtLeastXMessages(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testOneProducerTwoConsumersLargeMessagesLargePrefetch() throws Exception {
|
||||
super.testOneProducerTwoConsumersLargeMessagesLargePrefetch();
|
||||
assertMessagesDividedAmongConsumers();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testOneProducerManyConsumersFewMessages() throws Exception {
|
||||
super.testOneProducerManyConsumersFewMessages();
|
||||
|
||||
// Since there are more consumers, each consumer should have received at
|
||||
// most one message only
|
||||
assertMessagesDividedAmongConsumers();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testOneProducerManyConsumersManyMessages() throws Exception {
|
||||
super.testOneProducerManyConsumersManyMessages();
|
||||
assertMessagesDividedAmongConsumers();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testManyProducersManyConsumers() throws Exception {
|
||||
super.testManyProducersManyConsumers();
|
||||
assertMessagesDividedAmongConsumers();
|
||||
}
|
||||
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testOneProducerTwoMatchingConsumersOneNotMatchingConsumer() throws Exception {
|
||||
// Create consumer that won't consume any message
|
||||
createMessageConsumer(createConnectionFactory().createConnection(), createDestination(), "JMSPriority<1");
|
||||
super.testOneProducerTwoConsumersSmallMessagesLargePrefetch();
|
||||
assertMessagesDividedAmongConsumers();
|
||||
}
|
||||
|
||||
protected MessageConsumer createMessageConsumer(Connection conn,
|
||||
Destination dest,
|
||||
String selector) throws Exception {
|
||||
connections.add(conn);
|
||||
|
||||
Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
final MessageConsumer consumer = sess.createConsumer(dest, selector);
|
||||
conn.start();
|
||||
|
||||
return consumer;
|
||||
}
|
||||
|
||||
public void assertMessagesDividedAmongConsumers() {
|
||||
assertEachConsumerReceivedAtLeastXMessages((messageCount * producerCount) / consumerCount);
|
||||
assertEachConsumerReceivedAtMostXMessages(((messageCount * producerCount) / consumerCount) + 1);
|
||||
}
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
/**
|
||||
* 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.policy;
|
||||
|
||||
import javax.jms.Connection;
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.Session;
|
||||
|
||||
import org.apache.activemq.broker.BrokerPlugin;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.apache.activemq.command.ActiveMQTopic;
|
||||
import org.apache.activemq.filter.DestinationMap;
|
||||
import org.apache.activemq.security.AuthorizationMap;
|
||||
import org.apache.activemq.security.AuthorizationPlugin;
|
||||
import org.apache.activemq.security.DefaultAuthorizationMap;
|
||||
import org.apache.activemq.security.SimpleAuthorizationMap;
|
||||
import org.apache.activemq.security.SimpleSecurityBrokerSystemTest;
|
||||
|
||||
import static org.apache.activemq.security.SimpleSecurityBrokerSystemTest.ADMINS;
|
||||
import static org.apache.activemq.security.SimpleSecurityBrokerSystemTest.USERS;
|
||||
import static org.apache.activemq.security.SimpleSecurityBrokerSystemTest.WILDCARD;
|
||||
|
||||
public class SecureDLQTest extends DeadLetterTestSupport {
|
||||
|
||||
Connection dlqConnection;
|
||||
Session dlqSession;
|
||||
|
||||
public static AuthorizationMap createAuthorizationMap() {
|
||||
DestinationMap readAccess = new DefaultAuthorizationMap();
|
||||
readAccess.put(new ActiveMQQueue("TEST"), ADMINS);
|
||||
readAccess.put(new ActiveMQQueue("TEST"), USERS);
|
||||
readAccess.put(new ActiveMQQueue("ActiveMQ.DLQ"), ADMINS);
|
||||
|
||||
DestinationMap writeAccess = new DefaultAuthorizationMap();
|
||||
writeAccess.put(new ActiveMQQueue("TEST"), ADMINS);
|
||||
writeAccess.put(new ActiveMQQueue("TEST"), USERS);
|
||||
writeAccess.put(new ActiveMQQueue("ActiveMQ.DLQ"), ADMINS);
|
||||
|
||||
readAccess.put(new ActiveMQTopic("ActiveMQ.Advisory.>"), WILDCARD);
|
||||
writeAccess.put(new ActiveMQTopic("ActiveMQ.Advisory.>"), WILDCARD);
|
||||
|
||||
DestinationMap adminAccess = new DefaultAuthorizationMap();
|
||||
adminAccess.put(new ActiveMQQueue("TEST"), ADMINS);
|
||||
adminAccess.put(new ActiveMQQueue("TEST"), USERS);
|
||||
adminAccess.put(new ActiveMQQueue("ActiveMQ.DLQ"), ADMINS);
|
||||
adminAccess.put(new ActiveMQTopic("ActiveMQ.Advisory.>"), WILDCARD);
|
||||
|
||||
return new SimpleAuthorizationMap(writeAccess, readAccess, adminAccess);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerService broker = super.createBroker();
|
||||
AuthorizationPlugin authorizationPlugin = new AuthorizationPlugin(createAuthorizationMap());
|
||||
|
||||
broker.setPlugins(new BrokerPlugin[]{authorizationPlugin, new SimpleSecurityBrokerSystemTest.SimpleAuthenticationFactory()});
|
||||
return broker;
|
||||
}
|
||||
|
||||
// lets disable the inapplicable tests
|
||||
@Override
|
||||
public void testTransientTopicMessage() throws Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testDurableTopicMessage() throws Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doTest() throws Exception {
|
||||
timeToLive = 1000;
|
||||
acknowledgeMode = Session.CLIENT_ACKNOWLEDGE;
|
||||
makeConsumer();
|
||||
sendMessages();
|
||||
Thread.sleep(1000);
|
||||
consumer.close();
|
||||
|
||||
Thread.sleep(1000);
|
||||
// this should try to send expired messages to dlq
|
||||
makeConsumer();
|
||||
|
||||
makeDlqConsumer();
|
||||
for (int i = 0; i < messageCount; i++) {
|
||||
Message msg = dlqConsumer.receive(1000);
|
||||
assertMessage(msg, i);
|
||||
assertNotNull("Should be a DLQ message for loop: " + i, msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
if (dlqConnection != null) {
|
||||
dlqConnection.close();
|
||||
}
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Connection createConnection() throws Exception {
|
||||
return getConnectionFactory().createConnection("user", "password");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void makeDlqConsumer() throws Exception {
|
||||
dlqDestination = createDlqDestination();
|
||||
dlqConnection = getConnectionFactory().createConnection("system", "manager");
|
||||
dlqConnection.start();
|
||||
dlqSession = dlqConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
|
||||
dlqConsumer = dlqSession.createConsumer(dlqDestination);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Destination createDlqDestination() {
|
||||
return new ActiveMQQueue("ActiveMQ.DLQ");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDestinationString() {
|
||||
return "TEST";
|
||||
}
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
/**
|
||||
* 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.policy;
|
||||
|
||||
import javax.jms.MessageConsumer;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.QueueSubscriptionTest;
|
||||
import org.apache.activemq.broker.region.policy.FixedCountSubscriptionRecoveryPolicy;
|
||||
import org.apache.activemq.broker.region.policy.PolicyEntry;
|
||||
import org.apache.activemq.broker.region.policy.PolicyMap;
|
||||
import org.apache.activemq.broker.region.policy.SimpleDispatchPolicy;
|
||||
import org.apache.activemq.util.MessageIdList;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.BlockJUnit4ClassRunner;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
@RunWith(BlockJUnit4ClassRunner.class)
|
||||
public class SimpleDispatchPolicyTest extends QueueSubscriptionTest {
|
||||
|
||||
@Override
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerService broker = super.createBroker();
|
||||
|
||||
PolicyEntry policy = new PolicyEntry();
|
||||
policy.setDispatchPolicy(new SimpleDispatchPolicy());
|
||||
policy.setSubscriptionRecoveryPolicy(new FixedCountSubscriptionRecoveryPolicy());
|
||||
PolicyMap pMap = new PolicyMap();
|
||||
pMap.setDefaultEntry(policy);
|
||||
|
||||
broker.setDestinationPolicy(pMap);
|
||||
|
||||
return broker;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testOneProducerTwoConsumersSmallMessagesLargePrefetch() throws Exception {
|
||||
super.testOneProducerTwoConsumersSmallMessagesLargePrefetch();
|
||||
|
||||
// One consumer should have received all messages, and the rest none
|
||||
// assertOneConsumerReceivedAllMessages(messageCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(timeout = 60 * 1000)
|
||||
public void testOneProducerTwoConsumersLargeMessagesLargePrefetch() throws Exception {
|
||||
super.testOneProducerTwoConsumersLargeMessagesLargePrefetch();
|
||||
|
||||
// One consumer should have received all messages, and the rest none
|
||||
// assertOneConsumerReceivedAllMessages(messageCount);
|
||||
}
|
||||
|
||||
public void assertOneConsumerReceivedAllMessages(int messageCount) throws Exception {
|
||||
boolean found = false;
|
||||
for (Iterator<MessageConsumer> i = consumers.keySet().iterator(); i.hasNext(); ) {
|
||||
MessageIdList messageIdList = consumers.get(i.next());
|
||||
int count = messageIdList.getMessageCount();
|
||||
if (count > 0) {
|
||||
if (found) {
|
||||
fail("No other consumers should have received any messages");
|
||||
} else {
|
||||
assertEquals("Consumer should have received all messages.", messageCount, count);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
fail("At least one consumer should have received all messages");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,131 +0,0 @@
|
|||
/**
|
||||
* 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.policy;
|
||||
|
||||
import javax.jms.MessageConsumer;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.TopicSubscriptionTest;
|
||||
import org.apache.activemq.broker.region.policy.PolicyEntry;
|
||||
import org.apache.activemq.broker.region.policy.PolicyMap;
|
||||
import org.apache.activemq.broker.region.policy.StrictOrderDispatchPolicy;
|
||||
import org.apache.activemq.util.MessageIdList;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.BlockJUnit4ClassRunner;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@RunWith(BlockJUnit4ClassRunner.class)
|
||||
public class StrictOrderDispatchPolicyTest extends TopicSubscriptionTest {
|
||||
|
||||
@Override
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerService broker = super.createBroker();
|
||||
|
||||
PolicyEntry policy = new PolicyEntry();
|
||||
policy.setDispatchPolicy(new StrictOrderDispatchPolicy());
|
||||
|
||||
PolicyMap pMap = new PolicyMap();
|
||||
pMap.setDefaultEntry(policy);
|
||||
|
||||
broker.setDestinationPolicy(pMap);
|
||||
|
||||
return broker;
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testOneProducerTwoConsumersLargeMessagesOnePrefetch() throws Exception {
|
||||
super.testOneProducerTwoConsumersLargeMessagesOnePrefetch();
|
||||
|
||||
assertReceivedMessagesAreOrdered();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testOneProducerTwoConsumersSmallMessagesOnePrefetch() throws Exception {
|
||||
super.testOneProducerTwoConsumersSmallMessagesOnePrefetch();
|
||||
|
||||
assertReceivedMessagesAreOrdered();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testOneProducerTwoConsumersSmallMessagesLargePrefetch() throws Exception {
|
||||
super.testOneProducerTwoConsumersSmallMessagesLargePrefetch();
|
||||
|
||||
assertReceivedMessagesAreOrdered();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testOneProducerTwoConsumersLargeMessagesLargePrefetch() throws Exception {
|
||||
super.testOneProducerTwoConsumersLargeMessagesLargePrefetch();
|
||||
|
||||
assertReceivedMessagesAreOrdered();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testOneProducerManyConsumersFewMessages() throws Exception {
|
||||
super.testOneProducerManyConsumersFewMessages();
|
||||
|
||||
assertReceivedMessagesAreOrdered();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testOneProducerManyConsumersManyMessages() throws Exception {
|
||||
super.testOneProducerManyConsumersManyMessages();
|
||||
|
||||
assertReceivedMessagesAreOrdered();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testManyProducersOneConsumer() throws Exception {
|
||||
super.testManyProducersOneConsumer();
|
||||
|
||||
assertReceivedMessagesAreOrdered();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testManyProducersManyConsumers() throws Exception {
|
||||
super.testManyProducersManyConsumers();
|
||||
|
||||
assertReceivedMessagesAreOrdered();
|
||||
}
|
||||
|
||||
public void assertReceivedMessagesAreOrdered() throws Exception {
|
||||
// If there is only one consumer, messages is definitely ordered
|
||||
if (consumers.size() <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get basis of order
|
||||
Iterator<MessageConsumer> i = consumers.keySet().iterator();
|
||||
MessageIdList messageOrder = consumers.get(i.next());
|
||||
|
||||
for (; i.hasNext(); ) {
|
||||
MessageIdList messageIdList = consumers.get(i.next());
|
||||
assertTrue("Messages are not ordered.", messageOrder.equals(messageIdList));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2005-2006 The Apache Software Foundation
|
||||
|
||||
Licensed 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.
|
||||
-->
|
||||
|
||||
<!-- this file can only be parsed using the xbean-spring library -->
|
||||
<!-- START SNIPPET: xbean -->
|
||||
<beans
|
||||
xmlns="http://www.springframework.org/schema/beans"
|
||||
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
|
||||
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
||||
|
||||
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
|
||||
|
||||
<broker persistent="false" xmlns="http://activemq.apache.org/schema/core">
|
||||
|
||||
<!-- lets define the dispatch policy -->
|
||||
<destinationPolicy>
|
||||
<policyMap>
|
||||
<policyEntries>
|
||||
<policyEntry topic="org.apache.>" producerFlowControl="false" memoryLimit="1mb">
|
||||
|
||||
<deadLetterStrategy>
|
||||
<individualDeadLetterStrategy topicPrefix="Test.DLQ." />
|
||||
</deadLetterStrategy>
|
||||
<dispatchPolicy>
|
||||
<strictOrderDispatchPolicy />
|
||||
</dispatchPolicy>
|
||||
<pendingSubscriberPolicy>
|
||||
<vmCursor />
|
||||
</pendingSubscriberPolicy>
|
||||
</policyEntry>
|
||||
|
||||
<policyEntry queue="org.apache.>">
|
||||
|
||||
<deadLetterStrategy>
|
||||
<individualDeadLetterStrategy queuePrefix="Test.DLQ."/>
|
||||
</deadLetterStrategy>
|
||||
<dispatchPolicy>
|
||||
<strictOrderDispatchPolicy />
|
||||
</dispatchPolicy>
|
||||
<pendingQueuePolicy>
|
||||
<vmQueueCursor />
|
||||
</pendingQueuePolicy>
|
||||
</policyEntry>
|
||||
|
||||
</policyEntries>
|
||||
</policyMap>
|
||||
</destinationPolicy>
|
||||
</broker>
|
||||
|
||||
</beans>
|
||||
<!-- END SNIPPET: xbean -->
|
|
@ -1,60 +0,0 @@
|
|||
<?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.
|
||||
-->
|
||||
|
||||
<!-- this file can only be parsed using the xbean-spring library -->
|
||||
<!-- START SNIPPET: xbean -->
|
||||
<beans
|
||||
xmlns="http://www.springframework.org/schema/beans"
|
||||
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
|
||||
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
||||
|
||||
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
|
||||
|
||||
<broker persistent="false" xmlns="http://activemq.apache.org/schema/core">
|
||||
|
||||
<!-- lets define the dispatch policy -->
|
||||
<destinationPolicy>
|
||||
<policyMap>
|
||||
<policyEntries>
|
||||
<policyEntry topic="org.apache.>">
|
||||
<deadLetterStrategy>
|
||||
<individualDeadLetterStrategy topicPrefix="Test.DLQ." processNonPersistent="true" />
|
||||
</deadLetterStrategy>
|
||||
<dispatchPolicy>
|
||||
<strictOrderDispatchPolicy />
|
||||
</dispatchPolicy>
|
||||
</policyEntry>
|
||||
|
||||
<policyEntry queue="org.apache.>">
|
||||
<deadLetterStrategy>
|
||||
<individualDeadLetterStrategy queuePrefix="Test.DLQ." processNonPersistent="true"/>
|
||||
</deadLetterStrategy>
|
||||
<dispatchPolicy>
|
||||
<strictOrderDispatchPolicy />
|
||||
</dispatchPolicy>
|
||||
</policyEntry>
|
||||
|
||||
</policyEntries>
|
||||
</policyMap>
|
||||
</destinationPolicy>
|
||||
</broker>
|
||||
|
||||
</beans>
|
||||
<!-- END SNIPPET: xbean -->
|
|
@ -1,112 +0,0 @@
|
|||
/**
|
||||
* 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.region;
|
||||
|
||||
import javax.jms.Connection;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageConsumer;
|
||||
import javax.jms.MessageListener;
|
||||
import javax.jms.Session;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.EmbeddedBrokerTestSupport;
|
||||
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.ActiveMQDestination;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.apache.activemq.util.Wait;
|
||||
import org.apache.activemq.util.Wait.Condition;
|
||||
|
||||
public class DestinationGCTest extends EmbeddedBrokerTestSupport {
|
||||
|
||||
ActiveMQQueue queue = new ActiveMQQueue("TEST");
|
||||
ActiveMQQueue otherQueue = new ActiveMQQueue("TEST-OTHER");
|
||||
|
||||
@Override
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
BrokerService broker = super.createBroker();
|
||||
broker.setDestinations(new ActiveMQDestination[]{queue});
|
||||
broker.setSchedulePeriodForDestinationPurge(1000);
|
||||
broker.setMaxPurgedDestinationsPerSweep(1);
|
||||
PolicyEntry entry = new PolicyEntry();
|
||||
entry.setGcInactiveDestinations(true);
|
||||
entry.setInactiveTimeoutBeforeGC(3000);
|
||||
PolicyMap map = new PolicyMap();
|
||||
map.setDefaultEntry(entry);
|
||||
broker.setDestinationPolicy(map);
|
||||
return broker;
|
||||
}
|
||||
|
||||
public void testDestinationGCWithActiveConsumers() throws Exception {
|
||||
assertEquals(1, broker.getAdminView().getQueues().length);
|
||||
|
||||
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://localhost?create=false");
|
||||
Connection connection = factory.createConnection();
|
||||
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
session.createProducer(otherQueue).close();
|
||||
MessageConsumer consumer = session.createConsumer(queue);
|
||||
consumer.setMessageListener(new MessageListener() {
|
||||
|
||||
@Override
|
||||
public void onMessage(Message message) {
|
||||
}
|
||||
});
|
||||
connection.start();
|
||||
|
||||
TimeUnit.SECONDS.sleep(5);
|
||||
|
||||
assertTrue("After GC runs there should be one Queue.", Wait.waitFor(new Condition() {
|
||||
@Override
|
||||
public boolean isSatisified() throws Exception {
|
||||
return broker.getAdminView().getQueues().length == 1;
|
||||
}
|
||||
}));
|
||||
|
||||
connection.close();
|
||||
}
|
||||
|
||||
public void testDestinationGc() throws Exception {
|
||||
assertEquals(1, broker.getAdminView().getQueues().length);
|
||||
assertTrue("After GC runs the Queue should be empty.", Wait.waitFor(new Condition() {
|
||||
@Override
|
||||
public boolean isSatisified() throws Exception {
|
||||
return broker.getAdminView().getQueues().length == 0;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public void testDestinationGcLimit() throws Exception {
|
||||
|
||||
broker.getAdminView().addQueue("TEST1");
|
||||
broker.getAdminView().addQueue("TEST2");
|
||||
broker.getAdminView().addQueue("TEST3");
|
||||
broker.getAdminView().addQueue("TEST4");
|
||||
|
||||
assertEquals(5, broker.getAdminView().getQueues().length);
|
||||
Thread.sleep(7000);
|
||||
int queues = broker.getAdminView().getQueues().length;
|
||||
assertTrue(queues > 0 && queues < 5);
|
||||
assertTrue("After GC runs the Queue should be empty.", Wait.waitFor(new Condition() {
|
||||
@Override
|
||||
public boolean isSatisified() throws Exception {
|
||||
return broker.getAdminView().getQueues().length == 0;
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
|
@ -1,116 +0,0 @@
|
|||
/**
|
||||
* 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.region;
|
||||
|
||||
import junit.framework.Test;
|
||||
|
||||
import org.apache.activemq.CombinationTestSupport;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.command.ActiveMQDestination;
|
||||
|
||||
// from https://issues.apache.org/activemq/browse/AMQ-2216
|
||||
public class DestinationRemoveRestartTest extends CombinationTestSupport {
|
||||
|
||||
private final static String destinationName = "TEST";
|
||||
public byte destinationType = ActiveMQDestination.QUEUE_TYPE;
|
||||
BrokerService broker;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
broker = createBroker();
|
||||
}
|
||||
|
||||
private BrokerService createBroker() throws Exception {
|
||||
BrokerService broker = new BrokerService();
|
||||
broker.setUseJmx(false);
|
||||
broker.setPersistent(true);
|
||||
broker.setDeleteAllMessagesOnStartup(true);
|
||||
broker.start();
|
||||
return broker;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
broker.stop();
|
||||
}
|
||||
|
||||
public void initCombosForTestCheckDestinationRemoveActionAfterRestart() {
|
||||
addCombinationValues("destinationType", new Object[]{Byte.valueOf(ActiveMQDestination.QUEUE_TYPE), Byte.valueOf(ActiveMQDestination.TOPIC_TYPE)});
|
||||
}
|
||||
|
||||
public void testCheckDestinationRemoveActionAfterRestart() throws Exception {
|
||||
doAddDestination();
|
||||
doRemoveDestination();
|
||||
broker.stop();
|
||||
broker.waitUntilStopped();
|
||||
broker = createBroker();
|
||||
doCheckRemoveActionAfterRestart();
|
||||
}
|
||||
|
||||
public void doAddDestination() throws Exception {
|
||||
boolean res = false;
|
||||
|
||||
ActiveMQDestination amqDestination = ActiveMQDestination.createDestination(destinationName, destinationType);
|
||||
broker.getRegionBroker().addDestination(broker.getAdminConnectionContext(), amqDestination, true);
|
||||
|
||||
final ActiveMQDestination[] list = broker.getRegionBroker().getDestinations();
|
||||
for (final ActiveMQDestination element : list) {
|
||||
final Destination destination = broker.getDestination(element);
|
||||
if (destination.getActiveMQDestination().getPhysicalName().equals(destinationName)) {
|
||||
res = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue("Adding destination Failed", res);
|
||||
}
|
||||
|
||||
public void doRemoveDestination() throws Exception {
|
||||
boolean res = true;
|
||||
|
||||
broker.removeDestination(ActiveMQDestination.createDestination(destinationName, destinationType));
|
||||
final ActiveMQDestination[] list = broker.getRegionBroker().getDestinations();
|
||||
for (final ActiveMQDestination element : list) {
|
||||
final Destination destination = broker.getDestination(element);
|
||||
if (destination.getActiveMQDestination().getPhysicalName().equals(destinationName)) {
|
||||
res = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue("Removing destination Failed", res);
|
||||
}
|
||||
|
||||
public void doCheckRemoveActionAfterRestart() throws Exception {
|
||||
boolean res = true;
|
||||
|
||||
final ActiveMQDestination[] list = broker.getRegionBroker().getDestinations();
|
||||
for (final ActiveMQDestination element : list) {
|
||||
final Destination destination = broker.getDestination(element);
|
||||
if (destination.getActiveMQDestination().getPhysicalName().equals(destinationName)) {
|
||||
res = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue("The removed destination is reloaded after restart !", res);
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return suite(DestinationRemoveRestartTest.class);
|
||||
}
|
||||
}
|
|
@ -1,404 +0,0 @@
|
|||
/**
|
||||
* 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.region;
|
||||
|
||||
import javax.jms.InvalidSelectorException;
|
||||
import javax.management.ObjectName;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.ConnectionContext;
|
||||
import org.apache.activemq.broker.ProducerBrokerExchange;
|
||||
import org.apache.activemq.command.ActiveMQDestination;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.apache.activemq.command.ActiveMQTextMessage;
|
||||
import org.apache.activemq.command.ConsumerInfo;
|
||||
import org.apache.activemq.command.Message;
|
||||
import org.apache.activemq.command.MessageAck;
|
||||
import org.apache.activemq.command.MessageDispatchNotification;
|
||||
import org.apache.activemq.command.MessageId;
|
||||
import org.apache.activemq.command.MessagePull;
|
||||
import org.apache.activemq.command.ProducerInfo;
|
||||
import org.apache.activemq.command.Response;
|
||||
import org.apache.activemq.filter.MessageEvaluationContext;
|
||||
import org.apache.activemq.state.ProducerState;
|
||||
import org.apache.activemq.store.MessageStore;
|
||||
import org.apache.activemq.store.PersistenceAdapter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author gtully
|
||||
* @see https://issues.apache.org/activemq/browse/AMQ-2020
|
||||
**/
|
||||
public class QueueDuplicatesFromStoreTest extends TestCase {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(QueueDuplicatesFromStoreTest.class);
|
||||
|
||||
ActiveMQQueue destination = new ActiveMQQueue("queue-" + QueueDuplicatesFromStoreTest.class.getSimpleName());
|
||||
BrokerService brokerService;
|
||||
|
||||
final static String mesageIdRoot = "11111:22222:";
|
||||
final int messageBytesSize = 256;
|
||||
final String text = new String(new byte[messageBytesSize]);
|
||||
|
||||
final int ackStartIndex = 100;
|
||||
final int ackWindow = 50;
|
||||
final int ackBatchSize = 50;
|
||||
final int fullWindow = 200;
|
||||
protected int count = 5000;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
brokerService = createBroker();
|
||||
brokerService.setUseJmx(false);
|
||||
brokerService.deleteAllMessages();
|
||||
brokerService.start();
|
||||
}
|
||||
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
return new BrokerService();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
brokerService.stop();
|
||||
}
|
||||
|
||||
public void testNoDuplicateAfterCacheFullAndAckedWithLargeAuditDepth() throws Exception {
|
||||
doTestNoDuplicateAfterCacheFullAndAcked(1024 * 10);
|
||||
}
|
||||
|
||||
public void testNoDuplicateAfterCacheFullAndAckedWithSmallAuditDepth() throws Exception {
|
||||
doTestNoDuplicateAfterCacheFullAndAcked(512);
|
||||
}
|
||||
|
||||
public void doTestNoDuplicateAfterCacheFullAndAcked(final int auditDepth) throws Exception {
|
||||
final PersistenceAdapter persistenceAdapter = brokerService.getPersistenceAdapter();
|
||||
final MessageStore queueMessageStore = persistenceAdapter.createQueueMessageStore(destination);
|
||||
final ConnectionContext contextNotInTx = new ConnectionContext();
|
||||
final ConsumerInfo consumerInfo = new ConsumerInfo();
|
||||
final DestinationStatistics destinationStatistics = new DestinationStatistics();
|
||||
consumerInfo.setExclusive(true);
|
||||
final Queue queue = new Queue(brokerService, destination, queueMessageStore, destinationStatistics, brokerService.getTaskRunnerFactory());
|
||||
|
||||
// a workaround for this issue
|
||||
// queue.setUseCache(false);
|
||||
queue.systemUsage.getMemoryUsage().setLimit(1024 * 1024 * 10);
|
||||
queue.setMaxAuditDepth(auditDepth);
|
||||
queue.initialize();
|
||||
queue.start();
|
||||
|
||||
ProducerBrokerExchange producerExchange = new ProducerBrokerExchange();
|
||||
ProducerInfo producerInfo = new ProducerInfo();
|
||||
ProducerState producerState = new ProducerState(producerInfo);
|
||||
producerExchange.setProducerState(producerState);
|
||||
producerExchange.setConnectionContext(contextNotInTx);
|
||||
|
||||
final CountDownLatch receivedLatch = new CountDownLatch(count);
|
||||
final AtomicLong ackedCount = new AtomicLong(0);
|
||||
final AtomicLong enqueueCounter = new AtomicLong(0);
|
||||
final Vector<String> errors = new Vector<>();
|
||||
|
||||
// populate the queue store, exceed memory limit so that cache is disabled
|
||||
for (int i = 0; i < count; i++) {
|
||||
Message message = getMessage(i);
|
||||
queue.send(producerExchange, message);
|
||||
}
|
||||
|
||||
assertEquals("store count is correct", count, queueMessageStore.getMessageCount());
|
||||
|
||||
// pull from store in small windows
|
||||
Subscription subscription = new Subscription() {
|
||||
|
||||
private SubscriptionStatistics subscriptionStatistics = new SubscriptionStatistics();
|
||||
|
||||
@Override
|
||||
public long getPendingMessageSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(MessageReference node) throws Exception {
|
||||
if (enqueueCounter.get() != node.getMessageId().getProducerSequenceId()) {
|
||||
errors.add("Not in sequence at: " + enqueueCounter.get() + ", received: " + node.getMessageId().getProducerSequenceId());
|
||||
}
|
||||
assertEquals("is in order", enqueueCounter.get(), node.getMessageId().getProducerSequenceId());
|
||||
receivedLatch.countDown();
|
||||
enqueueCounter.incrementAndGet();
|
||||
node.decrementReferenceCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(ConnectionContext context, Destination destination) throws Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countBeforeFull() {
|
||||
if (isFull()) {
|
||||
return 0;
|
||||
} else {
|
||||
return fullWindow - (int) (enqueueCounter.get() - ackedCount.get());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gc() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConsumerInfo getConsumerInfo() {
|
||||
return consumerInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionContext getContext() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDequeueCounter() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDispatchedCounter() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDispatchedQueueSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEnqueueCounter() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInFlightSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInFlightUsage() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectName getObjectName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPendingQueueSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPrefetchSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelector() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBrowser() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFull() {
|
||||
return (enqueueCounter.get() - ackedCount.get()) >= fullWindow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHighWaterMark() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLowWaterMark() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRecoveryRequired() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(MessageReference node, MessageEvaluationContext context) throws IOException {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(ActiveMQDestination destination) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processMessageDispatchNotification(MessageDispatchNotification mdn) throws Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response pullMessage(ConnectionContext context, MessagePull pull) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWildcard() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MessageReference> remove(ConnectionContext context, Destination destination) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setObjectName(ObjectName objectName) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelector(String selector) throws InvalidSelectorException, UnsupportedOperationException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateConsumerPrefetch(int newPrefetch) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addRecoveredMessage(ConnectionContext context, MessageReference message) throws Exception {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActiveMQDestination getActiveMQDestination() {
|
||||
return destination;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acknowledge(ConnectionContext context, MessageAck ack) throws Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCursorMemoryHighWaterMark() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCursorMemoryHighWaterMark(int cursorMemoryHighWaterMark) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSlowConsumer() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unmatched(MessageReference node) throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTimeOfLastMessageAck() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getConsumedCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incrementConsumedCount() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetConsumedCount() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubscriptionStatistics getSubscriptionStatistics() {
|
||||
return subscriptionStatistics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getInFlightMessageSize() {
|
||||
return subscriptionStatistics.getInflightMessageSize().getTotalSize();
|
||||
}
|
||||
};
|
||||
|
||||
queue.addSubscription(contextNotInTx, subscription);
|
||||
int removeIndex = 0;
|
||||
do {
|
||||
// Simulate periodic acks in small but recent windows
|
||||
long receivedCount = enqueueCounter.get();
|
||||
if (receivedCount > ackStartIndex) {
|
||||
if (receivedCount >= removeIndex + ackWindow) {
|
||||
for (int j = 0; j < ackBatchSize; j++, removeIndex++) {
|
||||
ackedCount.incrementAndGet();
|
||||
MessageAck ack = new MessageAck();
|
||||
ack.setLastMessageId(new MessageId(mesageIdRoot + removeIndex));
|
||||
ack.setMessageCount(1);
|
||||
queue.removeMessage(contextNotInTx, subscription, new IndirectMessageReference(getMessage(removeIndex)), ack);
|
||||
queue.wakeup();
|
||||
|
||||
}
|
||||
if (removeIndex % 1000 == 0) {
|
||||
LOG.info("acked: " + removeIndex);
|
||||
persistenceAdapter.checkpoint(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} while (!receivedLatch.await(0, TimeUnit.MILLISECONDS) && errors.isEmpty());
|
||||
|
||||
assertTrue("There are no errors: " + errors, errors.isEmpty());
|
||||
assertEquals(count, enqueueCounter.get());
|
||||
assertEquals("store count is correct", count - removeIndex, queueMessageStore.getMessageCount());
|
||||
}
|
||||
|
||||
private Message getMessage(int i) throws Exception {
|
||||
ActiveMQTextMessage message = new ActiveMQTextMessage();
|
||||
message.setMessageId(new MessageId(mesageIdRoot + i));
|
||||
message.setDestination(destination);
|
||||
message.setPersistent(true);
|
||||
message.setResponseRequired(true);
|
||||
message.setText("Msg:" + i + " " + text);
|
||||
assertEquals(message.getMessageId().getProducerSequenceId(), i);
|
||||
return message;
|
||||
}
|
||||
}
|
|
@ -1,253 +0,0 @@
|
|||
/**
|
||||
* 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.region;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.Connection;
|
||||
import org.apache.activemq.broker.ConnectionContext;
|
||||
import org.apache.activemq.broker.Connector;
|
||||
import org.apache.activemq.broker.ProducerBrokerExchange;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.apache.activemq.command.ActiveMQTextMessage;
|
||||
import org.apache.activemq.command.Command;
|
||||
import org.apache.activemq.command.ConnectionControl;
|
||||
import org.apache.activemq.command.Message;
|
||||
import org.apache.activemq.command.MessageId;
|
||||
import org.apache.activemq.command.ProducerInfo;
|
||||
import org.apache.activemq.command.Response;
|
||||
import org.apache.activemq.state.ProducerState;
|
||||
import org.apache.activemq.store.MessageStore;
|
||||
import org.apache.activemq.store.PersistenceAdapter;
|
||||
import org.apache.activemq.usage.MemoryUsage;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public class QueueOptimizedDispatchExceptionTest {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(QueueOptimizedDispatchExceptionTest.class);
|
||||
|
||||
private static final String brokerName = "testBroker";
|
||||
private static final String brokerUrl = "vm://" + brokerName;
|
||||
private static final int count = 50;
|
||||
|
||||
private final static String mesageIdRoot = "11111:22222:";
|
||||
private final ActiveMQQueue destination = new ActiveMQQueue("queue-" + QueueOptimizedDispatchExceptionTest.class.getSimpleName());
|
||||
private final int messageBytesSize = 256;
|
||||
private final String text = new String(new byte[messageBytesSize]);
|
||||
|
||||
private BrokerService broker;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
// Setup and start the broker
|
||||
broker = new BrokerService();
|
||||
broker.setBrokerName(brokerName);
|
||||
broker.setPersistent(false);
|
||||
broker.setSchedulerSupport(false);
|
||||
broker.setUseJmx(false);
|
||||
broker.setUseShutdownHook(false);
|
||||
broker.addConnector(brokerUrl);
|
||||
|
||||
// Start the broker
|
||||
broker.start();
|
||||
broker.waitUntilStarted();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
broker.stop();
|
||||
broker.waitUntilStopped();
|
||||
}
|
||||
|
||||
private class MockMemoryUsage extends MemoryUsage {
|
||||
|
||||
private boolean full = true;
|
||||
|
||||
public void setFull(boolean full) {
|
||||
this.full = full;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFull() {
|
||||
return full;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestOptimizedDispatchCME() throws Exception {
|
||||
final PersistenceAdapter persistenceAdapter = broker.getPersistenceAdapter();
|
||||
final MessageStore queueMessageStore = persistenceAdapter.createQueueMessageStore(destination);
|
||||
final ConnectionContext contextNotInTx = new ConnectionContext();
|
||||
contextNotInTx.setConnection(new Connection() {
|
||||
|
||||
@Override
|
||||
public void stop() throws Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() throws Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateClient(ConnectionControl control) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serviceExceptionAsync(IOException e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serviceException(Throwable error) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response service(Command command) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSlow() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNetworkConnection() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isManageable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFaultTolerantConnection() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnected() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlocked() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionStatistics getStatistics() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRemoteAddress() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDispatchQueueSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connector getConnector() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConnectionId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchSync(Command message) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchAsync(Command command) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getActiveTransactionCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getOldestActiveTransactionDuration() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
final DestinationStatistics destinationStatistics = new DestinationStatistics();
|
||||
final Queue queue = new Queue(broker, destination, queueMessageStore, destinationStatistics, broker.getTaskRunnerFactory());
|
||||
|
||||
final MockMemoryUsage usage = new MockMemoryUsage();
|
||||
|
||||
queue.setOptimizedDispatch(true);
|
||||
queue.initialize();
|
||||
queue.start();
|
||||
queue.memoryUsage = usage;
|
||||
|
||||
ProducerBrokerExchange producerExchange = new ProducerBrokerExchange();
|
||||
ProducerInfo producerInfo = new ProducerInfo();
|
||||
ProducerState producerState = new ProducerState(producerInfo);
|
||||
producerExchange.setProducerState(producerState);
|
||||
producerExchange.setConnectionContext(contextNotInTx);
|
||||
|
||||
// populate the queue store, exceed memory limit so that cache is disabled
|
||||
for (int i = 0; i < count; i++) {
|
||||
Message message = getMessage(i);
|
||||
queue.send(producerExchange, message);
|
||||
}
|
||||
|
||||
usage.setFull(false);
|
||||
|
||||
try {
|
||||
queue.wakeup();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Queue threw an unexpected exception: " + e.toString());
|
||||
fail("Should not throw an exception.");
|
||||
}
|
||||
}
|
||||
|
||||
private Message getMessage(int i) throws Exception {
|
||||
ActiveMQTextMessage message = new ActiveMQTextMessage();
|
||||
message.setMessageId(new MessageId(mesageIdRoot + i));
|
||||
message.setDestination(destination);
|
||||
message.setPersistent(false);
|
||||
message.setResponseRequired(true);
|
||||
message.setText("Msg:" + i + " " + text);
|
||||
assertEquals(message.getMessageId().getProducerSequenceId(), i);
|
||||
return message;
|
||||
}
|
||||
}
|
|
@ -1,209 +0,0 @@
|
|||
/**
|
||||
* 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.region;
|
||||
|
||||
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.Queue;
|
||||
import javax.jms.Session;
|
||||
import javax.jms.TextMessage;
|
||||
import javax.management.MalformedObjectNameException;
|
||||
import javax.management.ObjectName;
|
||||
import java.io.File;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.CombinationTestSupport;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.jmx.QueueViewMBean;
|
||||
import org.apache.activemq.broker.region.policy.FilePendingQueueMessageStoragePolicy;
|
||||
import org.apache.activemq.broker.region.policy.PendingQueueMessageStoragePolicy;
|
||||
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.apache.activemq.util.DefaultTestAppender;
|
||||
import org.apache.log4j.Appender;
|
||||
import org.apache.log4j.Level;
|
||||
import org.apache.log4j.spi.LoggingEvent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class QueuePurgeTest extends CombinationTestSupport {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(QueuePurgeTest.class);
|
||||
private static final int NUM_TO_SEND = 20000;
|
||||
private final String MESSAGE_TEXT = new String(new byte[1024]);
|
||||
BrokerService broker;
|
||||
ConnectionFactory factory;
|
||||
Connection connection;
|
||||
Session session;
|
||||
Queue queue;
|
||||
MessageConsumer consumer;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
setMaxTestTime(10 * 60 * 1000); // 10 mins
|
||||
setAutoFail(true);
|
||||
super.setUp();
|
||||
broker = new BrokerService();
|
||||
|
||||
File testDataDir = new File("target/activemq-data/QueuePurgeTest");
|
||||
broker.setDataDirectoryFile(testDataDir);
|
||||
broker.setUseJmx(true);
|
||||
broker.setDeleteAllMessagesOnStartup(true);
|
||||
broker.getSystemUsage().getMemoryUsage().setLimit(1024L * 1024 * 64);
|
||||
KahaDBPersistenceAdapter persistenceAdapter = new KahaDBPersistenceAdapter();
|
||||
persistenceAdapter.setDirectory(new File(testDataDir, "kahadb"));
|
||||
broker.setPersistenceAdapter(persistenceAdapter);
|
||||
broker.addConnector("tcp://localhost:0");
|
||||
broker.start();
|
||||
factory = new ActiveMQConnectionFactory(broker.getTransportConnectors().get(0).getConnectUri().toString());
|
||||
connection = factory.createConnection();
|
||||
connection.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
if (consumer != null) {
|
||||
consumer.close();
|
||||
}
|
||||
session.close();
|
||||
connection.stop();
|
||||
connection.close();
|
||||
broker.stop();
|
||||
}
|
||||
|
||||
public void testPurgeLargeQueue() throws Exception {
|
||||
applyBrokerSpoolingPolicy();
|
||||
createProducerAndSendMessages(NUM_TO_SEND);
|
||||
QueueViewMBean proxy = getProxyToQueueViewMBean();
|
||||
LOG.info("purging..");
|
||||
|
||||
org.apache.log4j.Logger log4jLogger = org.apache.log4j.Logger.getLogger(org.apache.activemq.broker.region.Queue.class);
|
||||
final AtomicBoolean gotPurgeLogMessage = new AtomicBoolean(false);
|
||||
|
||||
Appender appender = new DefaultTestAppender() {
|
||||
@Override
|
||||
public void doAppend(LoggingEvent event) {
|
||||
if (event.getMessage() instanceof String) {
|
||||
String message = (String) event.getMessage();
|
||||
if (message.contains("purged of " + NUM_TO_SEND + " messages")) {
|
||||
LOG.info("Received a log message: {} ", event.getMessage());
|
||||
gotPurgeLogMessage.set(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Level level = log4jLogger.getLevel();
|
||||
log4jLogger.setLevel(Level.INFO);
|
||||
log4jLogger.addAppender(appender);
|
||||
try {
|
||||
|
||||
proxy.purge();
|
||||
|
||||
} finally {
|
||||
log4jLogger.setLevel(level);
|
||||
log4jLogger.removeAppender(appender);
|
||||
}
|
||||
|
||||
assertEquals("Queue size is not zero, it's " + proxy.getQueueSize(), 0, proxy.getQueueSize());
|
||||
assertTrue("cache is disabled, temp store being used", !proxy.isCacheEnabled());
|
||||
assertTrue("got expected info purge log message", gotPurgeLogMessage.get());
|
||||
}
|
||||
|
||||
public void testRepeatedExpiryProcessingOfLargeQueue() throws Exception {
|
||||
applyBrokerSpoolingPolicy();
|
||||
final int expiryPeriod = 500;
|
||||
applyExpiryDuration(expiryPeriod);
|
||||
createProducerAndSendMessages(NUM_TO_SEND);
|
||||
QueueViewMBean proxy = getProxyToQueueViewMBean();
|
||||
LOG.info("waiting for expiry to kick in a bunch of times to verify it does not blow mem");
|
||||
Thread.sleep(5000);
|
||||
assertEquals("Queue size is has not changed " + proxy.getQueueSize(), NUM_TO_SEND, proxy.getQueueSize());
|
||||
}
|
||||
|
||||
private void applyExpiryDuration(int i) {
|
||||
broker.getDestinationPolicy().getDefaultEntry().setExpireMessagesPeriod(i);
|
||||
}
|
||||
|
||||
private void applyBrokerSpoolingPolicy() {
|
||||
PolicyMap policyMap = new PolicyMap();
|
||||
PolicyEntry defaultEntry = new PolicyEntry();
|
||||
defaultEntry.setProducerFlowControl(false);
|
||||
PendingQueueMessageStoragePolicy pendingQueuePolicy = new FilePendingQueueMessageStoragePolicy();
|
||||
defaultEntry.setPendingQueuePolicy(pendingQueuePolicy);
|
||||
policyMap.setDefaultEntry(defaultEntry);
|
||||
broker.setDestinationPolicy(policyMap);
|
||||
}
|
||||
|
||||
public void testPurgeLargeQueueWithConsumer() throws Exception {
|
||||
applyBrokerSpoolingPolicy();
|
||||
createProducerAndSendMessages(NUM_TO_SEND);
|
||||
QueueViewMBean proxy = getProxyToQueueViewMBean();
|
||||
createConsumer();
|
||||
long start = System.currentTimeMillis();
|
||||
LOG.info("purging..");
|
||||
proxy.purge();
|
||||
LOG.info("purge done: " + (System.currentTimeMillis() - start) + "ms");
|
||||
assertEquals("Queue size is not zero, it's " + proxy.getQueueSize(), 0, proxy.getQueueSize());
|
||||
assertEquals("usage goes to duck", 0, proxy.getMemoryPercentUsage());
|
||||
Message msg;
|
||||
do {
|
||||
msg = consumer.receive(1000);
|
||||
if (msg != null) {
|
||||
msg.acknowledge();
|
||||
}
|
||||
} while (msg != null);
|
||||
assertEquals("Queue size not valid", 0, proxy.getQueueSize());
|
||||
}
|
||||
|
||||
private QueueViewMBean getProxyToQueueViewMBean() throws MalformedObjectNameException, JMSException {
|
||||
ObjectName queueViewMBeanName = new ObjectName("org.apache.activemq:type=Broker,brokerName=localhost,destinationType=Queue,destinationName=" + queue.getQueueName());
|
||||
QueueViewMBean proxy = (QueueViewMBean) broker.getManagementContext().newProxyInstance(queueViewMBeanName, QueueViewMBean.class, true);
|
||||
return proxy;
|
||||
}
|
||||
|
||||
private void createProducerAndSendMessages(int numToSend) throws Exception {
|
||||
session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
|
||||
queue = session.createQueue("test1");
|
||||
MessageProducer producer = session.createProducer(queue);
|
||||
for (int i = 0; i < numToSend; i++) {
|
||||
TextMessage message = session.createTextMessage(MESSAGE_TEXT + i);
|
||||
if (i != 0 && i % 10000 == 0) {
|
||||
LOG.info("sent: " + i);
|
||||
}
|
||||
producer.send(message);
|
||||
}
|
||||
producer.close();
|
||||
}
|
||||
|
||||
private void createConsumer() throws Exception {
|
||||
consumer = session.createConsumer(queue);
|
||||
// wait for buffer fill out
|
||||
Thread.sleep(5 * 1000);
|
||||
for (int i = 0; i < 500; ++i) {
|
||||
Message message = consumer.receive();
|
||||
message.acknowledge();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,249 +0,0 @@
|
|||
/**
|
||||
* 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.region;
|
||||
|
||||
import javax.jms.Connection;
|
||||
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 org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Confirm that the broker does not resend unacknowledged messages during a broker shutdown.
|
||||
*/
|
||||
public class QueueResendDuringShutdownTest {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(QueueResendDuringShutdownTest.class);
|
||||
public static final int NUM_CONNECTION_TO_TEST = 8;
|
||||
|
||||
private static boolean iterationFoundFailure = false;
|
||||
|
||||
private BrokerService broker;
|
||||
private ActiveMQConnectionFactory factory;
|
||||
private Connection[] connections;
|
||||
private Connection producerConnection;
|
||||
private Queue queue;
|
||||
|
||||
private final Object messageReceiveSync = new Object();
|
||||
private int receiveCount;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
this.receiveCount = 0;
|
||||
|
||||
this.broker = new BrokerService();
|
||||
this.broker.setPersistent(false);
|
||||
this.broker.start();
|
||||
this.broker.waitUntilStarted();
|
||||
|
||||
this.factory = new ActiveMQConnectionFactory(broker.getVmConnectorURI());
|
||||
this.queue = new ActiveMQQueue("TESTQUEUE");
|
||||
|
||||
connections = new Connection[NUM_CONNECTION_TO_TEST];
|
||||
int iter = 0;
|
||||
while (iter < NUM_CONNECTION_TO_TEST) {
|
||||
this.connections[iter] = factory.createConnection();
|
||||
iter++;
|
||||
}
|
||||
|
||||
this.producerConnection = factory.createConnection();
|
||||
this.producerConnection.start();
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() throws Exception {
|
||||
for (Connection oneConnection : connections) {
|
||||
if (oneConnection != null) {
|
||||
closeConnection(oneConnection);
|
||||
}
|
||||
}
|
||||
connections = null;
|
||||
|
||||
if (this.producerConnection != null) {
|
||||
closeConnection(this.producerConnection);
|
||||
this.producerConnection = null;
|
||||
}
|
||||
|
||||
this.broker.stop();
|
||||
this.broker.waitUntilStopped();
|
||||
}
|
||||
|
||||
@Test(timeout = 3000)
|
||||
public void testRedeliverAtBrokerShutdownAutoAckMsgListenerIter1() throws Throwable {
|
||||
runTestIteration();
|
||||
}
|
||||
|
||||
@Test(timeout = 3000)
|
||||
public void testRedeliverAtBrokerShutdownAutoAckMsgListenerIter2() throws Throwable {
|
||||
runTestIteration();
|
||||
}
|
||||
|
||||
@Test(timeout = 3000)
|
||||
public void testRedeliverAtBrokerShutdownAutoAckMsgListenerIter3() throws Throwable {
|
||||
runTestIteration();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run one iteration of the test, skipping it if a failure was found on a prior iteration since a single failure is
|
||||
* enough. Also keep track of the state of failure for the iteration.
|
||||
*/
|
||||
protected void runTestIteration() throws Throwable {
|
||||
if (iterationFoundFailure) {
|
||||
LOG.info("skipping test iteration; failure previously detected");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
testRedeliverAtBrokerShutdownAutoAckMsgListener();
|
||||
} catch (Throwable thrown) {
|
||||
iterationFoundFailure = true;
|
||||
throw thrown;
|
||||
}
|
||||
}
|
||||
|
||||
protected void testRedeliverAtBrokerShutdownAutoAckMsgListener() throws Exception {
|
||||
// Start consumers on all of the connections
|
||||
for (Connection oneConnection : connections) {
|
||||
MessageConsumer consumer = startupConsumer(oneConnection, false, Session.AUTO_ACKNOWLEDGE);
|
||||
configureMessageListener(consumer);
|
||||
oneConnection.start();
|
||||
}
|
||||
|
||||
// Send one message to the Queue and wait a short time for the dispatch to occur.
|
||||
this.sendMessage();
|
||||
waitForMessage(1000);
|
||||
|
||||
// Verify one consumer received it
|
||||
assertEquals(1, this.receiveCount);
|
||||
|
||||
// Shutdown the broker
|
||||
this.broker.stop();
|
||||
this.broker.waitUntilStopped();
|
||||
delay(100, "give queue time flush");
|
||||
|
||||
// Verify still only one consumer received it
|
||||
assertEquals(1, this.receiveCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a consumer on the given connection using the session transaction and acknowledge settings given.
|
||||
*/
|
||||
protected MessageConsumer startupConsumer(Connection conn, boolean transInd, int ackMode) throws JMSException {
|
||||
Session sess;
|
||||
MessageConsumer consumer;
|
||||
|
||||
sess = conn.createSession(transInd, ackMode);
|
||||
consumer = sess.createConsumer(queue);
|
||||
|
||||
return consumer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the receipt of a message from one of the consumers.
|
||||
*/
|
||||
protected void messageReceived() {
|
||||
synchronized (this) {
|
||||
this.receiveCount++;
|
||||
synchronized (this.messageReceiveSync) {
|
||||
this.messageReceiveSync.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the MessageListener for the given consumer. The listener uses a long delay on receiving the message to
|
||||
* simulate the reported case of problems at shutdown caused by a message listener's connection closing while it is
|
||||
* still processing.
|
||||
*/
|
||||
protected void configureMessageListener(MessageConsumer consumer) throws JMSException {
|
||||
final MessageConsumer fConsumer = consumer;
|
||||
|
||||
consumer.setMessageListener(new MessageListener() {
|
||||
@Override
|
||||
public void onMessage(Message msg) {
|
||||
LOG.debug("got a message on consumer {}", fConsumer);
|
||||
messageReceived();
|
||||
|
||||
// Delay long enough for the consumer to get closed while this delay is active.
|
||||
delay(3000, "pause so connection shutdown leads to unacked message redelivery");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a test message now.
|
||||
*/
|
||||
protected void sendMessage() throws JMSException {
|
||||
Session sess = this.producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
MessageProducer prod = sess.createProducer(queue);
|
||||
prod.send(sess.createTextMessage("X-TEST-MSG-X"));
|
||||
prod.close();
|
||||
sess.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the given connection safely and log any exception caught.
|
||||
*/
|
||||
protected void closeConnection(Connection conn) {
|
||||
try {
|
||||
conn.close();
|
||||
} catch (JMSException jmsExc) {
|
||||
LOG.info("failed to cleanup connection", jmsExc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pause for the given length of time, in milliseconds, logging an interruption if one occurs. Don't try to
|
||||
* recover from interrupt - the test case does not support interrupting and such an occurrence likely means the
|
||||
* test is being aborted.
|
||||
*/
|
||||
protected void delay(long delayMs, String desc) {
|
||||
try {
|
||||
Thread.sleep(delayMs);
|
||||
} catch (InterruptedException intExc) {
|
||||
LOG.warn("sleep interrupted: " + desc, intExc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait up to the specified duration for a message to be received by any consumer.
|
||||
*/
|
||||
protected void waitForMessage(long delayMs) {
|
||||
try {
|
||||
synchronized (this.messageReceiveSync) {
|
||||
while (this.receiveCount == 0) {
|
||||
this.messageReceiveSync.wait(delayMs);
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException intExc) {
|
||||
LOG.warn("sleep interrupted: wait for message to arrive");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,433 +0,0 @@
|
|||
/**
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* 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.region;
|
||||
|
||||
import javax.jms.InvalidSelectorException;
|
||||
import javax.management.ObjectName;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.ConnectionContext;
|
||||
import org.apache.activemq.broker.ProducerBrokerExchange;
|
||||
import org.apache.activemq.command.ActiveMQDestination;
|
||||
import org.apache.activemq.command.ActiveMQMessage;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.apache.activemq.command.ConsumerInfo;
|
||||
import org.apache.activemq.command.Message;
|
||||
import org.apache.activemq.command.MessageAck;
|
||||
import org.apache.activemq.command.MessageDispatchNotification;
|
||||
import org.apache.activemq.command.MessageId;
|
||||
import org.apache.activemq.command.MessagePull;
|
||||
import org.apache.activemq.command.ProducerInfo;
|
||||
import org.apache.activemq.command.Response;
|
||||
import org.apache.activemq.filter.MessageEvaluationContext;
|
||||
import org.apache.activemq.state.ProducerState;
|
||||
import org.apache.activemq.store.MessageStore;
|
||||
import org.apache.activemq.thread.TaskRunnerFactory;
|
||||
|
||||
public class SubscriptionAddRemoveQueueTest extends TestCase {
|
||||
|
||||
Queue queue;
|
||||
|
||||
ConsumerInfo info = new ConsumerInfo();
|
||||
List<SimpleImmediateDispatchSubscription> subs = new ArrayList<>();
|
||||
ConnectionContext context = new ConnectionContext();
|
||||
ProducerBrokerExchange producerBrokerExchange = new ProducerBrokerExchange();
|
||||
ProducerInfo producerInfo = new ProducerInfo();
|
||||
ProducerState producerState = new ProducerState(producerInfo);
|
||||
ActiveMQDestination destination = new ActiveMQQueue("TEST");
|
||||
int numSubscriptions = 1000;
|
||||
boolean working = true;
|
||||
int senders = 20;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
BrokerService brokerService = new BrokerService();
|
||||
brokerService.start();
|
||||
DestinationStatistics parentStats = new DestinationStatistics();
|
||||
parentStats.setEnabled(true);
|
||||
|
||||
TaskRunnerFactory taskFactory = new TaskRunnerFactory();
|
||||
MessageStore store = null;
|
||||
|
||||
info.setDestination(destination);
|
||||
info.setPrefetchSize(100);
|
||||
|
||||
producerBrokerExchange.setProducerState(producerState);
|
||||
producerBrokerExchange.setConnectionContext(context);
|
||||
|
||||
queue = new Queue(brokerService, destination, store, parentStats, taskFactory);
|
||||
queue.initialize();
|
||||
}
|
||||
|
||||
public void testNoDispatchToRemovedConsumers() throws Exception {
|
||||
final AtomicInteger producerId = new AtomicInteger();
|
||||
Runnable sender = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
AtomicInteger id = new AtomicInteger();
|
||||
int producerIdAndIncrement = producerId.getAndIncrement();
|
||||
while (working) {
|
||||
try {
|
||||
Message msg = new ActiveMQMessage();
|
||||
msg.setDestination(destination);
|
||||
msg.setMessageId(new MessageId(producerIdAndIncrement + ":0:" + id.getAndIncrement()));
|
||||
queue.send(producerBrokerExchange, msg);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail("unexpected exception in sendMessage, ex:" + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Runnable subRemover = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (Subscription sub : subs) {
|
||||
try {
|
||||
queue.removeSubscription(context, sub, 0);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail("unexpected exception in removeSubscription, ex:" + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (int i = 0; i < numSubscriptions; i++) {
|
||||
SimpleImmediateDispatchSubscription sub = new SimpleImmediateDispatchSubscription();
|
||||
subs.add(sub);
|
||||
queue.addSubscription(context, sub);
|
||||
}
|
||||
assertEquals("there are X subscriptions", numSubscriptions, queue.getDestinationStatistics().getConsumers().getCount());
|
||||
ExecutorService executor = Executors.newCachedThreadPool();
|
||||
for (int i = 0; i < senders; i++) {
|
||||
executor.submit(sender);
|
||||
}
|
||||
|
||||
Thread.sleep(1000);
|
||||
for (SimpleImmediateDispatchSubscription sub : subs) {
|
||||
assertTrue("There are some locked messages in the subscription", hasSomeLocks(sub.dispatched));
|
||||
}
|
||||
|
||||
Future<?> result = executor.submit(subRemover);
|
||||
result.get();
|
||||
working = false;
|
||||
assertEquals("there are no subscriptions", 0, queue.getDestinationStatistics().getConsumers().getCount());
|
||||
|
||||
for (SimpleImmediateDispatchSubscription sub : subs) {
|
||||
assertTrue("There are no locked messages in any removed subscriptions", !hasSomeLocks(sub.dispatched));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean hasSomeLocks(List<MessageReference> dispatched) {
|
||||
boolean hasLock = false;
|
||||
for (MessageReference mr : dispatched) {
|
||||
QueueMessageReference qmr = (QueueMessageReference) mr;
|
||||
if (qmr.getLockOwner() != null) {
|
||||
hasLock = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return hasLock;
|
||||
}
|
||||
|
||||
public class SimpleImmediateDispatchSubscription implements Subscription, LockOwner {
|
||||
|
||||
private SubscriptionStatistics subscriptionStatistics = new SubscriptionStatistics();
|
||||
List<MessageReference> dispatched = Collections.synchronizedList(new ArrayList<MessageReference>());
|
||||
|
||||
@Override
|
||||
public long getPendingMessageSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acknowledge(ConnectionContext context, MessageAck ack) throws Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(MessageReference node) throws Exception {
|
||||
// immediate dispatch
|
||||
QueueMessageReference qmr = (QueueMessageReference) node;
|
||||
qmr.lock(this);
|
||||
dispatched.add(qmr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionContext getContext() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCursorMemoryHighWaterMark() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCursorMemoryHighWaterMark(int cursorMemoryHighWaterMark) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSlowConsumer() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unmatched(MessageReference node) throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTimeOfLastMessageAck() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getConsumedCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incrementConsumedCount() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetConsumedCount() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(ConnectionContext context, Destination destination) throws Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gc() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConsumerInfo getConsumerInfo() {
|
||||
return info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDequeueCounter() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDispatchedCounter() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDispatchedQueueSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEnqueueCounter() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInFlightSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInFlightUsage() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectName getObjectName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPendingQueueSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPrefetchSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelector() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBrowser() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFull() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHighWaterMark() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLowWaterMark() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRecoveryRequired() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isSlave() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(MessageReference node, MessageEvaluationContext context) throws IOException {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(ActiveMQDestination destination) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processMessageDispatchNotification(MessageDispatchNotification mdn) throws Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response pullMessage(ConnectionContext context, MessagePull pull) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWildcard() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MessageReference> remove(ConnectionContext context, Destination destination) throws Exception {
|
||||
return new ArrayList<>(dispatched);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setObjectName(ObjectName objectName) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelector(String selector) throws InvalidSelectorException, UnsupportedOperationException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateConsumerPrefetch(int newPrefetch) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addRecoveredMessage(ConnectionContext context, MessageReference message) throws Exception {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActiveMQDestination getActiveMQDestination() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLockPriority() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLockExclusive() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void addDestination(Destination destination) {
|
||||
}
|
||||
|
||||
public void removeDestination(Destination destination) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countBeforeFull() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubscriptionStatistics getSubscriptionStatistics() {
|
||||
return subscriptionStatistics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getInFlightMessageSize() {
|
||||
return subscriptionStatistics.getInflightMessageSize().getTotalSize();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue