mirror of https://github.com/apache/activemq.git
Fixed Network Connection failure recovery.
http://issues.apache.org/activemq/browse/AMQ-802 http://issues.apache.org/activemq/browse/AMQ-805 git-svn-id: https://svn.apache.org/repos/asf/incubator/activemq/trunk@420723 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
75fde7165e
commit
ad2546fa8d
|
@ -53,9 +53,6 @@ public class DemandForwardingBridge extends DemandForwardingBridgeSupport {
|
||||||
ServiceSupport.dispose(this);
|
ServiceSupport.dispose(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!disposed){
|
|
||||||
triggerLocalStartBridge();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,14 +70,14 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
|
||||||
protected static final Log log = LogFactory.getLog(DemandForwardingBridge.class);
|
protected static final Log log = LogFactory.getLog(DemandForwardingBridge.class);
|
||||||
protected final Transport localBroker;
|
protected final Transport localBroker;
|
||||||
protected final Transport remoteBroker;
|
protected final Transport remoteBroker;
|
||||||
protected IdGenerator idGenerator = new IdGenerator();
|
protected final IdGenerator idGenerator = new IdGenerator();
|
||||||
protected LongSequenceGenerator consumerIdGenerator = new LongSequenceGenerator();
|
protected final LongSequenceGenerator consumerIdGenerator = new LongSequenceGenerator();
|
||||||
protected ConnectionInfo localConnectionInfo;
|
protected ConnectionInfo localConnectionInfo;
|
||||||
protected ConnectionInfo remoteConnectionInfo;
|
protected ConnectionInfo remoteConnectionInfo;
|
||||||
protected SessionInfo localSessionInfo;
|
protected SessionInfo localSessionInfo;
|
||||||
protected ProducerInfo producerInfo;
|
protected ProducerInfo producerInfo;
|
||||||
protected String localBrokerName;
|
protected String localBrokerName = "Unknown";
|
||||||
protected String remoteBrokerName;
|
protected String remoteBrokerName = "Unknown";
|
||||||
protected String localClientId;
|
protected String localClientId;
|
||||||
protected String userName;
|
protected String userName;
|
||||||
protected String password;
|
protected String password;
|
||||||
|
@ -87,22 +87,22 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
|
||||||
protected String name = "bridge";
|
protected String name = "bridge";
|
||||||
protected ConsumerInfo demandConsumerInfo;
|
protected ConsumerInfo demandConsumerInfo;
|
||||||
protected int demandConsumerDispatched;
|
protected int demandConsumerDispatched;
|
||||||
protected AtomicBoolean localBridgeStarted = new AtomicBoolean(false);
|
protected final AtomicBoolean localBridgeStarted = new AtomicBoolean(false);
|
||||||
protected AtomicBoolean remoteBridgeStarted = new AtomicBoolean(false);
|
protected final AtomicBoolean remoteBridgeStarted = new AtomicBoolean(false);
|
||||||
protected boolean disposed = false;
|
protected boolean disposed = false;
|
||||||
protected BrokerId localBrokerId;
|
protected BrokerId localBrokerId;
|
||||||
protected ActiveMQDestination[] excludedDestinations;
|
protected ActiveMQDestination[] excludedDestinations;
|
||||||
protected ActiveMQDestination[] dynamicallyIncludedDestinations;
|
protected ActiveMQDestination[] dynamicallyIncludedDestinations;
|
||||||
protected ActiveMQDestination[] staticallyIncludedDestinations;
|
protected ActiveMQDestination[] staticallyIncludedDestinations;
|
||||||
protected ActiveMQDestination[] durableDestinations;
|
protected ActiveMQDestination[] durableDestinations;
|
||||||
protected ConcurrentHashMap subscriptionMapByLocalId = new ConcurrentHashMap();
|
protected final ConcurrentHashMap subscriptionMapByLocalId = new ConcurrentHashMap();
|
||||||
protected ConcurrentHashMap subscriptionMapByRemoteId = new ConcurrentHashMap();
|
protected final ConcurrentHashMap subscriptionMapByRemoteId = new ConcurrentHashMap();
|
||||||
protected final BrokerId localBrokerPath[] = new BrokerId[] { null };
|
protected final BrokerId localBrokerPath[] = new BrokerId[] { null };
|
||||||
protected CountDownLatch startedLatch = new CountDownLatch(2);
|
protected CountDownLatch startedLatch = new CountDownLatch(2);
|
||||||
protected boolean decreaseNetworkConsumerPriority;
|
protected boolean decreaseNetworkConsumerPriority;
|
||||||
protected boolean shutDown;
|
|
||||||
protected int networkTTL = 1;
|
protected int networkTTL = 1;
|
||||||
protected final AtomicBoolean remoteInterupted = new AtomicBoolean(false);
|
protected final AtomicBoolean remoteInterupted = new AtomicBoolean(false);
|
||||||
|
protected final AtomicBoolean lastConnectSucceeded = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
|
||||||
public DemandForwardingBridgeSupport(final Transport localBroker, final Transport remoteBroker) {
|
public DemandForwardingBridgeSupport(final Transport localBroker, final Transport remoteBroker) {
|
||||||
|
@ -111,7 +111,6 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() throws Exception {
|
public void start() throws Exception {
|
||||||
log.info("Starting a network connection between "+localBroker+" and "+remoteBroker+" has been established.");
|
|
||||||
localBroker.setTransportListener(new DefaultTransportListener(){
|
localBroker.setTransportListener(new DefaultTransportListener(){
|
||||||
public void onCommand(Command command){
|
public void onCommand(Command command){
|
||||||
serviceLocalCommand(command);
|
serviceLocalCommand(command);
|
||||||
|
@ -130,16 +129,23 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
|
||||||
serviceRemoteException(error);
|
serviceRemoteException(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void transportInterupted(){
|
public void transportInterupted(){
|
||||||
//clear any subscriptions - to try and prevent the bridge from stalling the broker
|
//clear any subscriptions - to try and prevent the bridge from stalling the broker
|
||||||
if( remoteInterupted.compareAndSet(false, true) ) {
|
if( remoteInterupted.compareAndSet(false, true) ) {
|
||||||
log.warn("Outbound transport to " + remoteBrokerName + " interrupted ...");
|
|
||||||
|
log.debug("Outbound transport to " + remoteBrokerName + " interrupted.");
|
||||||
|
|
||||||
|
if( localBridgeStarted.get() ) {
|
||||||
clearDownSubscriptions();
|
clearDownSubscriptions();
|
||||||
|
synchronized( DemandForwardingBridgeSupport.this ) {
|
||||||
try{
|
try{
|
||||||
localBroker.oneway(localConnectionInfo.createRemoveCommand());
|
localBroker.oneway(localConnectionInfo.createRemoveCommand());
|
||||||
}catch(IOException e){
|
}catch(IOException e){
|
||||||
log.warn("Caught exception from local start",e);
|
log.warn("Caught exception from local start",e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
localBridgeStarted.set(false);
|
localBridgeStarted.set(false);
|
||||||
remoteBridgeStarted.set(false);
|
remoteBridgeStarted.set(false);
|
||||||
startedLatch = new CountDownLatch(2);
|
startedLatch = new CountDownLatch(2);
|
||||||
|
@ -147,35 +153,33 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void transportResumed(){
|
public void transportResumed(){
|
||||||
|
|
||||||
if( remoteInterupted.compareAndSet(true, false) ) {
|
if( remoteInterupted.compareAndSet(true, false) ) {
|
||||||
|
|
||||||
//restart and static subscriptions - the consumer advisories will be replayed
|
// We want to slow down false connects so that we don't get in a busy loop.
|
||||||
log.info("Outbound transport to " + remoteBrokerName + " resumed");
|
// False connects can occurr if you using SSH tunnels.
|
||||||
|
if( !lastConnectSucceeded.get() ) {
|
||||||
// try{
|
try {
|
||||||
// triggerLocalStartBridge();
|
log.debug("Previous connection was never fully established. Sleeping for second to avoid busy loop.");
|
||||||
// }catch(IOException e){
|
Thread.sleep(1000);
|
||||||
// log.warn("Caught exception from local start",e);
|
} catch (InterruptedException e) {
|
||||||
// }
|
Thread.currentThread().interrupt();
|
||||||
|
|
||||||
try{
|
|
||||||
// clear out the previous connection as it may have missed some consumer advisories.
|
|
||||||
remoteBroker.oneway(remoteConnectionInfo.createRemoveCommand());
|
|
||||||
triggerRemoteStartBridge();
|
|
||||||
}catch(IOException e){
|
|
||||||
log.warn("Caught exception from remote start",e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
lastConnectSucceeded.set(false);
|
||||||
|
|
||||||
|
log.debug("Outbound transport to " + remoteBrokerName + " resumed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
localBroker.start();
|
localBroker.start();
|
||||||
remoteBroker.start();
|
remoteBroker.start();
|
||||||
// triggerLocalStartBridge();
|
|
||||||
|
try{
|
||||||
triggerRemoteStartBridge();
|
triggerRemoteStartBridge();
|
||||||
|
}catch(IOException e){
|
||||||
|
log.warn("Caught exception from remote start",e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void triggerLocalStartBridge() throws IOException {
|
protected void triggerLocalStartBridge() throws IOException {
|
||||||
|
@ -184,7 +188,7 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
|
||||||
try{
|
try{
|
||||||
startLocalBridge();
|
startLocalBridge();
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
log.error("Failed to start network bridge: "+e,e);
|
serviceLocalException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -197,7 +201,7 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
|
||||||
try{
|
try{
|
||||||
startRemoteBridge();
|
startRemoteBridge();
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
log.error("Failed to start network bridge: "+e,e);
|
serviceRemoteException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -206,7 +210,7 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
|
||||||
|
|
||||||
protected void startLocalBridge() throws Exception {
|
protected void startLocalBridge() throws Exception {
|
||||||
if(localBridgeStarted.compareAndSet(false,true)){
|
if(localBridgeStarted.compareAndSet(false,true)){
|
||||||
|
synchronized( this ) {
|
||||||
localConnectionInfo=new ConnectionInfo();
|
localConnectionInfo=new ConnectionInfo();
|
||||||
localConnectionInfo.setConnectionId(new ConnectionId(idGenerator.generateId()));
|
localConnectionInfo.setConnectionId(new ConnectionId(idGenerator.generateId()));
|
||||||
localClientId="NC_"+remoteBrokerName+"_inbound"+name;
|
localClientId="NC_"+remoteBrokerName+"_inbound"+name;
|
||||||
|
@ -220,13 +224,21 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
|
||||||
|
|
||||||
log.info("Network connection between "+localBroker+" and "+remoteBroker+"("+remoteBrokerName
|
log.info("Network connection between "+localBroker+" and "+remoteBroker+"("+remoteBrokerName
|
||||||
+") has been established.");
|
+") has been established.");
|
||||||
|
|
||||||
startedLatch.countDown();
|
startedLatch.countDown();
|
||||||
setupStaticDestinations();
|
setupStaticDestinations();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void startRemoteBridge() throws Exception {
|
protected void startRemoteBridge() throws Exception {
|
||||||
if(remoteBridgeStarted.compareAndSet(false,true)){
|
if(remoteBridgeStarted.compareAndSet(false,true)) {
|
||||||
|
|
||||||
|
synchronized (this) {
|
||||||
|
|
||||||
|
if( remoteConnectionInfo!=null ) {
|
||||||
|
remoteBroker.oneway(remoteConnectionInfo.createRemoveCommand());
|
||||||
|
}
|
||||||
|
|
||||||
remoteConnectionInfo=new ConnectionInfo();
|
remoteConnectionInfo=new ConnectionInfo();
|
||||||
remoteConnectionInfo.setConnectionId(new ConnectionId(idGenerator.generateId()));
|
remoteConnectionInfo.setConnectionId(new ConnectionId(idGenerator.generateId()));
|
||||||
|
@ -259,39 +271,30 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
|
||||||
destinationInfo.setPrefetchSize(prefetchSize);
|
destinationInfo.setPrefetchSize(prefetchSize);
|
||||||
remoteBroker.oneway(destinationInfo);
|
remoteBroker.oneway(destinationInfo);
|
||||||
startedLatch.countDown();
|
startedLatch.countDown();
|
||||||
|
|
||||||
|
if (!disposed){
|
||||||
|
triggerLocalStartBridge();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop() throws Exception {
|
public void stop() throws Exception {
|
||||||
shutDown = true;
|
|
||||||
doStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* stop the bridge
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
protected void doStop() throws Exception {
|
|
||||||
log.debug(" stopping "+localBrokerName+ " bridge to " + remoteBrokerName + " is disposed already ? "+disposed);
|
log.debug(" stopping "+localBrokerName+ " bridge to " + remoteBrokerName + " is disposed already ? "+disposed);
|
||||||
if(!disposed){
|
if (!disposed) {
|
||||||
try{
|
try {
|
||||||
disposed=true;
|
disposed = true;
|
||||||
|
|
||||||
remoteBridgeStarted.set(false);
|
remoteBridgeStarted.set(false);
|
||||||
if(!shutDown){
|
|
||||||
remoteBroker.oneway(new ShutdownInfo());
|
|
||||||
if(localConnectionInfo!=null){
|
|
||||||
localBroker.oneway(localConnectionInfo.createRemoveCommand());
|
|
||||||
remoteBroker.oneway(remoteConnectionInfo.createRemoveCommand());
|
|
||||||
}
|
|
||||||
localBroker.oneway(new ShutdownInfo());
|
localBroker.oneway(new ShutdownInfo());
|
||||||
}
|
remoteBroker.oneway(new ShutdownInfo());
|
||||||
localBroker.setTransportListener(null);
|
|
||||||
remoteBroker.setTransportListener(null);
|
} catch (IOException e) {
|
||||||
}catch(IOException e){
|
log.debug("Caught exception stopping", e);
|
||||||
log.debug("Caught exception stopping",e);
|
} finally {
|
||||||
}finally{
|
ServiceStopper ss = new ServiceStopper();
|
||||||
ServiceStopper ss=new ServiceStopper();
|
|
||||||
ss.stop(localBroker);
|
ss.stop(localBroker);
|
||||||
ss.stop(remoteBroker);
|
ss.stop(remoteBroker);
|
||||||
ss.throwFirstException();
|
ss.throwFirstException();
|
||||||
|
@ -300,27 +303,16 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
|
||||||
log.debug(localBrokerName+ " bridge to " + remoteBrokerName + " stopped");
|
log.debug(localBrokerName+ " bridge to " + remoteBrokerName + " stopped");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void doStopLocal(){
|
|
||||||
try{
|
|
||||||
if(!shutDown){
|
|
||||||
if(localConnectionInfo!=null){
|
|
||||||
localBroker.oneway(localConnectionInfo.createRemoveCommand());
|
|
||||||
}
|
|
||||||
localBroker.oneway(new ShutdownInfo());
|
|
||||||
}
|
|
||||||
localBroker.setTransportListener(null);
|
|
||||||
}catch(IOException e){
|
|
||||||
log.debug("Caught exception stopping",e);
|
|
||||||
}finally{
|
|
||||||
ServiceStopper ss=new ServiceStopper();
|
|
||||||
ss.stop(localBroker);
|
|
||||||
localBridgeStarted.set(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void serviceRemoteException(Throwable error) {
|
protected void serviceRemoteException(Throwable error) {
|
||||||
log.info("Network connection between "+localBroker+" and "+remoteBroker+" shutdown: "+error.getMessage(),error);
|
if( !disposed ) {
|
||||||
ServiceSupport.dispose(this);
|
log.info("Network connection between "+localBroker+" and "+remoteBroker+" shutdown due to a remote error: "+error);
|
||||||
|
log.debug("The remote Exception was: "+error, error);
|
||||||
|
new Thread() {
|
||||||
|
public void run() {
|
||||||
|
ServiceSupport.dispose(DemandForwardingBridgeSupport.this);
|
||||||
|
}
|
||||||
|
}.start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void serviceRemoteCommand(Command command) {
|
protected void serviceRemoteCommand(Command command) {
|
||||||
|
@ -336,7 +328,10 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
|
||||||
demandConsumerDispatched=0;
|
demandConsumerDispatched=0;
|
||||||
}
|
}
|
||||||
}else if(command.isBrokerInfo()){
|
}else if(command.isBrokerInfo()){
|
||||||
|
|
||||||
|
lastConnectSucceeded.set(true);
|
||||||
serviceRemoteBrokerInfo(command);
|
serviceRemoteBrokerInfo(command);
|
||||||
|
|
||||||
}else if(command.getClass() == ConnectionError.class ) {
|
}else if(command.getClass() == ConnectionError.class ) {
|
||||||
ConnectionError ce = (ConnectionError) command;
|
ConnectionError ce = (ConnectionError) command;
|
||||||
serviceRemoteException(ce.getException());
|
serviceRemoteException(ce.getException());
|
||||||
|
@ -344,6 +339,7 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
|
||||||
switch(command.getDataStructureType()){
|
switch(command.getDataStructureType()){
|
||||||
case KeepAliveInfo.DATA_STRUCTURE_TYPE:
|
case KeepAliveInfo.DATA_STRUCTURE_TYPE:
|
||||||
case WireFormatInfo.DATA_STRUCTURE_TYPE:
|
case WireFormatInfo.DATA_STRUCTURE_TYPE:
|
||||||
|
case ShutdownInfo.DATA_STRUCTURE_TYPE:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log.warn("Unexpected remote command: "+command);
|
log.warn("Unexpected remote command: "+command);
|
||||||
|
@ -413,7 +409,10 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
|
||||||
ActiveMQTempDestination tempDest = (ActiveMQTempDestination) destInfo.getDestination();
|
ActiveMQTempDestination tempDest = (ActiveMQTempDestination) destInfo.getDestination();
|
||||||
tempDest.setConnectionId(localSessionInfo.getSessionId().getConnectionId());
|
tempDest.setConnectionId(localSessionInfo.getSessionId().getConnectionId());
|
||||||
}
|
}
|
||||||
|
|
||||||
destInfo.setBrokerPath(appendToBrokerPath(destInfo.getBrokerPath(),getRemoteBrokerPath()));
|
destInfo.setBrokerPath(appendToBrokerPath(destInfo.getBrokerPath(),getRemoteBrokerPath()));
|
||||||
|
|
||||||
|
log.debug("Replying destination control command: "+destInfo);
|
||||||
localBroker.oneway(destInfo);
|
localBroker.oneway(destInfo);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -424,8 +423,15 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void serviceLocalException(Throwable error) {
|
protected void serviceLocalException(Throwable error) {
|
||||||
log.info("Network connection between "+localBroker+" and "+remoteBroker+" shutdown: "+error.getMessage(),error);
|
if( !disposed ) {
|
||||||
ServiceSupport.dispose(this);
|
log.info("Network connection between "+localBroker+" and "+remoteBroker+" shutdown due to a local error: "+error);
|
||||||
|
log.debug("The local Exception was:"+error,error);
|
||||||
|
new Thread() {
|
||||||
|
public void run() {
|
||||||
|
ServiceSupport.dispose(DemandForwardingBridgeSupport.this);
|
||||||
|
}
|
||||||
|
}.start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addSubscription(DemandSubscription sub) throws IOException {
|
protected void addSubscription(DemandSubscription sub) throws IOException {
|
||||||
|
@ -502,16 +508,6 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
|
||||||
remoteBroker.asyncRequest(message, callback);
|
remoteBroker.asyncRequest(message, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ack on every message since we don't know if the broker is blocked due to memory
|
|
||||||
// usage and is waiting for an Ack to un-block him.
|
|
||||||
|
|
||||||
// Acking a range is more efficient, but also more prone to locking up a server
|
|
||||||
// Perhaps doing something like the following should be policy based.
|
|
||||||
// int dispatched = sub.incrementDispatched();
|
|
||||||
// if(dispatched>(sub.getLocalInfo().getPrefetchSize()*.75)){
|
|
||||||
// localBroker.oneway(new MessageAck(md,MessageAck.STANDARD_ACK_TYPE,dispatched));
|
|
||||||
// sub.setDispatched(0);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}else if(command.isBrokerInfo()){
|
}else if(command.isBrokerInfo()){
|
||||||
serviceLocalBrokerInfo(command);
|
serviceLocalBrokerInfo(command);
|
||||||
|
@ -521,8 +517,7 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
|
||||||
// the local transport is just shutting down temporarily until the remote side
|
// the local transport is just shutting down temporarily until the remote side
|
||||||
// is restored.
|
// is restored.
|
||||||
if( !remoteInterupted.get() ) {
|
if( !remoteInterupted.get() ) {
|
||||||
shutDown = true;
|
stop();
|
||||||
doStop();
|
|
||||||
}
|
}
|
||||||
}else if(command.getClass() == ConnectionError.class ) {
|
}else if(command.getClass() == ConnectionError.class ) {
|
||||||
ConnectionError ce = (ConnectionError) command;
|
ConnectionError ce = (ConnectionError) command;
|
||||||
|
@ -696,20 +691,6 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
|
||||||
this.networkTTL=networkTTL;
|
this.networkTTL=networkTTL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Returns the shutDown.
|
|
||||||
*/
|
|
||||||
public boolean isShutDown() {
|
|
||||||
return shutDown;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param shutDown The shutDown to set.
|
|
||||||
*/
|
|
||||||
public void setShutDown(boolean shutDown) {
|
|
||||||
this.shutDown=shutDown;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean contains(BrokerId[] brokerPath, BrokerId brokerId) {
|
public static boolean contains(BrokerId[] brokerPath, BrokerId brokerId) {
|
||||||
if(brokerPath!=null){
|
if(brokerPath!=null){
|
||||||
for(int i=0;i<brokerPath.length;i++){
|
for(int i=0;i<brokerPath.length;i++){
|
||||||
|
@ -843,7 +824,8 @@ public abstract class DemandForwardingBridgeSupport implements Bridge {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void clearDownSubscriptions() {
|
protected void clearDownSubscriptions() {
|
||||||
|
subscriptionMapByLocalId.clear();
|
||||||
|
subscriptionMapByRemoteId.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract NetworkBridgeFilter createNetworkBridgeFilter(ConsumerInfo info) throws IOException;
|
protected abstract NetworkBridgeFilter createNetworkBridgeFilter(ConsumerInfo info) throws IOException;
|
||||||
|
|
|
@ -16,9 +16,11 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.activemq.network;
|
package org.apache.activemq.network;
|
||||||
|
|
||||||
import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
import org.apache.activemq.broker.BrokerService;
|
|
||||||
import org.apache.activemq.command.DiscoveryEvent;
|
import org.apache.activemq.command.DiscoveryEvent;
|
||||||
import org.apache.activemq.transport.Transport;
|
import org.apache.activemq.transport.Transport;
|
||||||
import org.apache.activemq.transport.TransportFactory;
|
import org.apache.activemq.transport.TransportFactory;
|
||||||
|
@ -28,10 +30,7 @@ import org.apache.activemq.transport.discovery.DiscoveryListener;
|
||||||
import org.apache.activemq.util.ServiceStopper;
|
import org.apache.activemq.util.ServiceStopper;
|
||||||
import org.apache.activemq.util.ServiceSupport;
|
import org.apache.activemq.util.ServiceSupport;
|
||||||
|
|
||||||
import java.io.IOException;
|
import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A network connector which uses a discovery agent to detect the remote brokers
|
* A network connector which uses a discovery agent to detect the remote brokers
|
||||||
|
@ -58,6 +57,11 @@ public class DiscoveryNetworkConnector extends NetworkConnector implements Disco
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onServiceAdd(DiscoveryEvent event) {
|
public void onServiceAdd(DiscoveryEvent event) {
|
||||||
|
|
||||||
|
// Ignore events once we start stopping.
|
||||||
|
if( isStopped() || isStopping() )
|
||||||
|
return;
|
||||||
|
|
||||||
String url = event.getServiceName();
|
String url = event.getServiceName();
|
||||||
if (url != null) {
|
if (url != null) {
|
||||||
|
|
||||||
|
@ -80,7 +84,7 @@ public class DiscoveryNetworkConnector extends NetworkConnector implements Disco
|
||||||
URI connectUri = uri;
|
URI connectUri = uri;
|
||||||
if (failover) {
|
if (failover) {
|
||||||
try {
|
try {
|
||||||
connectUri = new URI("failover:" + connectUri);
|
connectUri = new URI("failover:(" + connectUri+")?maxReconnectDelay=1000");
|
||||||
}
|
}
|
||||||
catch (URISyntaxException e) {
|
catch (URISyntaxException e) {
|
||||||
log.warn("Could not create failover URI: " + connectUri);
|
log.warn("Could not create failover URI: " + connectUri);
|
||||||
|
@ -90,22 +94,24 @@ public class DiscoveryNetworkConnector extends NetworkConnector implements Disco
|
||||||
|
|
||||||
log.info("Establishing network connection between from " + localURI + " to " + connectUri);
|
log.info("Establishing network connection between from " + localURI + " to " + connectUri);
|
||||||
|
|
||||||
Transport localTransport;
|
|
||||||
try {
|
|
||||||
localTransport = createLocalTransport();
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
log.warn("Could not connect to local URI: " + localURI + ": " + e, e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Transport remoteTransport;
|
Transport remoteTransport;
|
||||||
try {
|
try {
|
||||||
remoteTransport = TransportFactory.connect(connectUri);
|
remoteTransport = TransportFactory.connect(connectUri);
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
ServiceSupport.dispose(localTransport);
|
log.warn("Could not connect to remote URI: " + localURI + ": " + e.getMessage());
|
||||||
log.warn("Could not connect to remote URI: " + connectUri + ": " + e, e);
|
log.debug("Connection failure exception: "+ e, e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Transport localTransport;
|
||||||
|
try {
|
||||||
|
localTransport = createLocalTransport();
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
ServiceSupport.dispose(remoteTransport);
|
||||||
|
log.warn("Could not connect to local URI: " + localURI + ": " + e.getMessage());
|
||||||
|
log.debug("Connection failure exception: "+ e, e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +123,13 @@ public class DiscoveryNetworkConnector extends NetworkConnector implements Disco
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
ServiceSupport.dispose(localTransport);
|
ServiceSupport.dispose(localTransport);
|
||||||
ServiceSupport.dispose(remoteTransport);
|
ServiceSupport.dispose(remoteTransport);
|
||||||
log.warn("Could not start network bridge between: " + localURI + " and: " + uri + " due to: " + e, e);
|
log.warn("Could not start network bridge between: " + localURI + " and: " + uri + " due to: " + e);
|
||||||
|
log.debug("Start failure exception: "+ e, e);
|
||||||
|
|
||||||
|
try {
|
||||||
|
discoveryAgent.serviceFailed(event);
|
||||||
|
} catch (IOException e1) {
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,28 +208,52 @@ public class DiscoveryNetworkConnector extends NetworkConnector implements Disco
|
||||||
if (conduitSubscriptions) {
|
if (conduitSubscriptions) {
|
||||||
if (dynamicOnly) {
|
if (dynamicOnly) {
|
||||||
result = new ConduitBridge(localTransport, remoteTransport) {
|
result = new ConduitBridge(localTransport, remoteTransport) {
|
||||||
protected void serviceRemoteException(Exception error) {
|
protected void serviceLocalException(Throwable error) {
|
||||||
super.serviceRemoteException(error);
|
|
||||||
try {
|
try {
|
||||||
// Notify the discovery agent that the remote broker
|
super.serviceLocalException(error);
|
||||||
// failed.
|
} finally {
|
||||||
discoveryAgent.serviceFailed(event);
|
fireServiceFailed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected void serviceRemoteException(Throwable error) {
|
||||||
|
try {
|
||||||
|
super.serviceRemoteException(error);
|
||||||
|
} finally {
|
||||||
|
fireServiceFailed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void fireServiceFailed() {
|
||||||
|
if( !isStopped() ) {
|
||||||
|
try {
|
||||||
|
discoveryAgent.serviceFailed(event);
|
||||||
|
} catch (IOException e) {
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = new DurableConduitBridge(localTransport, remoteTransport) {
|
result = new DurableConduitBridge(localTransport, remoteTransport) {
|
||||||
protected void serviceRemoteException(Exception error) {
|
protected void serviceLocalException(Throwable error) {
|
||||||
super.serviceRemoteException(error);
|
|
||||||
try {
|
try {
|
||||||
// Notify the discovery agent that the remote broker
|
super.serviceLocalException(error);
|
||||||
// failed.
|
} finally {
|
||||||
discoveryAgent.serviceFailed(event);
|
fireServiceFailed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected void serviceRemoteException(Throwable error) {
|
||||||
|
try {
|
||||||
|
super.serviceRemoteException(error);
|
||||||
|
} finally {
|
||||||
|
fireServiceFailed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void fireServiceFailed() {
|
||||||
|
if( !isStopped() ) {
|
||||||
|
try {
|
||||||
|
discoveryAgent.serviceFailed(event);
|
||||||
|
} catch (IOException e) {
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -225,14 +261,26 @@ public class DiscoveryNetworkConnector extends NetworkConnector implements Disco
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = new DemandForwardingBridge(localTransport, remoteTransport) {
|
result = new DemandForwardingBridge(localTransport, remoteTransport) {
|
||||||
protected void serviceRemoteException(Exception error) {
|
protected void serviceLocalException(Throwable error) {
|
||||||
super.serviceRemoteException(error);
|
|
||||||
try {
|
try {
|
||||||
// Notify the discovery agent that the remote broker
|
super.serviceLocalException(error);
|
||||||
// failed.
|
} finally {
|
||||||
discoveryAgent.serviceFailed(event);
|
fireServiceFailed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected void serviceRemoteException(Throwable error) {
|
||||||
|
try {
|
||||||
|
super.serviceRemoteException(error);
|
||||||
|
} finally {
|
||||||
|
fireServiceFailed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void fireServiceFailed() {
|
||||||
|
if( !isStopped() ) {
|
||||||
|
try {
|
||||||
|
discoveryAgent.serviceFailed(event);
|
||||||
|
} catch (IOException e) {
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue