From 72e83c3a33af3567191c665e876fb16be1483e4d Mon Sep 17 00:00:00 2001 From: Alex Rudyy Date: Tue, 28 Oct 2014 21:57:48 +0000 Subject: QPID-6195: Stop recovering records being updated in one upgrader and removed in another upgrader git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1634996 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/qpid/server/store/NonNullUpgrader.java | 1 + .../VirtualHostStoreUpgraderAndRecovererTest.java | 53 ++++++++++++++++++++++ 2 files changed, 54 insertions(+) (limited to 'qpid/java') diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/NonNullUpgrader.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/NonNullUpgrader.java index 1abd3de34a..3dbcfd2114 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/NonNullUpgrader.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/NonNullUpgrader.java @@ -61,6 +61,7 @@ public abstract class NonNullUpgrader implements DurableConfigurationStoreUpgrad { final Map updates = new HashMap(_updates); updates.putAll(_nextUpgrader.getUpdatedRecords()); + updates.keySet().removeAll(getDeletedRecords().keySet()); return updates; } diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/store/VirtualHostStoreUpgraderAndRecovererTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/store/VirtualHostStoreUpgraderAndRecovererTest.java index 1b13bcbdc6..0e82eb6c73 100644 --- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/store/VirtualHostStoreUpgraderAndRecovererTest.java +++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/store/VirtualHostStoreUpgraderAndRecovererTest.java @@ -35,6 +35,7 @@ import java.util.UUID; import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor; import org.apache.qpid.server.logging.EventLogger; +import org.apache.qpid.server.model.Binding; import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.BrokerModel; import org.apache.qpid.server.model.Exchange; @@ -142,7 +143,55 @@ public class VirtualHostStoreUpgraderAndRecovererTest extends QpidTestCase assertEquals("Unexpected alternative exchange", recoveredDLE, recoveredQueue.getAlternateExchange()); } + public void testRecordUpdatedInOneUpgraderAndRemovedInAnotherUpgraderIsNotRecovered() + { + ConfiguredObjectRecord queue = mockQueue("test-queue", null); + ConfiguredObjectRecord exchange = mockExchange("test-direct", "direct"); + ConfiguredObjectRecord queueBinding1 = mockBinding("test-binding", queue, exchange); + ConfiguredObjectRecord nonExistingExchange = mock(ConfiguredObjectRecord.class); + + // selector on non-topic exchange should be removed from binding arguments in upgrader 0.0->0.1 + // binding to non-existing exchange is removed in upgrader 0.1->0.2 + when(nonExistingExchange.getId()).thenReturn(UUIDGenerator.generateExchangeUUID("non-existing", "test")); + Map arguments = Collections.singletonMap("x-filter-jms-selector", "id=1"); + ConfiguredObjectRecord queueBinding2 = mockBinding("test-non-existing", queue, nonExistingExchange, arguments); + setUpVisit(_hostRecord, queue, exchange, queueBinding1, queueBinding2); + + VirtualHostStoreUpgraderAndRecoverer upgraderAndRecoverer = new VirtualHostStoreUpgraderAndRecoverer(_virtualHostNode); + upgraderAndRecoverer.perform(_durableConfigurationStore); + + final VirtualHost host = _virtualHostNode.getVirtualHost(); + Subject.doAs(org.apache.qpid.server.security.SecurityManager.getSubjectWithAddedSystemRights(), new PrivilegedAction() + { + @Override + public Void run() + { + host.open(); + return null; + } + } + ); + + assertNotNull("Virtual host is not recovered", host); + Queue recoveredQueue = host.findConfiguredObject(Queue.class, "test-queue"); + assertNotNull("Queue is not recovered", recoveredQueue); + + Exchange recoveredExchange= host.findConfiguredObject(Exchange.class, "test-direct"); + assertNotNull("Exchange is not recovered", recoveredExchange); + + Binding recoveredBinding1 = recoveredQueue.findConfiguredObject(Binding.class, "test-binding"); + assertNotNull("Correct binding is not recovered", recoveredBinding1); + + Binding recoveredBinding2 = recoveredQueue.findConfiguredObject(Binding.class, "test-non-existing"); + assertNull("Incorrect binding is recovered", recoveredBinding2); + } + private ConfiguredObjectRecord mockBinding(String bindingName, ConfiguredObjectRecord queue, ConfiguredObjectRecord exchange) + { + return mockBinding(bindingName, queue, exchange, null); + } + + private ConfiguredObjectRecord mockBinding(String bindingName, ConfiguredObjectRecord queue, ConfiguredObjectRecord exchange, Map arguments) { ConfiguredObjectRecord binding = mock(ConfiguredObjectRecord.class); when(binding.getId()).thenReturn(UUID.randomUUID()); @@ -156,6 +205,10 @@ public class VirtualHostStoreUpgraderAndRecovererTest extends QpidTestCase Map attributes = new HashMap<>(); attributes.put("durable", true); attributes.put("name", bindingName); + if (arguments != null) + { + attributes.put("arguments", arguments); + } when(binding.getAttributes()).thenReturn(attributes); return binding; } -- cgit v1.2.1