mirror of https://github.com/apache/activemq.git
[AMQ-6907] add selectorAware option to conditionalNetworkBridgeFilterFactory such that replay back to origin can happen if there are no matching local consumers
This commit is contained in:
parent
efaf9cd77e
commit
82c9f9531e
|
@ -43,6 +43,7 @@ public class ConditionalNetworkBridgeFilterFactory implements NetworkBridgeFilte
|
||||||
int replayDelay = 0;
|
int replayDelay = 0;
|
||||||
int rateLimit = 0;
|
int rateLimit = 0;
|
||||||
int rateDuration = 1000;
|
int rateDuration = 1000;
|
||||||
|
private boolean selectorAware = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NetworkBridgeFilter create(ConsumerInfo info, BrokerId[] remoteBrokerPath, int messageTTL, int consumerTTL) {
|
public NetworkBridgeFilter create(ConsumerInfo info, BrokerId[] remoteBrokerPath, int messageTTL, int consumerTTL) {
|
||||||
|
@ -54,6 +55,7 @@ public class ConditionalNetworkBridgeFilterFactory implements NetworkBridgeFilte
|
||||||
filter.setRateLimit(getRateLimit());
|
filter.setRateLimit(getRateLimit());
|
||||||
filter.setRateDuration(getRateDuration());
|
filter.setRateDuration(getRateDuration());
|
||||||
filter.setReplayDelay(getReplayDelay());
|
filter.setReplayDelay(getReplayDelay());
|
||||||
|
filter.setSelectorAware(isSelectorAware());
|
||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,6 +91,14 @@ public class ConditionalNetworkBridgeFilterFactory implements NetworkBridgeFilte
|
||||||
this.replayDelay = replayDelay;
|
this.replayDelay = replayDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSelectorAware(boolean selectorAware) {
|
||||||
|
this.selectorAware = selectorAware;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSelectorAware() {
|
||||||
|
return selectorAware;
|
||||||
|
}
|
||||||
|
|
||||||
private static class ConditionalNetworkBridgeFilter extends NetworkBridgeFilter {
|
private static class ConditionalNetworkBridgeFilter extends NetworkBridgeFilter {
|
||||||
final static Logger LOG = LoggerFactory.getLogger(ConditionalNetworkBridgeFilter.class);
|
final static Logger LOG = LoggerFactory.getLogger(ConditionalNetworkBridgeFilter.class);
|
||||||
private int rateLimit;
|
private int rateLimit;
|
||||||
|
@ -98,6 +108,7 @@ public class ConditionalNetworkBridgeFilterFactory implements NetworkBridgeFilte
|
||||||
|
|
||||||
private int matchCount;
|
private int matchCount;
|
||||||
private long rateDurationEnd;
|
private long rateDurationEnd;
|
||||||
|
private boolean selectorAware = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean matchesForwardingFilter(Message message, final MessageEvaluationContext mec) {
|
protected boolean matchesForwardingFilter(Message message, final MessageEvaluationContext mec) {
|
||||||
|
@ -136,10 +147,23 @@ public class ConditionalNetworkBridgeFilterFactory implements NetworkBridgeFilte
|
||||||
List<Subscription> consumers = regionDestination.getConsumers();
|
List<Subscription> consumers = regionDestination.getConsumers();
|
||||||
for (Subscription sub : consumers) {
|
for (Subscription sub : consumers) {
|
||||||
if (!sub.getConsumerInfo().isNetworkSubscription() && !sub.getConsumerInfo().isBrowser()) {
|
if (!sub.getConsumerInfo().isNetworkSubscription() && !sub.getConsumerInfo().isBrowser()) {
|
||||||
|
|
||||||
|
if (!isSelectorAware()) {
|
||||||
LOG.trace("Not replaying [{}] for [{}] to origin due to existing local consumer: {}", new Object[]{
|
LOG.trace("Not replaying [{}] for [{}] to origin due to existing local consumer: {}", new Object[]{
|
||||||
message.getMessageId(), message.getDestination(), sub.getConsumerInfo()
|
message.getMessageId(), message.getDestination(), sub.getConsumerInfo()
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
if (sub.matches(message, mec)) {
|
||||||
|
LOG.trace("Not replaying [{}] for [{}] to origin due to existing selector matching local consumer: {}", new Object[]{
|
||||||
|
message.getMessageId(), message.getDestination(), sub.getConsumerInfo()
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -172,5 +196,13 @@ public class ConditionalNetworkBridgeFilterFactory implements NetworkBridgeFilte
|
||||||
public void setAllowReplayWhenNoConsumers(boolean allowReplayWhenNoConsumers) {
|
public void setAllowReplayWhenNoConsumers(boolean allowReplayWhenNoConsumers) {
|
||||||
this.allowReplayWhenNoConsumers = allowReplayWhenNoConsumers;
|
this.allowReplayWhenNoConsumers = allowReplayWhenNoConsumers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSelectorAware(boolean selectorAware) {
|
||||||
|
this.selectorAware = selectorAware;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSelectorAware() {
|
||||||
|
return selectorAware;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,6 +178,95 @@ public class AMQ4607Test extends JmsMultipleBrokersTestSupport implements Uncaug
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testMigratingConsumerSelectorAwareTrue() throws Exception {
|
||||||
|
bridge("Broker0", "Broker1");
|
||||||
|
if (!duplex) bridge("Broker1", "Broker0");
|
||||||
|
|
||||||
|
ConditionalNetworkBridgeFilterFactory conditionalNetworkBridgeFilterFactory = new ConditionalNetworkBridgeFilterFactory();
|
||||||
|
conditionalNetworkBridgeFilterFactory.setReplayDelay(0);
|
||||||
|
conditionalNetworkBridgeFilterFactory.setReplayWhenNoConsumers(true);
|
||||||
|
conditionalNetworkBridgeFilterFactory.setSelectorAware(true);
|
||||||
|
brokers.get("Broker1").broker.getDestinationPolicy().getDefaultEntry().setNetworkBridgeFilterFactory(conditionalNetworkBridgeFilterFactory);
|
||||||
|
|
||||||
|
startAllBrokers();
|
||||||
|
this.waitForBridgeFormation();
|
||||||
|
|
||||||
|
Destination dest = createDestination("TEST.FOO", false);
|
||||||
|
sendMessages("Broker0", dest, 1);
|
||||||
|
|
||||||
|
assertExactMessageCount("Broker0", dest, 1, TIMEOUT);
|
||||||
|
|
||||||
|
MessageConsumer messageConsumerNoMatch = createConsumer("Broker1", dest, "DoNotConsume = 'true'");
|
||||||
|
|
||||||
|
assertExactConsumersConnect("Broker0", dest, 1, TIMEOUT);
|
||||||
|
assertExactConsumersConnect("Broker1", dest, 1, TIMEOUT);
|
||||||
|
|
||||||
|
assertExactMessageCount("Broker1", dest, 1, TIMEOUT);
|
||||||
|
assertExactMessageCount("Broker0", dest, 0, TIMEOUT);
|
||||||
|
|
||||||
|
// now consume the message
|
||||||
|
final String brokerId = "Broker0";
|
||||||
|
MessageConsumer messageConsumer = createConsumer(brokerId, dest);
|
||||||
|
|
||||||
|
assertExactConsumersConnect("Broker0", dest, 2, TIMEOUT);
|
||||||
|
assertExactConsumersConnect("Broker1", dest, 2, TIMEOUT);
|
||||||
|
|
||||||
|
|
||||||
|
assertTrue("Consumed ok", Wait.waitFor(new Wait.Condition() {
|
||||||
|
@Override
|
||||||
|
public boolean isSatisified() throws Exception {
|
||||||
|
return brokers.get(brokerId).allMessages.getMessageIds().size() == 1;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
messageConsumer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMigratingConsumerSelectorAwareFalse() throws Exception {
|
||||||
|
bridge("Broker0", "Broker1");
|
||||||
|
if (!duplex) bridge("Broker1", "Broker0");
|
||||||
|
|
||||||
|
ConditionalNetworkBridgeFilterFactory conditionalNetworkBridgeFilterFactory = new ConditionalNetworkBridgeFilterFactory();
|
||||||
|
conditionalNetworkBridgeFilterFactory.setReplayDelay(0);
|
||||||
|
conditionalNetworkBridgeFilterFactory.setReplayWhenNoConsumers(true);
|
||||||
|
conditionalNetworkBridgeFilterFactory.setSelectorAware(false);
|
||||||
|
brokers.get("Broker1").broker.getDestinationPolicy().getDefaultEntry().setNetworkBridgeFilterFactory(conditionalNetworkBridgeFilterFactory);
|
||||||
|
|
||||||
|
startAllBrokers();
|
||||||
|
this.waitForBridgeFormation();
|
||||||
|
|
||||||
|
Destination dest = createDestination("TEST.FOO", false);
|
||||||
|
sendMessages("Broker0", dest, 1);
|
||||||
|
|
||||||
|
assertExactMessageCount("Broker0", dest, 1, TIMEOUT);
|
||||||
|
|
||||||
|
MessageConsumer messageConsumerNoMatch = createConsumer("Broker1", dest, "DoNotConsume = 'true'");
|
||||||
|
|
||||||
|
assertExactConsumersConnect("Broker0", dest, 1, TIMEOUT);
|
||||||
|
assertExactConsumersConnect("Broker1", dest, 1, TIMEOUT);
|
||||||
|
|
||||||
|
assertExactMessageCount("Broker1", dest, 1, TIMEOUT);
|
||||||
|
assertExactMessageCount("Broker0", dest, 0, TIMEOUT);
|
||||||
|
|
||||||
|
// now try consume the message
|
||||||
|
final String brokerId = "Broker0";
|
||||||
|
MessageConsumer messageConsumer = createConsumer(brokerId, dest);
|
||||||
|
|
||||||
|
assertExactConsumersConnect("Broker0", dest, 2, TIMEOUT);
|
||||||
|
assertExactConsumersConnect("Broker1", dest, 2, TIMEOUT);
|
||||||
|
|
||||||
|
assertExactMessageCount("Broker1", dest, 1, TIMEOUT);
|
||||||
|
assertExactMessageCount("Broker0", dest, 0, TIMEOUT);
|
||||||
|
|
||||||
|
assertTrue("Consumed ok", Wait.waitFor(new Wait.Condition() {
|
||||||
|
@Override
|
||||||
|
public boolean isSatisified() throws Exception {
|
||||||
|
return brokers.get(brokerId).allMessages.getMessageIds().size() == 0;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
messageConsumer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void assertExactMessageCount(final String brokerName, Destination destination, final int count, long timeout) throws Exception {
|
protected void assertExactMessageCount(final String brokerName, Destination destination, final int count, long timeout) throws Exception {
|
||||||
ManagementContext context = brokers.get(brokerName).broker.getManagementContext();
|
ManagementContext context = brokers.get(brokerName).broker.getManagementContext();
|
||||||
final QueueViewMBean queueViewMBean = (QueueViewMBean) context.newProxyInstance(brokers.get(brokerName).broker.getAdminView().getQueues()[0], QueueViewMBean.class, false);
|
final QueueViewMBean queueViewMBean = (QueueViewMBean) context.newProxyInstance(brokers.get(brokerName).broker.getAdminView().getQueues()[0], QueueViewMBean.class, false);
|
||||||
|
|
Loading…
Reference in New Issue