mirror of https://github.com/apache/activemq.git
https://issues.apache.org/jira/browse/AMQ-3124 - Failover transport client gets corrupted connectedBrokers data - apply variant of suggested patch with thanks. Stripping server side url options is the right way to go, reusing api used by discovery publisher to same effect, additional test
git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@1057565 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
55c3ef9fda
commit
0ed0ba584c
|
@ -29,7 +29,6 @@ import org.apache.activemq.broker.region.MessageReference;
|
||||||
import org.apache.activemq.broker.region.Subscription;
|
import org.apache.activemq.broker.region.Subscription;
|
||||||
import org.apache.activemq.broker.region.TopicSubscription;
|
import org.apache.activemq.broker.region.TopicSubscription;
|
||||||
import org.apache.activemq.command.*;
|
import org.apache.activemq.command.*;
|
||||||
import org.apache.activemq.network.NetworkBridge;
|
|
||||||
import org.apache.activemq.security.SecurityContext;
|
import org.apache.activemq.security.SecurityContext;
|
||||||
import org.apache.activemq.state.ProducerState;
|
import org.apache.activemq.state.ProducerState;
|
||||||
import org.apache.activemq.usage.Usage;
|
import org.apache.activemq.usage.Usage;
|
||||||
|
@ -484,8 +483,8 @@ public class AdvisoryBroker extends BrokerFilter {
|
||||||
advisoryMessage.setStringProperty(AdvisorySupport.MSG_PROPERTY_ORIGIN_BROKER_ID, id);
|
advisoryMessage.setStringProperty(AdvisorySupport.MSG_PROPERTY_ORIGIN_BROKER_ID, id);
|
||||||
|
|
||||||
String url = getBrokerService().getVmConnectorURI().toString();
|
String url = getBrokerService().getVmConnectorURI().toString();
|
||||||
if (getBrokerService().getDefaultSocketURI() != null) {
|
if (getBrokerService().getDefaultSocketURIString() != null) {
|
||||||
url = getBrokerService().getDefaultSocketURI().toString();
|
url = getBrokerService().getDefaultSocketURIString();
|
||||||
}
|
}
|
||||||
advisoryMessage.setStringProperty(AdvisorySupport.MSG_PROPERTY_ORIGIN_BROKER_URL, url);
|
advisoryMessage.setStringProperty(AdvisorySupport.MSG_PROPERTY_ORIGIN_BROKER_URL, url);
|
||||||
|
|
||||||
|
|
|
@ -152,7 +152,7 @@ public class BrokerService implements Service {
|
||||||
private boolean deleteAllMessagesOnStartup;
|
private boolean deleteAllMessagesOnStartup;
|
||||||
private boolean advisorySupport = true;
|
private boolean advisorySupport = true;
|
||||||
private URI vmConnectorURI;
|
private URI vmConnectorURI;
|
||||||
private URI defaultSocketURI;
|
private String defaultSocketURIString;
|
||||||
private PolicyMap destinationPolicy;
|
private PolicyMap destinationPolicy;
|
||||||
private final AtomicBoolean started = new AtomicBoolean(false);
|
private final AtomicBoolean started = new AtomicBoolean(false);
|
||||||
private final AtomicBoolean stopped = new AtomicBoolean(false);
|
private final AtomicBoolean stopped = new AtomicBoolean(false);
|
||||||
|
@ -1315,24 +1315,24 @@ public class BrokerService implements Service {
|
||||||
this.vmConnectorURI = vmConnectorURI;
|
this.vmConnectorURI = vmConnectorURI;
|
||||||
}
|
}
|
||||||
|
|
||||||
public URI getDefaultSocketURI() {
|
public String getDefaultSocketURIString() {
|
||||||
|
|
||||||
if (started.get()) {
|
if (started.get()) {
|
||||||
if (this.defaultSocketURI==null) {
|
if (this.defaultSocketURIString ==null) {
|
||||||
for (TransportConnector tc:this.transportConnectors) {
|
for (TransportConnector tc:this.transportConnectors) {
|
||||||
URI result = null;
|
String result = null;
|
||||||
try {
|
try {
|
||||||
result = tc.getConnectUri();
|
result = tc.getPublishableConnectString();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.warn("Failed to get the ConnectURI for "+tc,e);
|
LOG.warn("Failed to get the ConnectURI for "+tc,e);
|
||||||
}
|
}
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
this.defaultSocketURI=result;
|
this.defaultSocketURIString =result;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.defaultSocketURI;
|
return this.defaultSocketURIString;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -2076,8 +2076,8 @@ public class BrokerService implements Service {
|
||||||
connector.setLocalUri(uri);
|
connector.setLocalUri(uri);
|
||||||
connector.setBrokerName(getBrokerName());
|
connector.setBrokerName(getBrokerName());
|
||||||
connector.setDurableDestinations(durableDestinations);
|
connector.setDurableDestinations(durableDestinations);
|
||||||
if (getDefaultSocketURI() != null) {
|
if (getDefaultSocketURIString() != null) {
|
||||||
connector.setBrokerURL(getDefaultSocketURI().toString());
|
connector.setBrokerURL(getDefaultSocketURIString());
|
||||||
}
|
}
|
||||||
connector.start();
|
connector.start();
|
||||||
}
|
}
|
||||||
|
|
|
@ -584,7 +584,7 @@ public class TransportConnection implements Connection, Task, CommandVisitor {
|
||||||
ConnectionId connectionId = info.getSessionId().getParentId();
|
ConnectionId connectionId = info.getSessionId().getParentId();
|
||||||
TransportConnectionState cs = lookupConnectionState(connectionId);
|
TransportConnectionState cs = lookupConnectionState(connectionId);
|
||||||
// Avoid replaying dup commands
|
// Avoid replaying dup commands
|
||||||
if (!cs.getSessionIds().contains(info.getSessionId())) {
|
if (cs != null && !cs.getSessionIds().contains(info.getSessionId())) {
|
||||||
broker.addSession(cs.getContext(), info);
|
broker.addSession(cs.getContext(), info);
|
||||||
try {
|
try {
|
||||||
cs.addSession(info);
|
cs.addSession(info);
|
||||||
|
|
|
@ -254,7 +254,7 @@ public class TransportConnector implements Connector, BrokerServiceAware {
|
||||||
LOG.info("Connector " + getName() + " Started");
|
LOG.info("Connector " + getName() + " Started");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getPublishableConnectString() throws Exception {
|
public String getPublishableConnectString() throws Exception {
|
||||||
URI theConnectURI = getConnectUri();
|
URI theConnectURI = getConnectUri();
|
||||||
String publishableConnectString = theConnectURI.toString();
|
String publishableConnectString = theConnectURI.toString();
|
||||||
// strip off server side query parameters which may not be compatible to
|
// strip off server side query parameters which may not be compatible to
|
||||||
|
@ -386,23 +386,26 @@ public class TransportConnector implements Connector, BrokerServiceAware {
|
||||||
boolean rebalance = isRebalanceClusterClients();
|
boolean rebalance = isRebalanceClusterClients();
|
||||||
String connectedBrokers = "";
|
String connectedBrokers = "";
|
||||||
String self = "";
|
String self = "";
|
||||||
if (brokerService.getDefaultSocketURI() != null) {
|
|
||||||
self += brokerService.getDefaultSocketURI().toString();
|
if (isUpdateClusterClients()) {
|
||||||
self += ",";
|
if (brokerService.getDefaultSocketURIString() != null) {
|
||||||
}
|
self += brokerService.getDefaultSocketURIString();
|
||||||
if (rebalance == false) {
|
self += ",";
|
||||||
connectedBrokers += self;
|
}
|
||||||
}
|
if (rebalance == false) {
|
||||||
if (this.broker.getPeerBrokerInfos() != null) {
|
connectedBrokers += self;
|
||||||
for (BrokerInfo info : this.broker.getPeerBrokerInfos()) {
|
}
|
||||||
if (isMatchesClusterFilter(info.getBrokerName())) {
|
if (this.broker.getPeerBrokerInfos() != null) {
|
||||||
connectedBrokers += info.getBrokerURL();
|
for (BrokerInfo info : this.broker.getPeerBrokerInfos()) {
|
||||||
connectedBrokers += ",";
|
if (isMatchesClusterFilter(info.getBrokerName())) {
|
||||||
|
connectedBrokers += info.getBrokerURL();
|
||||||
|
connectedBrokers += ",";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (rebalance) {
|
||||||
if (rebalance) {
|
connectedBrokers += self;
|
||||||
connectedBrokers += self;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectionControl control = new ConnectionControl();
|
ConnectionControl control = new ConnectionControl();
|
||||||
|
|
|
@ -59,6 +59,21 @@ private final List<ActiveMQConnection>connections = new ArrayList<ActiveMQConnec
|
||||||
assertTrue(set.size() > 1);
|
assertTrue(set.size() > 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testClusterURIOptionsStrip() throws Exception{
|
||||||
|
createClients();
|
||||||
|
if (brokerB == null) {
|
||||||
|
// add in server side only url param, should not be propagated
|
||||||
|
brokerB = createBrokerB(BROKER_B_BIND_ADDRESS + "?transport.closeAsync=false");
|
||||||
|
}
|
||||||
|
Thread.sleep(3000);
|
||||||
|
Set<String> set = new HashSet<String>();
|
||||||
|
for (ActiveMQConnection c:connections) {
|
||||||
|
set.add(c.getTransportChannel().getRemoteAddress());
|
||||||
|
}
|
||||||
|
assertTrue(set.size() > 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void testClusterConnectedBeforeClients() throws Exception{
|
public void testClusterConnectedBeforeClients() throws Exception{
|
||||||
|
|
||||||
if (brokerB == null) {
|
if (brokerB == null) {
|
||||||
|
@ -80,7 +95,7 @@ private final List<ActiveMQConnection>connections = new ArrayList<ActiveMQConnec
|
||||||
@Override
|
@Override
|
||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
if (brokerA == null) {
|
if (brokerA == null) {
|
||||||
brokerA = createBrokerA(BROKER_A_BIND_ADDRESS);
|
brokerA = createBrokerA(BROKER_A_BIND_ADDRESS + "?transport.closeAsync=false");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -103,6 +118,7 @@ private final List<ActiveMQConnection>connections = new ArrayList<ActiveMQConnec
|
||||||
|
|
||||||
protected BrokerService createBrokerA(String uri) throws Exception {
|
protected BrokerService createBrokerA(String uri) throws Exception {
|
||||||
BrokerService answer = new BrokerService();
|
BrokerService answer = new BrokerService();
|
||||||
|
answer.setUseJmx(false);
|
||||||
configureConsumerBroker(answer,uri);
|
configureConsumerBroker(answer,uri);
|
||||||
answer.start();
|
answer.start();
|
||||||
return answer;
|
return answer;
|
||||||
|
@ -119,6 +135,7 @@ private final List<ActiveMQConnection>connections = new ArrayList<ActiveMQConnec
|
||||||
|
|
||||||
protected BrokerService createBrokerB(String uri) throws Exception {
|
protected BrokerService createBrokerB(String uri) throws Exception {
|
||||||
BrokerService answer = new BrokerService();
|
BrokerService answer = new BrokerService();
|
||||||
|
answer.setUseJmx(false);
|
||||||
configureNetwork(answer,uri);
|
configureNetwork(answer,uri);
|
||||||
answer.start();
|
answer.start();
|
||||||
return answer;
|
return answer;
|
||||||
|
|
|
@ -18,77 +18,129 @@ package org.apache.activemq.transport.failover;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.net.URI;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.jms.Connection;
|
import javax.jms.Connection;
|
||||||
import javax.jms.JMSException;
|
|
||||||
import javax.jms.Message;
|
import javax.jms.Message;
|
||||||
import javax.jms.MessageProducer;
|
|
||||||
import javax.jms.MessageConsumer;
|
import javax.jms.MessageConsumer;
|
||||||
|
import javax.jms.MessageProducer;
|
||||||
import javax.jms.Queue;
|
import javax.jms.Queue;
|
||||||
import javax.jms.Session;
|
import javax.jms.Session;
|
||||||
import javax.jms.TextMessage;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||||
import org.apache.activemq.broker.BrokerService;
|
import org.apache.activemq.broker.BrokerService;
|
||||||
|
import org.apache.activemq.broker.TransportConnector;
|
||||||
|
import org.apache.activemq.network.NetworkConnector;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
public class FailoverUpdateURIsTest extends TestCase {
|
public class FailoverUpdateURIsTest extends TestCase {
|
||||||
|
|
||||||
private static final String QUEUE_NAME = "test.failoverupdateuris";
|
private static final String QUEUE_NAME = "test.failoverupdateuris";
|
||||||
|
private static final Logger LOG = Logger.getLogger(FailoverUpdateURIsTest.class);
|
||||||
|
|
||||||
public void testUpdateURIs() throws Exception {
|
String firstTcpUri = "tcp://localhost:61616";
|
||||||
|
String secondTcpUri = "tcp://localhost:61626";
|
||||||
|
Connection connection = null;
|
||||||
|
BrokerService bs2 = null;
|
||||||
|
|
||||||
long timeout = 1000;
|
public void tearDown() throws Exception {
|
||||||
URI firstTcpUri = new URI("tcp://localhost:61616");
|
if (connection != null) {
|
||||||
URI secondTcpUri = new URI("tcp://localhost:61626");
|
connection.close();
|
||||||
String targetDir = "target/" + getName();
|
}
|
||||||
new File(targetDir).mkdir();
|
if (bs2 != null) {
|
||||||
File updateFile = new File(targetDir + "/updateURIsFile.txt");
|
bs2.stop();
|
||||||
System.out.println(updateFile);
|
}
|
||||||
System.out.println(updateFile.toURI());
|
}
|
||||||
System.out.println(updateFile.getAbsoluteFile());
|
|
||||||
System.out.println(updateFile.getAbsoluteFile().toURI());
|
|
||||||
FileOutputStream out = new FileOutputStream(updateFile);
|
|
||||||
out.write(firstTcpUri.toString().getBytes());
|
|
||||||
out.close();
|
|
||||||
|
|
||||||
BrokerService bs1 = new BrokerService();
|
public void testUpdateURIsViaFile() throws Exception {
|
||||||
bs1.setUseJmx(false);
|
|
||||||
bs1.addConnector(firstTcpUri);
|
|
||||||
bs1.start();
|
|
||||||
|
|
||||||
// no failover uri's to start with, must be read from file...
|
String targetDir = "target/" + getName();
|
||||||
ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("failover:()?updateURIsURL=file:///" + updateFile.getAbsoluteFile());
|
new File(targetDir).mkdir();
|
||||||
Connection connection = cf.createConnection();
|
File updateFile = new File(targetDir + "/updateURIsFile.txt");
|
||||||
connection.start();
|
LOG.info(updateFile);
|
||||||
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
LOG.info(updateFile.toURI());
|
||||||
Queue theQueue = session.createQueue(QUEUE_NAME);
|
LOG.info(updateFile.getAbsoluteFile());
|
||||||
MessageProducer producer = session.createProducer(theQueue);
|
LOG.info(updateFile.getAbsoluteFile().toURI());
|
||||||
MessageConsumer consumer = session.createConsumer(theQueue);
|
FileOutputStream out = new FileOutputStream(updateFile);
|
||||||
Message message = session.createTextMessage("Test message");
|
out.write(firstTcpUri.getBytes());
|
||||||
producer.send(message);
|
out.close();
|
||||||
Message msg = consumer.receive(2000);
|
|
||||||
assertNotNull(msg);
|
|
||||||
|
|
||||||
bs1.stop();
|
BrokerService bs1 = createBroker("bs1", firstTcpUri);
|
||||||
bs1.waitUntilStopped();
|
bs1.start();
|
||||||
|
|
||||||
BrokerService bs2 = new BrokerService();
|
// no failover uri's to start with, must be read from file...
|
||||||
bs2.setUseJmx(false);
|
ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("failover:()?updateURIsURL=file:///" + updateFile.getAbsoluteFile());
|
||||||
bs2.addConnector(secondTcpUri);
|
connection = cf.createConnection();
|
||||||
bs2.start();
|
connection.start();
|
||||||
|
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||||
|
Queue theQueue = session.createQueue(QUEUE_NAME);
|
||||||
|
MessageProducer producer = session.createProducer(theQueue);
|
||||||
|
MessageConsumer consumer = session.createConsumer(theQueue);
|
||||||
|
Message message = session.createTextMessage("Test message");
|
||||||
|
producer.send(message);
|
||||||
|
Message msg = consumer.receive(2000);
|
||||||
|
assertNotNull(msg);
|
||||||
|
|
||||||
// add the transport uri for broker number 2
|
bs1.stop();
|
||||||
out = new FileOutputStream(updateFile, true);
|
bs1.waitUntilStopped();
|
||||||
out.write(",".getBytes());
|
|
||||||
out.write(secondTcpUri.toString().getBytes());
|
|
||||||
out.close();
|
|
||||||
|
|
||||||
producer.send(message);
|
bs2 = createBroker("bs2", secondTcpUri);
|
||||||
msg = consumer.receive(2000);
|
bs2.start();
|
||||||
assertNotNull(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// add the transport uri for broker number 2
|
||||||
|
out = new FileOutputStream(updateFile, true);
|
||||||
|
out.write(",".getBytes());
|
||||||
|
out.write(secondTcpUri.toString().getBytes());
|
||||||
|
out.close();
|
||||||
|
|
||||||
|
producer.send(message);
|
||||||
|
msg = consumer.receive(2000);
|
||||||
|
assertNotNull(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BrokerService createBroker(String name, String tcpUri) throws Exception {
|
||||||
|
BrokerService bs = new BrokerService();
|
||||||
|
bs.setBrokerName(name);
|
||||||
|
bs.setUseJmx(false);
|
||||||
|
bs.setPersistent(false);
|
||||||
|
bs.addConnector(tcpUri);
|
||||||
|
return bs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAutoUpdateURIs() throws Exception {
|
||||||
|
|
||||||
|
BrokerService bs1 = new BrokerService();
|
||||||
|
bs1.setUseJmx(false);
|
||||||
|
TransportConnector transportConnector = bs1.addConnector(firstTcpUri);
|
||||||
|
transportConnector.setUpdateClusterClients(true);
|
||||||
|
bs1.start();
|
||||||
|
|
||||||
|
ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("failover:(" + firstTcpUri + ")");
|
||||||
|
Connection connection = cf.createConnection();
|
||||||
|
connection.start();
|
||||||
|
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||||
|
Queue theQueue = session.createQueue(QUEUE_NAME);
|
||||||
|
MessageProducer producer = session.createProducer(theQueue);
|
||||||
|
MessageConsumer consumer = session.createConsumer(theQueue);
|
||||||
|
Message message = session.createTextMessage("Test message");
|
||||||
|
producer.send(message);
|
||||||
|
Message msg = consumer.receive(4000);
|
||||||
|
assertNotNull(msg);
|
||||||
|
|
||||||
|
bs2 = createBroker("bs2", secondTcpUri);
|
||||||
|
NetworkConnector networkConnector = bs2.addNetworkConnector("static:(" + firstTcpUri + ")");
|
||||||
|
networkConnector.setDuplex(true);
|
||||||
|
bs2.start();
|
||||||
|
LOG.info("started brokerService 2");
|
||||||
|
bs2.waitUntilStarted();
|
||||||
|
|
||||||
|
TimeUnit.SECONDS.sleep(4);
|
||||||
|
|
||||||
|
LOG.info("stopping brokerService 1");
|
||||||
|
bs1.stop();
|
||||||
|
bs1.waitUntilStopped();
|
||||||
|
|
||||||
|
producer.send(message);
|
||||||
|
msg = consumer.receive(4000);
|
||||||
|
assertNotNull(msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue