You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ma...@apache.org on 2016/09/06 14:08:03 UTC
[1/7] activemq-artemis git commit: This closes #749
Repository: activemq-artemis
Updated Branches:
refs/heads/master bfc2095b6 -> 3869d4935
This closes #749
Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/3869d493
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/3869d493
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/3869d493
Branch: refs/heads/master
Commit: 3869d49353f14fac4778f335de4af0b7571370cc
Parents: bfc2095 4472aa0
Author: Martyn Taylor <mt...@redhat.com>
Authored: Tue Sep 6 15:07:49 2016 +0100
Committer: Martyn Taylor <mt...@redhat.com>
Committed: Tue Sep 6 15:07:49 2016 +0100
----------------------------------------------------------------------
.../artemis/cli/commands/etc/broker.xml | 16 +-
.../config/ActiveMQDefaultConfiguration.java | 19 +
.../protocol/AbstractRemotingConnection.java | 4 +
.../spi/core/protocol/RemotingConnection.java | 8 +
.../core/protocol/mqtt/MQTTConnection.java | 5 +
.../core/protocol/stomp/StompConnection.java | 4 +
.../artemis/core/config/Configuration.java | 16 +-
.../core/config/impl/ConfigurationImpl.java | 39 +
.../deployers/impl/FileConfigurationParser.java | 12 +
.../artemis/core/paging/PagingManager.java | 16 +
.../artemis/core/paging/PagingStore.java | 3 +
.../artemis/core/paging/PagingStoreFactory.java | 3 +
.../artemis/core/paging/impl/PageSyncTimer.java | 2 +
.../core/paging/impl/PagingManagerImpl.java | 93 +-
.../core/paging/impl/PagingStoreFactoryNIO.java | 8 +-
.../core/paging/impl/PagingStoreImpl.java | 95 +-
.../core/persistence/StorageManager.java | 4 +
.../impl/journal/JournalStorageManager.java | 12 +-
.../impl/nullpm/NullStorageManager.java | 6 +
.../core/server/ActiveMQMessageBundle.java | 5 +
.../core/server/ActiveMQScheduledComponent.java | 101 +
.../core/server/ActiveMQServerLogger.java | 10 +
.../core/server/files/FileMoveManager.java | 218 +
.../core/server/files/FileStoreMonitor.java | 127 +
.../core/server/impl/ActiveMQServerImpl.java | 39 +-
.../core/server/impl/FileMoveManager.java | 218 -
.../core/server/impl/ServerSessionImpl.java | 17 +-
.../core/server/reload/ReloadManagerImpl.java | 50 +-
.../resources/schema/artemis-configuration.xsd | 24 +
.../core/config/impl/FileConfigurationTest.java | 3 +
.../core/server/files/FileMoveManagerTest.java | 346 ++
.../core/server/files/FileStoreMonitorTest.java | 161 +
.../core/server/impl/FileMoveManagerTest.java | 346 --
.../transaction/impl/TransactionImplTest.java | 6 +
.../artemis/tests/util/ActiveMQTestBase.java | 20 +-
.../resources/ConfigurationTest-full-config.xml | 3 +
docs/user-manual/en/configuration-index.md | 3 +
docs/user-manual/en/paging.md | 15 +-
.../integration/client/HangConsumerTest.java | 2 +-
.../integration/client/LargeMessageTest.java | 2 +-
.../integration/client/PagingOrderTest.java | 714 ---
.../integration/client/PagingSyncTest.java | 109 -
.../tests/integration/client/PagingTest.java | 5734 ------------------
.../cluster/failover/BackupSyncJournalTest.java | 2 +-
.../cluster/failover/FailoverTest.java | 2 +-
.../paging/AddressFullLoggingTest.java | 152 +
.../integration/paging/GlobalPagingTest.java | 183 +
.../integration/paging/PagingOrderTest.java | 714 +++
.../integration/paging/PagingSyncTest.java | 109 +
.../tests/integration/paging/PagingTest.java | 5731 +++++++++++++++++
.../server/AddressFullLoggingTest.java | 131 -
.../tests/integration/stomp/StompTest.java | 42 +
.../tests/integration/stomp/StompTestBase.java | 2 +-
.../storage/PersistMultiThreadTest.java | 5 +
.../core/paging/impl/PagingStoreImplTest.java | 6 +
.../tests/unit/util/FakePagingManager.java | 54 +-
56 files changed, 8383 insertions(+), 7388 deletions(-)
----------------------------------------------------------------------
[6/7] activemq-artemis git commit: ARTEMIS-581 Implement max disk
usage, and global-max-size
Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/test/java/org/apache/activemq/artemis/core/server/files/FileMoveManagerTest.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/core/server/files/FileMoveManagerTest.java b/artemis-server/src/test/java/org/apache/activemq/artemis/core/server/files/FileMoveManagerTest.java
new file mode 100644
index 0000000..7353b47
--- /dev/null
+++ b/artemis-server/src/test/java/org/apache/activemq/artemis/core/server/files/FileMoveManagerTest.java
@@ -0,0 +1,346 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.artemis.core.server.files;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.core.paging.PagingStore;
+import org.apache.activemq.artemis.core.paging.impl.PagingManagerImpl;
+import org.apache.activemq.artemis.core.paging.impl.PagingStoreFactoryNIO;
+import org.apache.activemq.artemis.core.persistence.StorageManager;
+import org.apache.activemq.artemis.core.persistence.impl.nullpm.NullStorageManager;
+import org.apache.activemq.artemis.core.settings.HierarchicalRepository;
+import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy;
+import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
+import org.apache.activemq.artemis.core.settings.impl.HierarchicalObjectRepository;
+import org.apache.activemq.artemis.logs.AssertionLoggerHandler;
+import org.apache.activemq.artemis.tests.util.ThreadLeakCheckRule;
+import org.apache.activemq.artemis.utils.OrderedExecutorFactory;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+public class FileMoveManagerTest {
+
+ @Rule
+ public TemporaryFolder temporaryFolder;
+
+ @Rule
+ public ThreadLeakCheckRule leakCheckRule = new ThreadLeakCheckRule();
+
+ private File dataLocation;
+ private FileMoveManager manager;
+
+
+ @Before
+ public void setUp() {
+ dataLocation = new File(temporaryFolder.getRoot(), "data");
+ dataLocation.mkdirs();
+ manager = new FileMoveManager(dataLocation, 10);
+ }
+
+
+ public FileMoveManagerTest() {
+ File parent = new File("./target/tmp");
+ parent.mkdirs();
+ temporaryFolder = new TemporaryFolder(parent);
+ }
+
+ @Test
+ public void testBackupFiles() {
+ int[] originalFiles = new int[12];
+ int count = 0;
+
+ // It will fake folders creation
+ for (int i = 0; i < 12; i++) {
+ originalFiles[count++] = i;
+ File bkp = new File(dataLocation, FileMoveManager.PREFIX + i);
+ bkp.mkdirs();
+ }
+
+ Assert.assertEquals(12, manager.getFolders().length);
+ Assert.assertEquals(12, manager.getNumberOfFolders());
+
+
+ assertIDs(originalFiles, manager.getIDlist());
+ }
+
+ @Test
+ public void testMinMax() {
+ int[] originalFiles = new int[12];
+ int count = 0;
+
+ // It will fake folders creation
+ for (int i = 0; i < 5; i++) {
+ originalFiles[count++] = i;
+ File bkp = new File(dataLocation, FileMoveManager.PREFIX + i);
+ bkp.mkdirs();
+ }
+
+ // simulates a hole where someone removed a folder by hand
+
+ // It will fake folders creation
+ for (int i = 7; i < 14; i++) {
+ originalFiles[count++] = i;
+ File bkp = new File(dataLocation, FileMoveManager.PREFIX + i);
+ bkp.mkdirs();
+ }
+
+ Assert.assertEquals(12, manager.getFolders().length);
+ Assert.assertEquals(12, manager.getNumberOfFolders());
+
+ int[] ids = manager.getIDlist();
+
+ assertIDs(originalFiles, ids);
+
+ Assert.assertEquals(0, manager.getMinID());
+ Assert.assertEquals(13, manager.getMaxID());
+
+ manager.setMaxFolders(3).checkOldFolders();
+
+ Assert.assertEquals(3, manager.getNumberOfFolders());
+ Assert.assertEquals(13, manager.getMaxID());
+ Assert.assertEquals(11, manager.getMinID());
+
+ }
+
+ @Test
+ public void testGarbageCreated() {
+ // I'm pretending an admin created a folder here
+ File garbage = new File(dataLocation, "bkp.zzz");
+ garbage.mkdirs();
+
+ testMinMax();
+
+ resetTmp();
+ // the admin renamed a folder maybe
+ garbage = new File(dataLocation, "bkp.001.old");
+ garbage.mkdirs();
+
+ resetTmp();
+
+ // the admin renamed a folder maybe
+ garbage = new File(dataLocation, "bkp.1.5");
+ garbage.mkdirs();
+
+ testMinMax();
+ }
+
+
+ @Test
+ public void testNoFolders() {
+ Assert.assertEquals(0, manager.getFolders().length);
+ Assert.assertEquals(0, manager.getNumberOfFolders());
+
+ Assert.assertTrue(dataLocation.delete());
+
+ Assert.assertEquals(0, manager.getFolders().length);
+ Assert.assertEquals(0, manager.getNumberOfFolders());
+ }
+
+
+ @Test
+ public void testNoFiles() throws Exception {
+ // nothing to be moved, so why to do a backup
+ manager.doMove();
+
+ Assert.assertEquals(0, manager.getNumberOfFolders());
+ }
+
+ @Test
+ public void testMoveFiles() throws Exception {
+ manager.setMaxFolders(3);
+
+ for (int bkp = 1; bkp <= 10; bkp++) {
+ for (int i = 0; i < 100; i++) {
+ createFile(dataLocation, i);
+ }
+
+ manager.doMove();
+
+ // We will always have maximum of 3 folders
+ Assert.assertEquals(Math.min(bkp, manager.getMaxFolders()), manager.getNumberOfFolders());
+
+ File bkpFolder = manager.getFolder(bkp);
+
+ FileMoveManager bkp1Manager = new FileMoveManager(bkpFolder, 10);
+ String[] filesAfterMove = bkp1Manager.getFiles();
+
+ for (String file : filesAfterMove) {
+ checkFile(bkpFolder, file);
+ }
+ }
+
+ Assert.assertEquals(manager.getMaxFolders(), manager.getNumberOfFolders());
+
+ manager.setMaxFolders(0).checkOldFolders();
+
+ Assert.assertEquals(3, manager.getNumberOfFolders());
+
+ manager.setMaxFolders(1).checkOldFolders();
+ Assert.assertEquals(1, manager.getNumberOfFolders());
+
+
+ Assert.assertEquals(10, manager.getMaxID());
+ Assert.assertEquals(10, manager.getMinID());
+ }
+
+
+ @Test
+ public void testMoveFolders() throws Exception {
+ manager.setMaxFolders(3);
+
+ int NUMBER_OF_FOLDERS = 10;
+ int FILES_PER_FOLDER = 10;
+
+ for (int bkp = 1; bkp <= 10; bkp++) {
+ for (int f = 0; f < NUMBER_OF_FOLDERS; f++) {
+ File folderF = new File(dataLocation, "folder" + f);
+ folderF.mkdirs();
+
+ // FILES_PER_FOLDER + f, I'm just creating more files as f grows.
+ // this is just to make each folder unique somehow
+ for (int i = 0; i < FILES_PER_FOLDER + f; i++) {
+ createFile(folderF, i);
+ }
+ }
+
+ manager.doMove();
+
+ // We will always have maximum of 3 folders
+ Assert.assertEquals(Math.min(bkp, manager.getMaxFolders()), manager.getNumberOfFolders());
+
+ File bkpFolder = manager.getFolder(bkp);
+
+ for (int f = 0; f < NUMBER_OF_FOLDERS; f++) {
+ File fileTmp = new File(bkpFolder, "folder" + f);
+
+ String[] filesOnFolder = fileTmp.list();
+
+ Assert.assertEquals(FILES_PER_FOLDER + f, filesOnFolder.length);
+
+ for (String file : filesOnFolder) {
+ checkFile(fileTmp, file);
+ }
+ }
+
+ }
+
+ Assert.assertEquals(manager.getMaxFolders(), manager.getNumberOfFolders());
+
+ manager.setMaxFolders(0).checkOldFolders();
+
+ Assert.assertEquals(3, manager.getNumberOfFolders());
+
+ manager.setMaxFolders(1).checkOldFolders();
+ Assert.assertEquals(1, manager.getNumberOfFolders());
+
+
+ Assert.assertEquals(10, manager.getMaxID());
+ Assert.assertEquals(10, manager.getMinID());
+ }
+
+ @Test
+ public void testMoveOverPaging() throws Exception {
+ AssertionLoggerHandler.startCapture();
+
+ ExecutorService threadPool = Executors.newCachedThreadPool();
+ try {
+ manager.setMaxFolders(3);
+ for (int i = 1; i <= 10; i++) {
+ HierarchicalRepository<AddressSettings> addressSettings = new HierarchicalObjectRepository<>();
+ AddressSettings settings = new AddressSettings();
+ settings.setAddressFullMessagePolicy(AddressFullMessagePolicy.PAGE);
+ addressSettings.setDefault(settings);
+
+ final StorageManager storageManager = new NullStorageManager();
+
+ PagingStoreFactoryNIO storeFactory =
+ new PagingStoreFactoryNIO(storageManager, dataLocation, 100, null,
+ new OrderedExecutorFactory(threadPool), true, null);
+
+ PagingManagerImpl managerImpl = new PagingManagerImpl(storeFactory, addressSettings, -1);
+
+ managerImpl.start();
+
+ PagingStore store = managerImpl.getPageStore(new SimpleString("simple-test"));
+
+ store.startPaging();
+
+ store.stop();
+
+ managerImpl.stop();
+
+ manager.doMove();
+
+ Assert.assertEquals(Math.min(i, manager.getMaxFolders()), manager.getNumberOfFolders());
+ }
+
+ Assert.assertFalse("The loggers are complaining about address.txt", AssertionLoggerHandler.findText("address.txt"));
+ }
+ finally {
+ AssertionLoggerHandler.stopCapture();
+ threadPool.shutdown();
+ }
+
+
+ }
+
+
+ private void assertIDs(int[] originalFiles, int[] ids) {
+ Assert.assertEquals(originalFiles.length, ids.length);
+ for (int i = 0; i < ids.length; i++) {
+ Assert.assertEquals(originalFiles[i], ids[i]);
+ }
+ }
+
+ private void resetTmp() {
+ temporaryFolder.delete();
+ temporaryFolder.getRoot().mkdirs();
+ Assert.assertEquals(0, manager.getNumberOfFolders());
+ }
+
+ private void createFile(File folder, int i) throws FileNotFoundException {
+ File dataFile = new File(folder, i + ".jrn");
+ PrintWriter outData = new PrintWriter(new FileOutputStream(dataFile));
+ outData.print(i);
+ outData.close();
+ }
+
+ private void checkFile(File bkpFolder, String file) throws IOException {
+ File fileRead = new File(bkpFolder, file);
+ InputStreamReader stream = new InputStreamReader(new FileInputStream(fileRead));
+ BufferedReader reader = new BufferedReader(stream);
+ String valueRead = reader.readLine();
+ int id = Integer.parseInt(file.substring(0, file.indexOf('.')));
+ Assert.assertEquals("content of the file wasn't the expected", id, Integer.parseInt(valueRead));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/test/java/org/apache/activemq/artemis/core/server/files/FileStoreMonitorTest.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/core/server/files/FileStoreMonitorTest.java b/artemis-server/src/test/java/org/apache/activemq/artemis/core/server/files/FileStoreMonitorTest.java
new file mode 100644
index 0000000..9a47d05
--- /dev/null
+++ b/artemis-server/src/test/java/org/apache/activemq/artemis/core/server/files/FileStoreMonitorTest.java
@@ -0,0 +1,161 @@
+/**
+ * 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.artemis.core.server.files;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.nio.file.FileStore;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
+import org.apache.activemq.artemis.utils.ReusableLatch;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class FileStoreMonitorTest extends ActiveMQTestBase {
+
+ private ScheduledExecutorService scheduledExecutorService;
+
+ @Before
+ public void startScheduled() {
+ scheduledExecutorService = new ScheduledThreadPoolExecutor(5);
+ }
+
+ @After
+ public void stopScheduled() {
+ scheduledExecutorService.shutdown();
+ scheduledExecutorService = null;
+ }
+
+ @Test
+ public void testSimpleTick() throws Exception {
+ File garbageFile = new File(getTestDirfile(), "garbage.bin");
+ FileOutputStream garbage = new FileOutputStream(garbageFile);
+ BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(garbage);
+ PrintStream out = new PrintStream(bufferedOutputStream);
+
+ // This is just to make sure there is at least something on the device.
+ // If the testsuite is running with an empty tempFS, it would return 0 and the assertion would fail.
+ for (int i = 0; i < 100; i++) {
+ out.println("Garbage " + i);
+ }
+
+ bufferedOutputStream.close();
+
+ final AtomicInteger over = new AtomicInteger(0);
+ final AtomicInteger under = new AtomicInteger(0);
+ final AtomicInteger tick = new AtomicInteger(0);
+
+ FileStoreMonitor.Callback callback = new FileStoreMonitor.Callback() {
+ @Override
+ public void tick(FileStore store, double usage) {
+ tick.incrementAndGet();
+ System.out.println("tick:: " + store + " usage::" + usage);
+ }
+
+ @Override
+ public void over(FileStore store, double usage) {
+ over.incrementAndGet();
+ System.out.println("over:: " + store + " usage::" + usage);
+ }
+
+ @Override
+ public void under(FileStore store, double usage) {
+ under.incrementAndGet();
+ System.out.println("under:: " + store + " usage::" + usage);
+ }
+ };
+
+ final AtomicBoolean fakeReturn = new AtomicBoolean(false);
+ FileStoreMonitor storeMonitor = new FileStoreMonitor(scheduledExecutorService, 100, TimeUnit.MILLISECONDS, 0.999) {
+ @Override
+ protected double calculateUsage(FileStore store) throws IOException {
+ if (fakeReturn.get()) {
+ return 1f;
+ }
+ else {
+ return super.calculateUsage(store);
+ }
+ }
+ };
+ storeMonitor.addCallback(callback);
+ storeMonitor.addStore(getTestDirfile());
+
+ storeMonitor.tick();
+
+ Assert.assertEquals(0, over.get());
+ Assert.assertEquals(1, tick.get());
+ Assert.assertEquals(1, under.get());
+
+ fakeReturn.set(true);
+
+ storeMonitor.tick();
+
+ Assert.assertEquals(1, over.get());
+ Assert.assertEquals(2, tick.get());
+ Assert.assertEquals(1, under.get());
+ }
+
+ @Test
+ public void testScheduler() throws Exception {
+
+ FileStoreMonitor storeMonitor = new FileStoreMonitor(scheduledExecutorService, 20, TimeUnit.MILLISECONDS, 0.9);
+
+ final ReusableLatch latch = new ReusableLatch(5);
+ storeMonitor.addStore(getTestDirfile());
+ storeMonitor.addCallback(new FileStoreMonitor.Callback() {
+ @Override
+ public void tick(FileStore store, double usage) {
+ System.out.println("TickS::" + usage);
+ latch.countDown();
+ }
+
+ @Override
+ public void over(FileStore store, double usage) {
+
+ }
+
+ @Override
+ public void under(FileStore store, double usage) {
+
+ }
+ });
+ storeMonitor.start();
+
+
+ Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
+
+ storeMonitor.stop();
+
+ latch.setCount(1);
+
+ Assert.assertFalse(latch.await(100, TimeUnit.MILLISECONDS));
+
+// FileStoreMonitor monitor = new FileStoreMonitor()
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/FileMoveManagerTest.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/FileMoveManagerTest.java b/artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/FileMoveManagerTest.java
deleted file mode 100644
index 0935c38..0000000
--- a/artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/FileMoveManagerTest.java
+++ /dev/null
@@ -1,346 +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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.artemis.core.server.impl;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.PrintWriter;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.paging.PagingStore;
-import org.apache.activemq.artemis.core.paging.impl.PagingManagerImpl;
-import org.apache.activemq.artemis.core.paging.impl.PagingStoreFactoryNIO;
-import org.apache.activemq.artemis.core.persistence.StorageManager;
-import org.apache.activemq.artemis.core.persistence.impl.nullpm.NullStorageManager;
-import org.apache.activemq.artemis.core.settings.HierarchicalRepository;
-import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy;
-import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
-import org.apache.activemq.artemis.core.settings.impl.HierarchicalObjectRepository;
-import org.apache.activemq.artemis.logs.AssertionLoggerHandler;
-import org.apache.activemq.artemis.tests.util.ThreadLeakCheckRule;
-import org.apache.activemq.artemis.utils.OrderedExecutorFactory;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-public class FileMoveManagerTest {
-
- @Rule
- public TemporaryFolder temporaryFolder;
-
- @Rule
- public ThreadLeakCheckRule leakCheckRule = new ThreadLeakCheckRule();
-
- private File dataLocation;
- private FileMoveManager manager;
-
-
- @Before
- public void setUp() {
- dataLocation = new File(temporaryFolder.getRoot(), "data");
- dataLocation.mkdirs();
- manager = new FileMoveManager(dataLocation, 10);
- }
-
-
- public FileMoveManagerTest() {
- File parent = new File("./target/tmp");
- parent.mkdirs();
- temporaryFolder = new TemporaryFolder(parent);
- }
-
- @Test
- public void testBackupFiles() {
- int[] originalFiles = new int[12];
- int count = 0;
-
- // It will fake folders creation
- for (int i = 0; i < 12; i++) {
- originalFiles[count++] = i;
- File bkp = new File(dataLocation, FileMoveManager.PREFIX + i);
- bkp.mkdirs();
- }
-
- Assert.assertEquals(12, manager.getFolders().length);
- Assert.assertEquals(12, manager.getNumberOfFolders());
-
-
- assertIDs(originalFiles, manager.getIDlist());
- }
-
- @Test
- public void testMinMax() {
- int[] originalFiles = new int[12];
- int count = 0;
-
- // It will fake folders creation
- for (int i = 0; i < 5; i++) {
- originalFiles[count++] = i;
- File bkp = new File(dataLocation, FileMoveManager.PREFIX + i);
- bkp.mkdirs();
- }
-
- // simulates a hole where someone removed a folder by hand
-
- // It will fake folders creation
- for (int i = 7; i < 14; i++) {
- originalFiles[count++] = i;
- File bkp = new File(dataLocation, FileMoveManager.PREFIX + i);
- bkp.mkdirs();
- }
-
- Assert.assertEquals(12, manager.getFolders().length);
- Assert.assertEquals(12, manager.getNumberOfFolders());
-
- int[] ids = manager.getIDlist();
-
- assertIDs(originalFiles, ids);
-
- Assert.assertEquals(0, manager.getMinID());
- Assert.assertEquals(13, manager.getMaxID());
-
- manager.setMaxFolders(3).checkOldFolders();
-
- Assert.assertEquals(3, manager.getNumberOfFolders());
- Assert.assertEquals(13, manager.getMaxID());
- Assert.assertEquals(11, manager.getMinID());
-
- }
-
- @Test
- public void testGarbageCreated() {
- // I'm pretending an admin created a folder here
- File garbage = new File(dataLocation, "bkp.zzz");
- garbage.mkdirs();
-
- testMinMax();
-
- resetTmp();
- // the admin renamed a folder maybe
- garbage = new File(dataLocation, "bkp.001.old");
- garbage.mkdirs();
-
- resetTmp();
-
- // the admin renamed a folder maybe
- garbage = new File(dataLocation, "bkp.1.5");
- garbage.mkdirs();
-
- testMinMax();
- }
-
-
- @Test
- public void testNoFolders() {
- Assert.assertEquals(0, manager.getFolders().length);
- Assert.assertEquals(0, manager.getNumberOfFolders());
-
- Assert.assertTrue(dataLocation.delete());
-
- Assert.assertEquals(0, manager.getFolders().length);
- Assert.assertEquals(0, manager.getNumberOfFolders());
- }
-
-
- @Test
- public void testNoFiles() throws Exception {
- // nothing to be moved, so why to do a backup
- manager.doMove();
-
- Assert.assertEquals(0, manager.getNumberOfFolders());
- }
-
- @Test
- public void testMoveFiles() throws Exception {
- manager.setMaxFolders(3);
-
- for (int bkp = 1; bkp <= 10; bkp++) {
- for (int i = 0; i < 100; i++) {
- createFile(dataLocation, i);
- }
-
- manager.doMove();
-
- // We will always have maximum of 3 folders
- Assert.assertEquals(Math.min(bkp, manager.getMaxFolders()), manager.getNumberOfFolders());
-
- File bkpFolder = manager.getFolder(bkp);
-
- FileMoveManager bkp1Manager = new FileMoveManager(bkpFolder, 10);
- String[] filesAfterMove = bkp1Manager.getFiles();
-
- for (String file : filesAfterMove) {
- checkFile(bkpFolder, file);
- }
- }
-
- Assert.assertEquals(manager.getMaxFolders(), manager.getNumberOfFolders());
-
- manager.setMaxFolders(0).checkOldFolders();
-
- Assert.assertEquals(3, manager.getNumberOfFolders());
-
- manager.setMaxFolders(1).checkOldFolders();
- Assert.assertEquals(1, manager.getNumberOfFolders());
-
-
- Assert.assertEquals(10, manager.getMaxID());
- Assert.assertEquals(10, manager.getMinID());
- }
-
-
- @Test
- public void testMoveFolders() throws Exception {
- manager.setMaxFolders(3);
-
- int NUMBER_OF_FOLDERS = 10;
- int FILES_PER_FOLDER = 10;
-
- for (int bkp = 1; bkp <= 10; bkp++) {
- for (int f = 0; f < NUMBER_OF_FOLDERS; f++) {
- File folderF = new File(dataLocation, "folder" + f);
- folderF.mkdirs();
-
- // FILES_PER_FOLDER + f, I'm just creating more files as f grows.
- // this is just to make each folder unique somehow
- for (int i = 0; i < FILES_PER_FOLDER + f; i++) {
- createFile(folderF, i);
- }
- }
-
- manager.doMove();
-
- // We will always have maximum of 3 folders
- Assert.assertEquals(Math.min(bkp, manager.getMaxFolders()), manager.getNumberOfFolders());
-
- File bkpFolder = manager.getFolder(bkp);
-
- for (int f = 0; f < NUMBER_OF_FOLDERS; f++) {
- File fileTmp = new File(bkpFolder, "folder" + f);
-
- String[] filesOnFolder = fileTmp.list();
-
- Assert.assertEquals(FILES_PER_FOLDER + f, filesOnFolder.length);
-
- for (String file : filesOnFolder) {
- checkFile(fileTmp, file);
- }
- }
-
- }
-
- Assert.assertEquals(manager.getMaxFolders(), manager.getNumberOfFolders());
-
- manager.setMaxFolders(0).checkOldFolders();
-
- Assert.assertEquals(3, manager.getNumberOfFolders());
-
- manager.setMaxFolders(1).checkOldFolders();
- Assert.assertEquals(1, manager.getNumberOfFolders());
-
-
- Assert.assertEquals(10, manager.getMaxID());
- Assert.assertEquals(10, manager.getMinID());
- }
-
- @Test
- public void testMoveOverPaging() throws Exception {
- AssertionLoggerHandler.startCapture();
-
- ExecutorService threadPool = Executors.newCachedThreadPool();
- try {
- manager.setMaxFolders(3);
- for (int i = 1; i <= 10; i++) {
- HierarchicalRepository<AddressSettings> addressSettings = new HierarchicalObjectRepository<>();
- AddressSettings settings = new AddressSettings();
- settings.setAddressFullMessagePolicy(AddressFullMessagePolicy.PAGE);
- addressSettings.setDefault(settings);
-
- final StorageManager storageManager = new NullStorageManager();
-
- PagingStoreFactoryNIO storeFactory =
- new PagingStoreFactoryNIO(storageManager, dataLocation, 100, null,
- new OrderedExecutorFactory(threadPool), true, null);
-
- PagingManagerImpl managerImpl = new PagingManagerImpl(storeFactory, addressSettings);
-
- managerImpl.start();
-
- PagingStore store = managerImpl.getPageStore(new SimpleString("simple-test"));
-
- store.startPaging();
-
- store.stop();
-
- managerImpl.stop();
-
- manager.doMove();
-
- Assert.assertEquals(Math.min(i, manager.getMaxFolders()), manager.getNumberOfFolders());
- }
-
- Assert.assertFalse("The loggers are complaining about address.txt", AssertionLoggerHandler.findText("address.txt"));
- }
- finally {
- AssertionLoggerHandler.stopCapture();
- threadPool.shutdown();
- }
-
-
- }
-
-
- private void assertIDs(int[] originalFiles, int[] ids) {
- Assert.assertEquals(originalFiles.length, ids.length);
- for (int i = 0; i < ids.length; i++) {
- Assert.assertEquals(originalFiles[i], ids[i]);
- }
- }
-
- private void resetTmp() {
- temporaryFolder.delete();
- temporaryFolder.getRoot().mkdirs();
- Assert.assertEquals(0, manager.getNumberOfFolders());
- }
-
- private void createFile(File folder, int i) throws FileNotFoundException {
- File dataFile = new File(folder, i + ".jrn");
- PrintWriter outData = new PrintWriter(new FileOutputStream(dataFile));
- outData.print(i);
- outData.close();
- }
-
- private void checkFile(File bkpFolder, String file) throws IOException {
- File fileRead = new File(bkpFolder, file);
- InputStreamReader stream = new InputStreamReader(new FileInputStream(fileRead));
- BufferedReader reader = new BufferedReader(stream);
- String valueRead = reader.readLine();
- int id = Integer.parseInt(file.substring(0, file.indexOf('.')));
- Assert.assertEquals("content of the file wasn't the expected", id, Integer.parseInt(valueRead));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/test/java/org/apache/activemq/artemis/core/transaction/impl/TransactionImplTest.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/core/transaction/impl/TransactionImplTest.java b/artemis-server/src/test/java/org/apache/activemq/artemis/core/transaction/impl/TransactionImplTest.java
index 9a66610..2a6837f 100644
--- a/artemis-server/src/test/java/org/apache/activemq/artemis/core/transaction/impl/TransactionImplTest.java
+++ b/artemis-server/src/test/java/org/apache/activemq/artemis/core/transaction/impl/TransactionImplTest.java
@@ -52,6 +52,7 @@ import org.apache.activemq.artemis.core.server.LargeServerMessage;
import org.apache.activemq.artemis.core.server.MessageReference;
import org.apache.activemq.artemis.core.server.RouteContextList;
import org.apache.activemq.artemis.core.server.ServerMessage;
+import org.apache.activemq.artemis.core.server.files.FileStoreMonitor;
import org.apache.activemq.artemis.core.server.group.impl.GroupBinding;
import org.apache.activemq.artemis.core.server.impl.JournalLoader;
import org.apache.activemq.artemis.core.transaction.ResourceManager;
@@ -300,6 +301,11 @@ public class TransactionImplTest extends ActiveMQTestBase {
}
@Override
+ public void injectMonitor(FileStoreMonitor monitor) throws Exception {
+
+ }
+
+ @Override
public void confirmPendingLargeMessage(long recordID) throws Exception {
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java b/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java
index 8cfc31b..b5fe7b0 100644
--- a/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java
+++ b/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java
@@ -1420,10 +1420,16 @@ public abstract class ActiveMQTestBase extends Assert {
}
}
}
-
protected final ActiveMQServer createServer(final boolean realFiles,
final Configuration configuration,
final long pageSize,
+ final long maxAddressSize) {
+ return createServer(realFiles, configuration, pageSize, maxAddressSize, (Map<String, AddressSettings>)null);
+ }
+
+ protected ActiveMQServer createServer(final boolean realFiles,
+ final Configuration configuration,
+ final long pageSize,
final long maxAddressSize,
final Map<String, AddressSettings> settings) {
ActiveMQServer server = addServer(ActiveMQServers.newActiveMQServer(configuration, realFiles));
@@ -1458,20 +1464,20 @@ public abstract class ActiveMQTestBase extends Assert {
}
protected final ActiveMQServer createServer(final boolean realFiles, final boolean netty) throws Exception {
- return createServer(realFiles, createDefaultConfig(netty), AddressSettings.DEFAULT_PAGE_SIZE, AddressSettings.DEFAULT_MAX_SIZE_BYTES, new HashMap<String, AddressSettings>());
+ return createServer(realFiles, createDefaultConfig(netty), AddressSettings.DEFAULT_PAGE_SIZE, AddressSettings.DEFAULT_MAX_SIZE_BYTES);
}
protected ActiveMQServer createServer(final boolean realFiles, final Configuration configuration) {
- return createServer(realFiles, configuration, AddressSettings.DEFAULT_PAGE_SIZE, AddressSettings.DEFAULT_MAX_SIZE_BYTES, new HashMap<String, AddressSettings>());
+ return createServer(realFiles, configuration, AddressSettings.DEFAULT_PAGE_SIZE, AddressSettings.DEFAULT_MAX_SIZE_BYTES);
}
protected final ActiveMQServer createServer(final Configuration configuration) {
- return createServer(configuration.isPersistenceEnabled(), configuration, AddressSettings.DEFAULT_PAGE_SIZE, AddressSettings.DEFAULT_MAX_SIZE_BYTES, new HashMap<String, AddressSettings>());
+ return createServer(configuration.isPersistenceEnabled(), configuration, AddressSettings.DEFAULT_PAGE_SIZE, AddressSettings.DEFAULT_MAX_SIZE_BYTES);
}
protected ActiveMQServer createServer(final boolean realFiles, boolean isNetty, StoreConfiguration.StoreType storeType) throws Exception {
Configuration configuration = storeType == StoreConfiguration.StoreType.DATABASE ? createDefaultJDBCConfig(isNetty) : createDefaultConfig(isNetty);
- return createServer(realFiles, configuration, AddressSettings.DEFAULT_PAGE_SIZE, AddressSettings.DEFAULT_MAX_SIZE_BYTES, new HashMap<String, AddressSettings>());
+ return createServer(realFiles, configuration, AddressSettings.DEFAULT_PAGE_SIZE, AddressSettings.DEFAULT_MAX_SIZE_BYTES);
}
protected ActiveMQServer createInVMFailoverServer(final boolean realFiles,
@@ -1559,7 +1565,7 @@ public abstract class ActiveMQTestBase extends Assert {
final boolean realFiles,
final Map<String, Object> params) throws Exception {
String acceptor = isNetty ? NETTY_ACCEPTOR_FACTORY : INVM_ACCEPTOR_FACTORY;
- return createServer(realFiles, createDefaultConfig(index, params, acceptor), -1, -1, new HashMap<String, AddressSettings>());
+ return createServer(realFiles, createDefaultConfig(index, params, acceptor), -1, -1);
}
protected ActiveMQServer createClusteredServerWithParams(final boolean isNetty,
@@ -1568,7 +1574,7 @@ public abstract class ActiveMQTestBase extends Assert {
final int pageSize,
final int maxAddressSize,
final Map<String, Object> params) throws Exception {
- return createServer(realFiles, createDefaultConfig(index, params, (isNetty ? NETTY_ACCEPTOR_FACTORY : INVM_ACCEPTOR_FACTORY)), pageSize, maxAddressSize, new HashMap<String, AddressSettings>());
+ return createServer(realFiles, createDefaultConfig(index, params, (isNetty ? NETTY_ACCEPTOR_FACTORY : INVM_ACCEPTOR_FACTORY)), pageSize, maxAddressSize);
}
protected ServerLocator createFactory(final boolean isNetty) throws Exception {
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/test/resources/ConfigurationTest-full-config.xml
----------------------------------------------------------------------
diff --git a/artemis-server/src/test/resources/ConfigurationTest-full-config.xml b/artemis-server/src/test/resources/ConfigurationTest-full-config.xml
index 78d55c2..cc11029 100644
--- a/artemis-server/src/test/resources/ConfigurationTest-full-config.xml
+++ b/artemis-server/src/test/resources/ConfigurationTest-full-config.xml
@@ -53,6 +53,9 @@
<populate-validated-user>true</populate-validated-user>
<connection-ttl-check-interval>98765</connection-ttl-check-interval>
<configuration-file-refresh-period>1234567</configuration-file-refresh-period>
+ <global-max-size>1234567</global-max-size>
+ <max-disk-usage>37</max-disk-usage>
+ <disk-scan-period>123</disk-scan-period>
<remoting-incoming-interceptors>
<class-name>org.apache.activemq.artemis.tests.unit.core.config.impl.TestInterceptor1</class-name>
<class-name>org.apache.activemq.artemis.tests.unit.core.config.impl.TestInterceptor2</class-name>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/docs/user-manual/en/configuration-index.md
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/configuration-index.md b/docs/user-manual/en/configuration-index.md
index 6660b5a..b9a49fb 100644
--- a/docs/user-manual/en/configuration-index.md
+++ b/docs/user-manual/en/configuration-index.md
@@ -41,7 +41,9 @@ Name | Description
[create-bindings-dir](persistence.md "Configuring the bindings journal") | true means that the server will create the bindings directory on start up. Default=true
[create-journal-dir](persistence.md) | true means that the journal directory will be created. Default=true
[discovery-groups](clusters.md "Clusters") | [a list of discovery-group](#discovery-group-type)
+[disk-scan-period](paging.md#max-disk-usage) | The interval where the disk is scanned for percentual usage. Default=5000 ms.
[diverts](diverts.md "Diverting and Splitting Message Flows") | [a list of diverts to use](#divert-type)
+[global-max-size](paging.md#global-max-size) | The amount in bytes before all addresses are considered full
[graceful-shutdown-enabled](graceful-shutdown.md "Graceful Server Shutdown") | true means that graceful shutdown is enabled. Default=true
[graceful-shutdown-timeout](graceful-shutdown.md "Graceful Server Shutdown") | Timeout on waitin for clients to disconnect before server shutdown. Default=-1
[grouping-handler](message-grouping.md "Message Grouping") | Message Group configuration
@@ -65,6 +67,7 @@ Name | Description
[management-notification-address](management.md "Configuring The Core Management Notification Address") | the name of the address that consumers bind to receive management notifications. Default=activemq.notifications
[mask-password](configuration-index.md "Using Masked Passwords in Configuration Files") | This option controls whether passwords in server configuration need be masked. If set to "true" the passwords are masked. Default=false
[max-saved-replicated-journals-size]() | This specifies how many times a replicated backup server can restart after moving its files on start. Once there are this number of backup journal files the server will stop permanently after if fails back. Default=2
+[max-disk-usage](paging.md#max-disk-usage) | The max percentage of data we should use from disks. The System will block while the disk is full. Default=100
[memory-measure-interval](perf-tuning.md) | frequency to sample JVM memory in ms (or -1 to disable memory sampling). Default=-1
[memory-warning-threshold](perf-tuning.md) | Percentage of available memory which will trigger a warning log. Default=25
[message-counter-enabled](management.md "Configuring Message Counters") | true means that message counters are enabled. Default=false
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/docs/user-manual/en/paging.md
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/paging.md b/docs/user-manual/en/paging.md
index 6b5ddb5..a001a6f 100644
--- a/docs/user-manual/en/paging.md
+++ b/docs/user-manual/en/paging.md
@@ -11,8 +11,7 @@ a low memory footprint.
Apache ActiveMQ Artemis will start paging messages to disk, when the size of all
messages in memory for an address exceeds a configured maximum size.
-By default, Apache ActiveMQ Artemis does not page messages - this must be explicitly
-configured to activate it.
+The default configuration from Artemis has destinations with paging.
## Page Files
@@ -121,6 +120,12 @@ This is the list of available parameters on the address settings.
</tbody>
</table>
+## Global Max Size
+
+Beyond the max-size-bytes on the address you can also set the global-max-size on the main configuration. If you set max-size-bytes = -1 on paging the global-max-size can still be used.
+
+When you have more messages than what is configured global-max-size any new produced message will make that destination to go through its paging policy.
+
## Dropping messages
Instead of paging messages when the max size is reached, an address can
@@ -181,6 +186,12 @@ In this example all the other 9 queues will be consuming messages from
the page system. This may cause performance issues if this is an
undesirable state.
+## Max Disk Usage
+
+The System will perform scans on the disk to determine if the disk is beyond a configured limit.
+These are configured through 'max-disk-usage' in percentage. Once that limit is reached any
+message will be blocked. (unless the protocol doesn't support flow control on which case there will be an exception thrown and the connection for those clients dropped).
+
## Example
See the [examples](examples.md) chapter for an example which shows how to use paging with Apache ActiveMQ Artemis.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/HangConsumerTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/HangConsumerTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/HangConsumerTest.java
index bbccbf1..89432d9 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/HangConsumerTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/HangConsumerTest.java
@@ -588,7 +588,7 @@ public class HangConsumerTest extends ActiveMQTestBase {
SessionCallback callback,
OperationContext context,
boolean autoCreateQueue) throws Exception {
- return new ServerSessionImpl(name, username, password, validatedUser, minLargeMessageSize, autoCommitSends, autoCommitAcks, preAcknowledge, getConfiguration().isPersistDeliveryCountBeforeDelivery(), xa, connection, getStorageManager(), getPostOffice(), getResourceManager(), getSecurityStore(), getManagementService(), this, getConfiguration().getManagementAddress(), defaultAddress == null ? null : new SimpleString(defaultAddress), new MyCallback(callback), context, null);
+ return new ServerSessionImpl(name, username, password, validatedUser, minLargeMessageSize, autoCommitSends, autoCommitAcks, preAcknowledge, getConfiguration().isPersistDeliveryCountBeforeDelivery(), xa, connection, getStorageManager(), getPostOffice(), getResourceManager(), getSecurityStore(), getManagementService(), this, getConfiguration().getManagementAddress(), defaultAddress == null ? null : new SimpleString(defaultAddress), new MyCallback(callback), context, null, getPagingManager());
}
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LargeMessageTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LargeMessageTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LargeMessageTest.java
index abcf195..cd9978f 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LargeMessageTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/LargeMessageTest.java
@@ -57,7 +57,7 @@ import org.junit.Test;
public class LargeMessageTest extends LargeMessageTestBase {
- static final int RECEIVE_WAIT_TIME = 10000;
+ private static final int RECEIVE_WAIT_TIME = 10000;
private final IntegrationTestLogger log = IntegrationTestLogger.LOGGER;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/PagingOrderTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/PagingOrderTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/PagingOrderTest.java
deleted file mode 100644
index 8f87803..0000000
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/PagingOrderTest.java
+++ /dev/null
@@ -1,714 +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.artemis.tests.integration.client;
-
-import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
-import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.api.core.TransportConfiguration;
-import org.apache.activemq.artemis.api.core.client.ClientConsumer;
-import org.apache.activemq.artemis.api.core.client.ClientMessage;
-import org.apache.activemq.artemis.api.core.client.ClientProducer;
-import org.apache.activemq.artemis.api.core.client.ClientSession;
-import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
-import org.apache.activemq.artemis.api.core.client.ServerLocator;
-import org.apache.activemq.artemis.api.jms.ActiveMQJMSClient;
-import org.apache.activemq.artemis.api.jms.JMSFactoryType;
-import org.apache.activemq.artemis.core.config.Configuration;
-import org.apache.activemq.artemis.core.paging.PagingStore;
-import org.apache.activemq.artemis.core.postoffice.Binding;
-import org.apache.activemq.artemis.core.postoffice.Bindings;
-import org.apache.activemq.artemis.core.postoffice.impl.LocalQueueBinding;
-import org.apache.activemq.artemis.core.registry.JndiBindingRegistry;
-import org.apache.activemq.artemis.core.server.ActiveMQServer;
-import org.apache.activemq.artemis.core.server.Queue;
-import org.apache.activemq.artemis.core.server.impl.QueueImpl;
-import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy;
-import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
-import org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory;
-import org.apache.activemq.artemis.jms.server.impl.JMSServerManagerImpl;
-import org.apache.activemq.artemis.tests.unit.util.InVMNamingContext;
-import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.junit.Test;
-
-import javax.jms.BytesMessage;
-import javax.jms.Connection;
-import javax.jms.DeliveryMode;
-import javax.jms.MessageProducer;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-import javax.jms.Topic;
-import java.nio.ByteBuffer;
-import java.util.HashMap;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * A PagingOrderTest. PagingTest has a lot of tests already. I decided to create a newer one more
- * specialized on Ordering and counters
- */
-public class PagingOrderTest extends ActiveMQTestBase {
-
- private static final int PAGE_MAX = 100 * 1024;
-
- private static final int PAGE_SIZE = 10 * 1024;
-
- // Attributes ----------------------------------------------------
-
- // Static --------------------------------------------------------
-
- static final SimpleString ADDRESS = new SimpleString("SimpleAddress");
-
- private Connection conn;
-
- @Test
- public void testOrder1() throws Throwable {
- boolean persistentMessages = true;
-
- Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
-
- ActiveMQServer server = createServer(true, config, PAGE_SIZE, PAGE_MAX, new HashMap<String, AddressSettings>());
-
- server.start();
-
- final int messageSize = 1024;
-
- final int numberOfMessages = 500;
-
- ServerLocator locator = createInVMNonHALocator().setClientFailureCheckPeriod(1000).setConnectionTTL(2000).setReconnectAttempts(0).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setConsumerWindowSize(1024 * 1024);
-
- ClientSessionFactory sf = createSessionFactory(locator);
-
- ClientSession session = sf.createSession(false, false, false);
-
- server.createQueue(ADDRESS, ADDRESS, null, true, false);
-
- ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
-
- byte[] body = new byte[messageSize];
-
- ByteBuffer bb = ByteBuffer.wrap(body);
-
- for (int j = 1; j <= messageSize; j++) {
- bb.put(getSamplebyte(j));
- }
-
- for (int i = 0; i < numberOfMessages; i++) {
- ClientMessage message = session.createMessage(persistentMessages);
-
- ActiveMQBuffer bodyLocal = message.getBodyBuffer();
-
- bodyLocal.writeBytes(body);
-
- message.putIntProperty(new SimpleString("id"), i);
-
- producer.send(message);
- if (i % 1000 == 0) {
- session.commit();
- }
- }
-
- session.commit();
-
- session.close();
-
- session = sf.createSession(true, true, 0);
-
- session.start();
-
- ClientConsumer consumer = session.createConsumer(ADDRESS);
-
- for (int i = 0; i < numberOfMessages / 2; i++) {
- ClientMessage message = consumer.receive(5000);
- assertNotNull(message);
- assertEquals(i, message.getIntProperty("id").intValue());
-
- if (i < 100) {
- // Do not consume the last one so we could restart
- message.acknowledge();
- }
- }
-
- session.close();
-
- sf.close();
- sf = createSessionFactory(locator);
-
- session = sf.createSession(true, true, 0);
-
- session.start();
-
- consumer = session.createConsumer(ADDRESS);
-
- for (int i = 100; i < numberOfMessages; i++) {
- ClientMessage message = consumer.receive(5000);
- assertNotNull(message);
- assertEquals(i, message.getIntProperty("id").intValue());
- message.acknowledge();
- }
-
- session.close();
- }
-
- @Test
- public void testPageCounter() throws Throwable {
- boolean persistentMessages = true;
-
- Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
-
- ActiveMQServer server = createServer(true, config, PAGE_SIZE, PAGE_MAX, new HashMap<String, AddressSettings>());
-
- server.start();
-
- final int messageSize = 1024;
-
- final int numberOfMessages = 500;
-
- ServerLocator locator = createInVMNonHALocator().setClientFailureCheckPeriod(1000).setConnectionTTL(2000).setReconnectAttempts(0).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setConsumerWindowSize(1024 * 1024);
-
- ClientSessionFactory sf = createSessionFactory(locator);
-
- ClientSession session = sf.createSession(false, false, false);
-
- Queue q1 = server.createQueue(ADDRESS, ADDRESS, null, true, false);
-
- Queue q2 = server.createQueue(ADDRESS, new SimpleString("inactive"), null, true, false);
-
- ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
-
- byte[] body = new byte[messageSize];
-
- ByteBuffer bb = ByteBuffer.wrap(body);
-
- for (int j = 1; j <= messageSize; j++) {
- bb.put(getSamplebyte(j));
- }
-
- final AtomicInteger errors = new AtomicInteger(0);
-
- Thread t1 = new Thread() {
- @Override
- public void run() {
- try {
- ServerLocator sl = createInVMNonHALocator();
- ClientSessionFactory sf = sl.createSessionFactory();
- ClientSession sess = sf.createSession(true, true, 0);
- sess.start();
- ClientConsumer cons = sess.createConsumer(ADDRESS);
- for (int i = 0; i < numberOfMessages; i++) {
- ClientMessage msg = cons.receive(5000);
- assertNotNull(msg);
- assertEquals(i, msg.getIntProperty("id").intValue());
- msg.acknowledge();
- }
-
- assertNull(cons.receiveImmediate());
- sess.close();
- sl.close();
- }
- catch (Throwable e) {
- e.printStackTrace();
- errors.incrementAndGet();
- }
-
- }
- };
-
- t1.start();
-
- for (int i = 0; i < numberOfMessages; i++) {
- ClientMessage message = session.createMessage(persistentMessages);
-
- ActiveMQBuffer bodyLocal = message.getBodyBuffer();
-
- bodyLocal.writeBytes(body);
-
- message.putIntProperty(new SimpleString("id"), i);
-
- producer.send(message);
- if (i % 20 == 0) {
- session.commit();
- }
- }
-
- session.commit();
-
- t1.join();
-
- assertEquals(0, errors.get());
-
- assertEquals(numberOfMessages, getMessageCount(q2));
- assertEquals(numberOfMessages, getMessagesAdded(q2));
- assertEquals(0, getMessageCount(q1));
- assertEquals(numberOfMessages, getMessagesAdded(q1));
-
- session.close();
- sf.close();
- locator.close();
-
- server.stop();
-
- server.start();
-
- Bindings bindings = server.getPostOffice().getBindingsForAddress(ADDRESS);
-
- q1 = null;
- q2 = null;
-
- for (Binding bind : bindings.getBindings()) {
- if (bind instanceof LocalQueueBinding) {
- LocalQueueBinding qb = (LocalQueueBinding) bind;
- if (qb.getQueue().getName().equals(ADDRESS)) {
- q1 = qb.getQueue();
- }
-
- if (qb.getQueue().getName().equals(new SimpleString("inactive"))) {
- q2 = qb.getQueue();
- }
- }
- }
-
- assertNotNull(q1);
-
- assertNotNull(q2);
-
- assertEquals("q2 msg count", numberOfMessages, getMessageCount(q2));
- assertEquals("q2 msgs added", numberOfMessages, getMessagesAdded(q2));
- assertEquals("q1 msg count", 0, getMessageCount(q1));
- // 0, since nothing was sent to the queue after the server was restarted
- assertEquals("q1 msgs added", 0, getMessagesAdded(q1));
-
- }
-
- @Test
- public void testPageCounter2() throws Throwable {
- boolean persistentMessages = true;
-
- Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
-
- ActiveMQServer server = createServer(true, config, PAGE_SIZE, PAGE_MAX, new HashMap<String, AddressSettings>());
-
- server.start();
-
- final int messageSize = 1024;
-
- final int numberOfMessages = 500;
-
- ServerLocator locator = createInVMNonHALocator().setClientFailureCheckPeriod(1000).setConnectionTTL(2000).setReconnectAttempts(0).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setConsumerWindowSize(1024 * 1024);
-
- ClientSessionFactory sf = createSessionFactory(locator);
-
- ClientSession session = sf.createSession(false, false, false);
-
- Queue q1 = server.createQueue(ADDRESS, ADDRESS, null, true, false);
-
- Queue q2 = server.createQueue(ADDRESS, new SimpleString("inactive"), null, true, false);
-
- ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
-
- byte[] body = new byte[messageSize];
-
- ByteBuffer bb = ByteBuffer.wrap(body);
-
- for (int j = 1; j <= messageSize; j++) {
- bb.put(getSamplebyte(j));
- }
-
- final AtomicInteger errors = new AtomicInteger(0);
-
- Thread t1 = new Thread() {
- @Override
- public void run() {
- try {
- ServerLocator sl = createInVMNonHALocator();
- ClientSessionFactory sf = sl.createSessionFactory();
- ClientSession sess = sf.createSession(true, true, 0);
- sess.start();
- ClientConsumer cons = sess.createConsumer(ADDRESS);
- for (int i = 0; i < 100; i++) {
- ClientMessage msg = cons.receive(5000);
- assertNotNull(msg);
- assertEquals(i, msg.getIntProperty("id").intValue());
- msg.acknowledge();
- }
- sess.close();
- sl.close();
- }
- catch (Throwable e) {
- e.printStackTrace();
- errors.incrementAndGet();
- }
-
- }
- };
-
- for (int i = 0; i < numberOfMessages; i++) {
- ClientMessage message = session.createMessage(persistentMessages);
-
- ActiveMQBuffer bodyLocal = message.getBodyBuffer();
-
- bodyLocal.writeBytes(body);
-
- message.putIntProperty(new SimpleString("id"), i);
-
- producer.send(message);
- if (i % 20 == 0) {
- session.commit();
- }
- }
-
- session.commit();
-
- t1.start();
- t1.join();
-
- assertEquals(0, errors.get());
- long timeout = System.currentTimeMillis() + 10000;
- while (numberOfMessages - 100 != getMessageCount(q1) && System.currentTimeMillis() < timeout) {
- Thread.sleep(500);
-
- }
-
- assertEquals(numberOfMessages, getMessageCount(q2));
- assertEquals(numberOfMessages, getMessagesAdded(q2));
- assertEquals(numberOfMessages - 100, getMessageCount(q1));
- }
-
- @Test
- public void testOrderOverRollback() throws Throwable {
- boolean persistentMessages = true;
-
- Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
-
- ActiveMQServer server = createServer(true, config, PAGE_SIZE, PAGE_MAX, new HashMap<String, AddressSettings>());
-
- server.start();
-
- final int messageSize = 1024;
-
- final int numberOfMessages = 3000;
-
- ServerLocator locator = createInVMNonHALocator().setClientFailureCheckPeriod(1000).setConnectionTTL(2000).setReconnectAttempts(0).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setConsumerWindowSize(1024 * 1024);
-
- ClientSessionFactory sf = createSessionFactory(locator);
-
- ClientSession session = sf.createSession(false, false, false);
-
- server.createQueue(ADDRESS, ADDRESS, null, true, false);
-
- ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
-
- byte[] body = new byte[messageSize];
-
- ByteBuffer bb = ByteBuffer.wrap(body);
-
- for (int j = 1; j <= messageSize; j++) {
- bb.put(getSamplebyte(j));
- }
-
- for (int i = 0; i < numberOfMessages; i++) {
- ClientMessage message = session.createMessage(persistentMessages);
-
- ActiveMQBuffer bodyLocal = message.getBodyBuffer();
-
- bodyLocal.writeBytes(body);
-
- message.putIntProperty(new SimpleString("id"), i);
-
- producer.send(message);
- if (i % 1000 == 0) {
- session.commit();
- }
- }
-
- session.commit();
-
- session.close();
-
- session = sf.createSession(false, false, 0);
-
- session.start();
-
- ClientConsumer consumer = session.createConsumer(ADDRESS);
-
- for (int i = 0; i < numberOfMessages / 2; i++) {
- ClientMessage message = consumer.receive(5000);
- assertNotNull(message);
- assertEquals(i, message.getIntProperty("id").intValue());
- message.acknowledge();
- }
-
- session.rollback();
-
- session.close();
-
- session = sf.createSession(false, false, 0);
-
- session.start();
-
- consumer = session.createConsumer(ADDRESS);
-
- for (int i = 0; i < numberOfMessages; i++) {
- ClientMessage message = consumer.receive(5000);
- assertNotNull(message);
- assertEquals(i, message.getIntProperty("id").intValue());
- message.acknowledge();
- }
-
- session.commit();
- }
-
- @Test
- public void testOrderOverRollback2() throws Throwable {
- boolean persistentMessages = true;
-
- Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
-
- ActiveMQServer server = createServer(true, config, PAGE_SIZE, PAGE_MAX, new HashMap<String, AddressSettings>());
-
- server.start();
-
- final int messageSize = 1024;
-
- final int numberOfMessages = 200;
-
- ServerLocator locator = createInVMNonHALocator().setClientFailureCheckPeriod(1000).setConnectionTTL(2000).setReconnectAttempts(0).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setConsumerWindowSize(0);
-
- ClientSessionFactory sf = createSessionFactory(locator);
-
- ClientSession session = sf.createSession(false, false, false);
-
- QueueImpl queue = (QueueImpl) server.createQueue(ADDRESS, ADDRESS, null, true, false);
-
- ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
-
- byte[] body = new byte[messageSize];
-
- ByteBuffer bb = ByteBuffer.wrap(body);
-
- for (int j = 1; j <= messageSize; j++) {
- bb.put(getSamplebyte(j));
- }
-
- for (int i = 0; i < numberOfMessages; i++) {
- ClientMessage message = session.createMessage(persistentMessages);
-
- ActiveMQBuffer bodyLocal = message.getBodyBuffer();
-
- bodyLocal.writeBytes(body);
-
- message.putIntProperty(new SimpleString("id"), i);
-
- producer.send(message);
- if (i % 1000 == 0) {
- session.commit();
- }
- }
-
- session.commit();
-
- session.close();
-
- session = sf.createSession(false, false, 0);
-
- session.start();
-
- ClientConsumer consumer = session.createConsumer(ADDRESS);
-
- // number of references without paging
- int numberOfRefs = queue.getNumberOfReferences();
-
- // consume all non-paged references
- for (int ref = 0; ref < numberOfRefs; ref++) {
- ClientMessage msg = consumer.receive(5000);
- assertNotNull(msg);
- msg.acknowledge();
- }
-
- session.commit();
-
- session.close();
-
- session = sf.createSession(false, false, 0);
-
- session.start();
-
- consumer = session.createConsumer(ADDRESS);
-
- ClientMessage msg = consumer.receive(5000);
- assertNotNull(msg);
- int msgIDRolledBack = msg.getIntProperty("id").intValue();
- msg.acknowledge();
-
- session.rollback();
-
- msg = consumer.receive(5000);
-
- assertNotNull(msg);
-
- assertEquals(msgIDRolledBack, msg.getIntProperty("id").intValue());
-
- session.rollback();
-
- session.close();
-
- sf.close();
- locator.close();
-
- server.stop();
-
- server.start();
-
- locator = createInVMNonHALocator().setClientFailureCheckPeriod(1000).setConnectionTTL(2000).setReconnectAttempts(0).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setConsumerWindowSize(0);
-
- sf = createSessionFactory(locator);
-
- session = sf.createSession(false, false, 0);
-
- session.start();
-
- consumer = session.createConsumer(ADDRESS);
-
- for (int i = msgIDRolledBack; i < numberOfMessages; i++) {
- ClientMessage message = consumer.receive(5000);
- assertNotNull(message);
- assertEquals(i, message.getIntProperty("id").intValue());
- message.acknowledge();
- }
-
- session.commit();
-
- session.close();
- }
-
- @Test
- public void testPagingOverCreatedDestinationTopics() throws Exception {
-
- Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
-
- ActiveMQServer server = createServer(true, config, PAGE_SIZE, -1, new HashMap<String, AddressSettings>());
-
- JMSServerManagerImpl jmsServer = new JMSServerManagerImpl(server);
- InVMNamingContext context = new InVMNamingContext();
- jmsServer.setRegistry(new JndiBindingRegistry(context));
- jmsServer.start();
-
- jmsServer.createTopic(true, "tt", "/topic/TT");
-
- server.getActiveMQServerControl().addAddressSettings("jms.topic.TT", "DLQ", "DLQ", -1, false, 5, 1024 * 1024, 1024 * 10, 5, 5, 1, 1000, 0, false, "PAGE", -1, 10, "KILL", true, true, true, true);
-
- ActiveMQJMSConnectionFactory cf = (ActiveMQJMSConnectionFactory) ActiveMQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, new TransportConfiguration(INVM_CONNECTOR_FACTORY));
-
- Connection conn = cf.createConnection();
- conn.setClientID("tst");
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Topic topic = (Topic) context.lookup("/topic/TT");
- sess.createDurableSubscriber(topic, "t1");
-
- MessageProducer prod = sess.createProducer(topic);
- prod.setDeliveryMode(DeliveryMode.PERSISTENT);
- TextMessage txt = sess.createTextMessage("TST");
- prod.send(txt);
-
- PagingStore store = server.getPagingManager().getPageStore(new SimpleString("jms.topic.TT"));
-
- assertEquals(1024 * 1024, store.getMaxSize());
- assertEquals(10 * 1024, store.getPageSizeBytes());
-
- jmsServer.stop();
-
- server = createServer(true, config, PAGE_SIZE, -1, new HashMap<String, AddressSettings>());
-
- jmsServer = new JMSServerManagerImpl(server);
- context = new InVMNamingContext();
- jmsServer.setRegistry(new JndiBindingRegistry(context));
- jmsServer.start();
-
- AddressSettings settings = server.getAddressSettingsRepository().getMatch("jms.topic.TT");
-
- assertEquals(1024 * 1024, settings.getMaxSizeBytes());
- assertEquals(10 * 1024, settings.getPageSizeBytes());
- assertEquals(AddressFullMessagePolicy.PAGE, settings.getAddressFullMessagePolicy());
-
- store = server.getPagingManager().getPageStore(new SimpleString("TT"));
-
- conn.close();
-
- server.stop();
-
- }
-
- @Test
- public void testPagingOverCreatedDestinationQueues() throws Exception {
-
- Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
-
- ActiveMQServer server = createServer(true, config, -1, -1, new HashMap<String, AddressSettings>());
- server.getAddressSettingsRepository().getMatch("#").setAddressFullMessagePolicy(AddressFullMessagePolicy.BLOCK);
-
- JMSServerManagerImpl jmsServer = new JMSServerManagerImpl(server);
- InVMNamingContext context = new InVMNamingContext();
- jmsServer.setRegistry(new JndiBindingRegistry(context));
- jmsServer.start();
-
- server.getActiveMQServerControl().addAddressSettings("jms.queue.Q1", "DLQ", "DLQ", -1, false, 5, 100 * 1024, 10 * 1024, 5, 5, 1, 1000, 0, false, "PAGE", -1, 10, "KILL", true, true, true, true);
-
- jmsServer.createQueue(true, "Q1", null, true, "/queue/Q1");
-
- ActiveMQJMSConnectionFactory cf = (ActiveMQJMSConnectionFactory) ActiveMQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, new TransportConfiguration(INVM_CONNECTOR_FACTORY));
-
- conn = cf.createConnection();
- conn.setClientID("tst");
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
- javax.jms.Queue queue = (javax.jms.Queue) context.lookup("/queue/Q1");
-
- MessageProducer prod = sess.createProducer(queue);
- prod.setDeliveryMode(DeliveryMode.PERSISTENT);
- BytesMessage bmt = sess.createBytesMessage();
-
- bmt.writeBytes(new byte[1024]);
-
- for (int i = 0; i < 500; i++) {
- prod.send(bmt);
- }
-
- PagingStore store = server.getPagingManager().getPageStore(new SimpleString("jms.queue.Q1"));
-
- assertEquals(100 * 1024, store.getMaxSize());
- assertEquals(10 * 1024, store.getPageSizeBytes());
- assertEquals(AddressFullMessagePolicy.PAGE, store.getAddressFullMessagePolicy());
-
- jmsServer.stop();
-
- server = createServer(true, config, -1, -1, new HashMap<String, AddressSettings>());
- server.getAddressSettingsRepository().getMatch("#").setAddressFullMessagePolicy(AddressFullMessagePolicy.BLOCK);
-
- jmsServer = new JMSServerManagerImpl(server);
- context = new InVMNamingContext();
- jmsServer.setRegistry(new JndiBindingRegistry(context));
- jmsServer.start();
-
- AddressSettings settings = server.getAddressSettingsRepository().getMatch("jms.queue.Q1");
-
- assertEquals(100 * 1024, settings.getMaxSizeBytes());
- assertEquals(10 * 1024, settings.getPageSizeBytes());
- assertEquals(AddressFullMessagePolicy.PAGE, settings.getAddressFullMessagePolicy());
-
- store = server.getPagingManager().getPageStore(new SimpleString("jms.queue.Q1"));
- assertEquals(100 * 1024, store.getMaxSize());
- assertEquals(10 * 1024, store.getPageSizeBytes());
- assertEquals(AddressFullMessagePolicy.PAGE, store.getAddressFullMessagePolicy());
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/PagingSyncTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/PagingSyncTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/PagingSyncTest.java
deleted file mode 100644
index 635a911..0000000
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/PagingSyncTest.java
+++ /dev/null
@@ -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.artemis.tests.integration.client;
-
-import java.nio.ByteBuffer;
-import java.util.HashMap;
-
-import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
-import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.api.core.client.ClientMessage;
-import org.apache.activemq.artemis.api.core.client.ClientProducer;
-import org.apache.activemq.artemis.api.core.client.ClientSession;
-import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
-import org.apache.activemq.artemis.api.core.client.ServerLocator;
-import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.apache.activemq.artemis.core.config.Configuration;
-import org.apache.activemq.artemis.core.server.ActiveMQServer;
-import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
-import org.junit.Test;
-
-/**
- * A PagingOrderTest.
- * <br>
- * PagingTest has a lot of tests already. I decided to create a newer one more specialized on Ordering and counters
- */
-public class PagingSyncTest extends ActiveMQTestBase {
-
- private static final int PAGE_MAX = 100 * 1024;
-
- private static final int PAGE_SIZE = 10 * 1024;
-
- // Attributes ----------------------------------------------------
-
- // Static --------------------------------------------------------
-
- static final SimpleString ADDRESS = new SimpleString("SimpleAddress");
-
- @Test
- public void testOrder1() throws Throwable {
- boolean persistentMessages = true;
-
- Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
-
- ActiveMQServer server = createServer(true, config, PAGE_SIZE, PAGE_MAX, new HashMap<String, AddressSettings>());
-
- server.start();
-
- final int messageSize = 1024;
-
- final int numberOfMessages = 500;
-
- ServerLocator locator = createInVMNonHALocator().setClientFailureCheckPeriod(1000).setConnectionTTL(2000).setReconnectAttempts(0).setBlockOnNonDurableSend(false).setBlockOnDurableSend(false).setBlockOnAcknowledge(false).setConsumerWindowSize(1024 * 1024);
-
- ClientSessionFactory sf = createSessionFactory(locator);
-
- ClientSession session = sf.createSession(false, false, false);
-
- server.createQueue(ADDRESS, ADDRESS, null, true, false);
-
- ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
-
- byte[] body = new byte[messageSize];
-
- ByteBuffer bb = ByteBuffer.wrap(body);
-
- for (int j = 1; j <= messageSize; j++) {
- bb.put(getSamplebyte(j));
- }
-
- for (int i = 0; i < numberOfMessages; i++) {
- ClientMessage message = session.createMessage(persistentMessages);
-
- ActiveMQBuffer bodyLocal = message.getBodyBuffer();
-
- bodyLocal.writeBytes(body);
-
- message.putIntProperty(new SimpleString("id"), i);
-
- producer.send(message);
- }
-
- session.commit();
-
- session.close();
- }
-
- // Package protected ---------------------------------------------
-
- // Protected -----------------------------------------------------
-
- // Private -------------------------------------------------------
-
- // Inner classes -------------------------------------------------
-
-}
[5/7] activemq-artemis git commit: ARTEMIS-581 Implement max disk
usage, and global-max-size
Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/PagingTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/PagingTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/PagingTest.java
deleted file mode 100644
index 14d9da6..0000000
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/PagingTest.java
+++ /dev/null
@@ -1,5734 +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.artemis.tests.integration.client;
-
-import javax.transaction.xa.XAResource;
-import javax.transaction.xa.Xid;
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.lang.management.ManagementFactory;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
-import org.apache.activemq.artemis.api.core.ActiveMQException;
-import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
-import org.apache.activemq.artemis.api.core.Message;
-import org.apache.activemq.artemis.api.core.Pair;
-import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.api.core.client.ClientConsumer;
-import org.apache.activemq.artemis.api.core.client.ClientMessage;
-import org.apache.activemq.artemis.api.core.client.ClientProducer;
-import org.apache.activemq.artemis.api.core.client.ClientSession;
-import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
-import org.apache.activemq.artemis.api.core.client.MessageHandler;
-import org.apache.activemq.artemis.api.core.client.ServerLocator;
-import org.apache.activemq.artemis.core.client.impl.ClientConsumerInternal;
-import org.apache.activemq.artemis.core.config.Configuration;
-import org.apache.activemq.artemis.core.config.DivertConfiguration;
-import org.apache.activemq.artemis.core.filter.Filter;
-import org.apache.activemq.artemis.core.io.IOCallback;
-import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
-import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
-import org.apache.activemq.artemis.core.journal.RecordInfo;
-import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
-import org.apache.activemq.artemis.core.paging.PagingManager;
-import org.apache.activemq.artemis.core.paging.PagingStore;
-import org.apache.activemq.artemis.core.paging.cursor.PageCursorProvider;
-import org.apache.activemq.artemis.core.paging.cursor.impl.PageCursorProviderImpl;
-import org.apache.activemq.artemis.core.paging.cursor.impl.PagePositionImpl;
-import org.apache.activemq.artemis.core.paging.impl.PagingStoreFactoryNIO;
-import org.apache.activemq.artemis.core.persistence.OperationContext;
-import org.apache.activemq.artemis.core.persistence.StorageManager;
-import org.apache.activemq.artemis.core.persistence.impl.journal.AckDescribe;
-import org.apache.activemq.artemis.core.persistence.impl.journal.DescribeJournal;
-import org.apache.activemq.artemis.core.persistence.impl.journal.DescribeJournal.ReferenceDescribe;
-import org.apache.activemq.artemis.core.persistence.impl.journal.JournalRecordIds;
-import org.apache.activemq.artemis.core.persistence.impl.journal.OperationContextImpl;
-import org.apache.activemq.artemis.core.server.ActiveMQServer;
-import org.apache.activemq.artemis.core.server.Queue;
-import org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl;
-import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy;
-import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
-import org.apache.activemq.artemis.logs.AssertionLoggerHandler;
-import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManagerImpl;
-import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger;
-import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.jboss.logging.Logger;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class PagingTest extends ActiveMQTestBase {
-
- private static final Logger logger = Logger.getLogger(PagingTest.class);
-
- private ServerLocator locator;
- private ActiveMQServer server;
- private ClientSessionFactory sf;
- static final int MESSAGE_SIZE = 1024; // 1k
-
- private static final IntegrationTestLogger log = IntegrationTestLogger.LOGGER;
-
- private static final int RECEIVE_TIMEOUT = 5000;
-
- private static final int PAGE_MAX = 100 * 1024;
-
- private static final int PAGE_SIZE = 10 * 1024;
-
- static final SimpleString ADDRESS = new SimpleString("SimpleAddress");
-
- @Override
- @Before
- public void setUp() throws Exception {
- super.setUp();
- locator = createInVMNonHALocator();
- }
-
- @Test
- public void testPageOnLargeMessageMultipleQueues() throws Exception {
- Configuration config = createDefaultInVMConfig();
-
- final int PAGE_MAX = 20 * 1024;
-
- final int PAGE_SIZE = 10 * 1024;
-
- HashMap<String, AddressSettings> map = new HashMap<>();
-
- AddressSettings value = new AddressSettings();
- map.put(ADDRESS.toString(), value);
- ActiveMQServer server = createServer(true, config, PAGE_SIZE, PAGE_MAX, map);
- server.start();
-
- final int numberOfBytes = 1024;
-
- locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
-
- ClientSessionFactory sf = addSessionFactory(createSessionFactory(locator));
-
- ClientSession session = sf.createSession(null, null, false, true, true, false, 0);
-
- session.createQueue(ADDRESS, ADDRESS.concat("-0"), null, true);
- session.createQueue(ADDRESS, ADDRESS.concat("-1"), null, true);
-
- ClientProducer producer = session.createProducer(ADDRESS);
-
- ClientMessage message = null;
-
- for (int i = 0; i < 201; i++) {
- message = session.createMessage(true);
-
- message.getBodyBuffer().writerIndex(0);
-
- message.getBodyBuffer().writeBytes(new byte[numberOfBytes]);
-
- for (int j = 1; j <= numberOfBytes; j++) {
- message.getBodyBuffer().writeInt(j);
- }
-
- producer.send(message);
- }
-
- session.close();
-
- server.stop();
-
- server = createServer(true, config, PAGE_SIZE, PAGE_MAX, map);
- server.start();
-
- sf = createSessionFactory(locator);
-
- for (int ad = 0; ad < 2; ad++) {
- session = sf.createSession(false, false, false);
-
- ClientConsumer consumer = session.createConsumer(ADDRESS.concat("-" + ad));
-
- session.start();
-
- for (int i = 0; i < 201; i++) {
- ClientMessage message2 = consumer.receive(LargeMessageTest.RECEIVE_WAIT_TIME);
-
- Assert.assertNotNull(message2);
-
- message2.acknowledge();
-
- Assert.assertNotNull(message2);
- }
-
- if (ad > -1) {
- session.commit();
- }
- else {
- session.rollback();
- for (int i = 0; i < 100; i++) {
- ClientMessage message2 = consumer.receive(LargeMessageTest.RECEIVE_WAIT_TIME);
-
- Assert.assertNotNull(message2);
-
- message2.acknowledge();
-
- Assert.assertNotNull(message2);
- }
- session.commit();
-
- }
-
- consumer.close();
-
- session.close();
- }
- }
-
- @Test
- public void testPageCleanup() throws Exception {
- clearDataRecreateServerDirs();
-
- Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
-
- server.start();
-
- final int numberOfMessages = 5000;
-
- locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
-
- sf = createSessionFactory(locator);
-
- ClientSession session = sf.createSession(false, false, false);
-
- session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
-
- ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
-
- ClientMessage message = null;
-
- byte[] body = new byte[MESSAGE_SIZE];
-
- ByteBuffer bb = ByteBuffer.wrap(body);
-
- for (int j = 1; j <= MESSAGE_SIZE; j++) {
- bb.put(getSamplebyte(j));
- }
-
- for (int i = 0; i < numberOfMessages; i++) {
- message = session.createMessage(true);
-
- ActiveMQBuffer bodyLocal = message.getBodyBuffer();
-
- bodyLocal.writeBytes(body);
-
- producer.send(message);
- if (i % 1000 == 0) {
- session.commit();
- }
- }
- session.commit();
- producer.close();
- session.close();
-
- session = sf.createSession(false, false, false);
- producer = session.createProducer(PagingTest.ADDRESS);
- producer.send(session.createMessage(true));
- session.rollback();
- producer.close();
- session.close();
-
- session = sf.createSession(false, false, false);
- producer = session.createProducer(PagingTest.ADDRESS);
-
- for (int i = 0; i < numberOfMessages; i++) {
- message = session.createMessage(true);
-
- ActiveMQBuffer bodyLocal = message.getBodyBuffer();
-
- bodyLocal.writeBytes(body);
-
- producer.send(message);
- if (i % 1000 == 0) {
- session.commit();
- }
- }
- session.commit();
- producer.close();
- session.close();
- //System.out.println("Just sent " + numberOfMessages + " messages.");
-
- Queue queue = server.locateQueue(PagingTest.ADDRESS);
-
- session = sf.createSession(false, false, false);
-
- session.start();
-
- assertEquals(numberOfMessages * 2, getMessageCount(queue));
-
- // The consumer has to be created after the getMessageCount(queue) assertion
- // otherwise delivery could alter the messagecount and give us a false failure
- ClientConsumer consumer = session.createConsumer(PagingTest.ADDRESS);
- ClientMessage msg = null;
-
- for (int i = 0; i < numberOfMessages * 2; i++) {
- msg = consumer.receive(1000);
- assertNotNull(msg);
- msg.acknowledge();
- if (i % 500 == 0) {
- session.commit();
- }
- }
- session.commit();
- consumer.close();
- session.close();
-
- sf.close();
-
- locator.close();
-
- assertEquals(0, getMessageCount(queue));
-
- waitForNotPaging(queue);
-
- server.stop();
-
- HashMap<Integer, AtomicInteger> counts = countJournalLivingRecords(server.getConfiguration());
-
- AtomicInteger pgComplete = counts.get((int) JournalRecordIds.PAGE_CURSOR_COMPLETE);
-
- assertTrue(pgComplete == null || pgComplete.get() == 0);
-
- System.out.println("pgComplete = " + pgComplete);
- }
-
- // First page is complete but it wasn't deleted
- @Test
- public void testFirstPageCompleteNotDeleted() throws Exception {
- clearDataRecreateServerDirs();
-
- Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
-
- server.start();
-
- final int numberOfMessages = 20;
-
- locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
-
- sf = createSessionFactory(locator);
-
- ClientSession session = sf.createSession(false, true, true);
-
- Queue queue = server.createQueue(ADDRESS, ADDRESS, null, true, false);
-
- queue.getPageSubscription().getPagingStore().startPaging();
-
- ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
-
- ClientMessage message = null;
-
- byte[] body = new byte[MESSAGE_SIZE];
-
- ByteBuffer bb = ByteBuffer.wrap(body);
-
- for (int j = 1; j <= MESSAGE_SIZE; j++) {
- bb.put(getSamplebyte(j));
- }
-
- for (int i = 0; i < numberOfMessages; i++) {
- message = session.createMessage(true);
-
- ActiveMQBuffer bodyLocal = message.getBodyBuffer();
-
- bodyLocal.writeBytes(body);
-
- message.putIntProperty("count", i);
-
- producer.send(message);
-
- if ((i + 1) % 5 == 0) {
- session.commit();
- queue.getPageSubscription().getPagingStore().forceAnotherPage();
- }
- }
-
- session.commit();
- producer.close();
- session.close();
-
- // This will make the cursor to set the page complete and not actually delete it
- queue.getPageSubscription().getPagingStore().disableCleanup();
-
- session = sf.createSession(false, false, false);
-
- ClientConsumer consumer = session.createConsumer(ADDRESS);
- session.start();
-
- for (int i = 0; i < 5; i++) {
- ClientMessage msg = consumer.receive(2000);
- assertNotNull(msg);
- assertEquals(i, msg.getIntProperty("count").intValue());
-
- msg.individualAcknowledge();
-
- System.out.println(msg);
- }
-
- session.commit();
-
- session.close();
-
- server.stop();
-
- server.start();
-
- sf = createSessionFactory(locator);
-
- session = sf.createSession(false, false, false);
-
- consumer = session.createConsumer(ADDRESS);
- session.start();
-
- for (int i = 5; i < numberOfMessages; i++) {
- ClientMessage msg = consumer.receive(2000);
- assertNotNull(msg);
- assertEquals(i, msg.getIntProperty("count").intValue());
- msg.acknowledge();
- System.out.println(msg);
- }
-
- assertNull(consumer.receiveImmediate());
- session.commit();
-
- session.close();
- sf.close();
- locator.close();
-
- }
-
- @Test
- public void testPreparedACKAndRestart() throws Exception {
- clearDataRecreateServerDirs();
-
- Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
-
- server.start();
-
- final int numberOfMessages = 50;
-
- locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setAckBatchSize(0);
-
- sf = createSessionFactory(locator);
-
- ClientSession session = sf.createSession(false, true, true);
-
- session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
-
- Queue queue = server.locateQueue(PagingTest.ADDRESS);
-
- ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
-
- byte[] body = new byte[MESSAGE_SIZE];
-
- ByteBuffer bb = ByteBuffer.wrap(body);
-
- for (int j = 1; j <= MESSAGE_SIZE; j++) {
- bb.put(getSamplebyte(j));
- }
-
- queue.getPageSubscription().getPagingStore().startPaging();
-
- forcePage(queue);
-
- // Send many messages, 5 on each page
- for (int i = 0; i < numberOfMessages; i++) {
- ClientMessage message = session.createMessage(true);
-
- message.putIntProperty("count", i);
-
- ActiveMQBuffer bodyLocal = message.getBodyBuffer();
-
- bodyLocal.writeBytes(body);
-
- producer.send(message);
-
- if ((i + 1) % 5 == 0) {
- System.out.println("Forcing at " + i);
- session.commit();
- queue.getPageSubscription().getPagingStore().forceAnotherPage();
- }
- }
-
- session.close();
-
- session = sf.createSession(true, false, false);
-
- Xid xidConsumeNoCommit = newXID();
- session.start(xidConsumeNoCommit, XAResource.TMNOFLAGS);
-
- ClientConsumer cons = session.createConsumer(ADDRESS);
-
- session.start();
-
- // First message is consumed, prepared, will be rolled back later
- ClientMessage firstMessageConsumed = cons.receive(5000);
- assertNotNull(firstMessageConsumed);
- firstMessageConsumed.acknowledge();
-
- session.end(xidConsumeNoCommit, XAResource.TMSUCCESS);
-
- session.prepare(xidConsumeNoCommit);
-
- Xid xidConsumeCommit = newXID();
- session.start(xidConsumeCommit, XAResource.TMNOFLAGS);
-
- Xid neverCommittedXID = newXID();
-
- for (int i = 1; i < numberOfMessages; i++) {
- if (i == 20) {
- // I elected a single message to be in prepared state, it won't ever be committed
- session.end(xidConsumeCommit, XAResource.TMSUCCESS);
- session.commit(xidConsumeCommit, true);
- session.start(neverCommittedXID, XAResource.TMNOFLAGS);
- }
- ClientMessage message = cons.receive(5000);
- assertNotNull(message);
- System.out.println("ACK " + i);
- message.acknowledge();
- assertEquals(i, message.getIntProperty("count").intValue());
- if (i == 20) {
- session.end(neverCommittedXID, XAResource.TMSUCCESS);
- session.prepare(neverCommittedXID);
- xidConsumeCommit = newXID();
- session.start(xidConsumeCommit, XAResource.TMNOFLAGS);
- }
- }
-
- session.end(xidConsumeCommit, XAResource.TMSUCCESS);
-
- session.commit(xidConsumeCommit, true);
-
- session.close();
- sf.close();
-
- // Restart the server, and we expect cleanup to not destroy any page with prepared data
- server.stop();
-
- server.start();
-
- sf = createSessionFactory(locator);
-
- session = sf.createSession(false, true, true);
-
- queue = server.locateQueue(ADDRESS);
-
- assertTrue(queue.getPageSubscription().getPagingStore().isPaging());
-
- producer = session.createProducer(ADDRESS);
-
- for (int i = numberOfMessages; i < numberOfMessages * 2; i++) {
- ClientMessage message = session.createMessage(true);
-
- message.putIntProperty("count", i);
-
- ActiveMQBuffer bodyLocal = message.getBodyBuffer();
-
- bodyLocal.writeBytes(body);
-
- producer.send(message);
-
- if ((i + 1) % 5 == 0) {
- session.commit();
- queue.getPageSubscription().getPagingStore().forceAnotherPage();
- }
- }
-
- cons = session.createConsumer(ADDRESS);
-
- session.start();
-
- for (int i = numberOfMessages; i < numberOfMessages * 2; i++) {
- ClientMessage message = cons.receive(5000);
- assertNotNull(message);
- assertEquals(i, message.getIntProperty("count").intValue());
- message.acknowledge();
- }
- assertNull(cons.receiveImmediate());
- session.commit();
-
- System.out.println("count = " + getMessageCount(queue));
-
- session.commit();
-
- session.close();
-
- session = sf.createSession(true, false, false);
-
- session.rollback(xidConsumeNoCommit);
-
- session.start();
-
- xidConsumeCommit = newXID();
-
- session.start(xidConsumeCommit, XAResource.TMNOFLAGS);
- cons = session.createConsumer(ADDRESS);
-
- session.start();
-
- ClientMessage message = cons.receive(5000);
- assertNotNull(message);
- message.acknowledge();
-
- session.end(xidConsumeCommit, XAResource.TMSUCCESS);
-
- session.commit(xidConsumeCommit, true);
-
- session.close();
- }
-
- /**
- * @param queue
- * @throws InterruptedException
- */
- private void forcePage(Queue queue) throws InterruptedException {
- for (long timeout = System.currentTimeMillis() + 5000; timeout > System.currentTimeMillis() && !queue.getPageSubscription().getPagingStore().isPaging(); ) {
- Thread.sleep(10);
- }
- assertTrue(queue.getPageSubscription().getPagingStore().isPaging());
- }
-
- @Test
- public void testMoveExpire() throws Exception {
- clearDataRecreateServerDirs();
-
- Configuration config = createDefaultInVMConfig().setJournalDirectory(getJournalDir()).setJournalSyncNonTransactional(false).setJournalCompactMinFiles(0) // disable compact
- .setMessageExpiryScanPeriod(500);
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
-
- AddressSettings defaultSetting = new AddressSettings().setPageSizeBytes(PAGE_SIZE).setMaxSizeBytes(PAGE_MAX).setExpiryAddress(new SimpleString("EXP")).setAddressFullMessagePolicy(AddressFullMessagePolicy.PAGE);
-
- server.getAddressSettingsRepository().clear();
-
- server.getAddressSettingsRepository().addMatch("#", defaultSetting);
-
- server.start();
-
- final int numberOfMessages = 5000;
-
- locator = createInVMNonHALocator().setConsumerWindowSize(10 * 1024 * 1024).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
-
- ClientSessionFactory sf = locator.createSessionFactory();
-
- ClientSession session = sf.createSession(false, false, false);
-
- session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
-
- session.createQueue("EXP", "EXP", null, true);
-
- Queue queue1 = server.locateQueue(ADDRESS);
- Queue qEXP = server.locateQueue(new SimpleString("EXP"));
-
- ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
-
- final int MESSAGE_SIZE = 1024;
-
- byte[] body = new byte[MESSAGE_SIZE];
-
- ByteBuffer bb = ByteBuffer.wrap(body);
-
- for (int j = 1; j <= MESSAGE_SIZE; j++) {
- bb.put(getSamplebyte(j));
- }
-
- for (int i = 0; i < numberOfMessages; i++) {
- ClientMessage message = session.createMessage(true);
-
- if (i < 1000) {
- message.setExpiration(System.currentTimeMillis() + 1000);
- }
-
- message.putIntProperty("tst-count", i);
-
- ActiveMQBuffer bodyLocal = message.getBodyBuffer();
-
- bodyLocal.writeBytes(body);
-
- producer.send(message);
- if (i % 1000 == 0) {
- session.commit();
- }
- }
- session.commit();
- producer.close();
-
- for (long timeout = System.currentTimeMillis() + 60000; timeout > System.currentTimeMillis() && getMessageCount(qEXP) < 1000; ) {
- System.out.println("count = " + getMessageCount(qEXP));
- Thread.sleep(100);
- }
-
- assertEquals(1000, getMessageCount(qEXP));
-
- session.start();
-
- ClientConsumer consumer = session.createConsumer(ADDRESS);
-
- for (int i = 0; i < numberOfMessages - 1000; i++) {
- ClientMessage message = consumer.receive(5000);
- assertNotNull(message);
- message.acknowledge();
- assertTrue(message.getIntProperty("tst-count") >= 1000);
- }
-
- session.commit();
-
- assertNull(consumer.receiveImmediate());
-
- for (long timeout = System.currentTimeMillis() + 5000; timeout > System.currentTimeMillis() && getMessageCount(queue1) != 0; ) {
- Thread.sleep(100);
- }
- assertEquals(0, getMessageCount(queue1));
-
- consumer.close();
-
- consumer = session.createConsumer("EXP");
-
- for (int i = 0; i < 1000; i++) {
- ClientMessage message = consumer.receive(5000);
- assertNotNull(message);
- message.acknowledge();
- assertTrue(message.getIntProperty("tst-count") < 1000);
- }
-
- assertNull(consumer.receiveImmediate());
-
- // This is just to hold some messages as being delivered
- ClientConsumerInternal cons = (ClientConsumerInternal) session.createConsumer(ADDRESS);
-
- session.commit();
- producer.close();
- session.close();
-
- server.stop();
- }
-
- @Test
- public void testDeleteQueueRestart() throws Exception {
- clearDataRecreateServerDirs();
-
- Configuration config = createDefaultInVMConfig().setJournalDirectory(getJournalDir()).setJournalSyncNonTransactional(false).setJournalCompactMinFiles(0); // disable compact
-
- ActiveMQServer server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
-
- server.start();
-
- final int numberOfMessages = 5000;
-
- locator = createInVMNonHALocator().setConsumerWindowSize(10 * 1024 * 1024).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
-
- SimpleString QUEUE2 = ADDRESS.concat("-2");
-
- ClientSessionFactory sf = locator.createSessionFactory();
-
- ClientSession session = sf.createSession(false, false, false);
-
- session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
-
- session.createQueue(PagingTest.ADDRESS, QUEUE2, null, true);
-
- ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
-
- // This is just to hold some messages as being delivered
- ClientConsumerInternal cons = (ClientConsumerInternal) session.createConsumer(ADDRESS);
- ClientConsumerInternal cons2 = (ClientConsumerInternal) session.createConsumer(QUEUE2);
-
- ClientMessage message = null;
-
- byte[] body = new byte[MESSAGE_SIZE];
-
- ByteBuffer bb = ByteBuffer.wrap(body);
-
- for (int j = 1; j <= MESSAGE_SIZE; j++) {
- bb.put(getSamplebyte(j));
- }
-
- for (int i = 0; i < numberOfMessages; i++) {
- message = session.createMessage(true);
-
- ActiveMQBuffer bodyLocal = message.getBodyBuffer();
-
- bodyLocal.writeBytes(body);
-
- producer.send(message);
- if (i % 1000 == 0) {
- session.commit();
- }
- }
- session.commit();
- producer.close();
- session.start();
-
- long timeout = System.currentTimeMillis() + 30000;
-
- // I want the buffer full to make sure there are pending messages on the server's side
- while (System.currentTimeMillis() < timeout && (cons.getBufferSize() < 1000 || cons2.getBufferSize() < 1000)) {
- System.out.println("cons1 buffer = " + cons.getBufferSize() + ", cons2 buffer = " + cons2.getBufferSize());
- Thread.sleep(100);
- }
-
- assertTrue(cons.getBufferSize() >= 1000);
- assertTrue(cons2.getBufferSize() >= 1000);
-
- session.close();
-
- Queue queue = server.locateQueue(QUEUE2);
-
- long deletedQueueID = queue.getID();
-
- server.destroyQueue(QUEUE2);
-
- sf.close();
- locator.close();
- locator = null;
- sf = null;
-
- server.stop();
-
- final HashMap<Integer, AtomicInteger> recordsType = countJournal(config);
-
- for (Map.Entry<Integer, AtomicInteger> entry : recordsType.entrySet()) {
- System.out.println(entry.getKey() + "=" + entry.getValue());
- }
-
- assertNull("The system is acking page records instead of just delete data", recordsType.get(new Integer(JournalRecordIds.ACKNOWLEDGE_CURSOR)));
-
- Pair<List<RecordInfo>, List<PreparedTransactionInfo>> journalData = loadMessageJournal(config);
-
- HashSet<Long> deletedQueueReferences = new HashSet<>();
-
- for (RecordInfo info : journalData.getA()) {
- if (info.getUserRecordType() == JournalRecordIds.ADD_REF) {
- DescribeJournal.ReferenceDescribe ref = (ReferenceDescribe) DescribeJournal.newObjectEncoding(info);
-
- if (ref.refEncoding.queueID == deletedQueueID) {
- deletedQueueReferences.add(new Long(info.id));
- }
- }
- else if (info.getUserRecordType() == JournalRecordIds.ACKNOWLEDGE_REF) {
- AckDescribe ref = (AckDescribe) DescribeJournal.newObjectEncoding(info);
-
- if (ref.refEncoding.queueID == deletedQueueID) {
- deletedQueueReferences.remove(new Long(info.id));
- }
- }
- }
-
- if (!deletedQueueReferences.isEmpty()) {
- for (Long value : deletedQueueReferences) {
- System.out.println("Deleted Queue still has a reference:" + value);
- }
-
- fail("Deleted queue still have references");
- }
-
- server.start();
-
- locator = createInVMNonHALocator();
- locator.setConsumerWindowSize(10 * 1024 * 1024);
- sf = locator.createSessionFactory();
- session = sf.createSession(false, false, false);
- cons = (ClientConsumerInternal) session.createConsumer(ADDRESS);
- session.start();
-
- for (int i = 0; i < numberOfMessages; i++) {
- message = cons.receive(5000);
- assertNotNull(message);
- message.acknowledge();
- if (i % 1000 == 0) {
- session.commit();
- }
- }
- session.commit();
- producer.close();
- session.close();
-
- queue = server.locateQueue(PagingTest.ADDRESS);
-
- assertEquals(0, getMessageCount(queue));
-
- timeout = System.currentTimeMillis() + 10000;
- while (timeout > System.currentTimeMillis() && queue.getPageSubscription().getPagingStore().isPaging()) {
- Thread.sleep(100);
- }
- assertFalse(queue.getPageSubscription().getPagingStore().isPaging());
-
- server.stop();
- }
-
- @Test
- public void testPreparePersistent() throws Exception {
- clearDataRecreateServerDirs();
-
- Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
-
- server.start();
-
- final int numberOfMessages = 5000;
-
- final int numberOfTX = 10;
-
- final int messagesPerTX = numberOfMessages / numberOfTX;
-
- locator = createInVMNonHALocator();
-
- locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
-
- sf = createSessionFactory(locator);
-
- ClientSession session = sf.createSession(false, false, false);
-
- session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
-
- ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
-
- ClientMessage message = null;
-
- byte[] body = new byte[MESSAGE_SIZE];
-
- ByteBuffer bb = ByteBuffer.wrap(body);
-
- for (int j = 1; j <= MESSAGE_SIZE; j++) {
- bb.put(getSamplebyte(j));
- }
-
- for (int i = 0; i < numberOfMessages; i++) {
- message = session.createMessage(true);
-
- ActiveMQBuffer bodyLocal = message.getBodyBuffer();
-
- bodyLocal.writeBytes(body);
-
- message.putIntProperty(new SimpleString("id"), i);
-
- producer.send(message);
- if (i % 1000 == 0) {
- session.commit();
- }
- }
- session.commit();
- session.close();
- session = null;
-
- sf.close();
- locator.close();
-
- server.stop();
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
- server.start();
-
- locator = createInVMNonHALocator();
- sf = createSessionFactory(locator);
-
- Queue queue = server.locateQueue(ADDRESS);
-
- assertEquals(numberOfMessages, getMessageCount(queue));
-
- LinkedList<Xid> xids = new LinkedList<>();
-
- int msgReceived = 0;
- for (int i = 0; i < numberOfTX; i++) {
- ClientSession sessionConsumer = sf.createSession(true, false, false);
- Xid xid = newXID();
- xids.add(xid);
- sessionConsumer.start(xid, XAResource.TMNOFLAGS);
- sessionConsumer.start();
- ClientConsumer consumer = sessionConsumer.createConsumer(PagingTest.ADDRESS);
- for (int msgCount = 0; msgCount < messagesPerTX; msgCount++) {
- if (msgReceived == numberOfMessages) {
- break;
- }
- msgReceived++;
- ClientMessage msg = consumer.receive(10000);
- assertNotNull(msg);
- msg.acknowledge();
- }
- sessionConsumer.end(xid, XAResource.TMSUCCESS);
- sessionConsumer.prepare(xid);
- sessionConsumer.close();
- }
-
- ClientSession sessionCheck = sf.createSession(true, true);
-
- ClientConsumer consumer = sessionCheck.createConsumer(PagingTest.ADDRESS);
-
- assertNull(consumer.receiveImmediate());
-
- sessionCheck.close();
-
- assertEquals(numberOfMessages, getMessageCount(queue));
-
- sf.close();
- locator.close();
-
- server.stop();
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
- server.start();
-
- waitForServerToStart(server);
-
- queue = server.locateQueue(ADDRESS);
-
- locator = createInVMNonHALocator();
- sf = createSessionFactory(locator);
-
- session = sf.createSession(true, false, false);
-
- consumer = session.createConsumer(PagingTest.ADDRESS);
-
- session.start();
-
- assertEquals(numberOfMessages, getMessageCount(queue));
-
- ClientMessage msg = consumer.receive(5000);
- if (msg != null) {
- while (true) {
- ClientMessage msg2 = consumer.receive(1000);
- if (msg2 == null) {
- break;
- }
- }
- }
- assertNull(msg);
-
- for (int i = xids.size() - 1; i >= 0; i--) {
- Xid xid = xids.get(i);
- session.rollback(xid);
- }
-
- xids.clear();
-
- session.close();
-
- session = sf.createSession(false, false, false);
-
- session.start();
-
- consumer = session.createConsumer(PagingTest.ADDRESS);
-
- for (int i = 0; i < numberOfMessages; i++) {
- msg = consumer.receive(1000);
- assertNotNull(msg);
- msg.acknowledge();
-
- assertEquals(i, msg.getIntProperty("id").intValue());
-
- if (i % 500 == 0) {
- session.commit();
- }
- }
-
- session.commit();
-
- session.close();
-
- sf.close();
-
- locator.close();
-
- assertEquals(0, getMessageCount(queue));
-
- waitForNotPaging(queue);
- }
-
- @Test
- public void testSendOverBlockingNoFlowControl() throws Exception {
- clearDataRecreateServerDirs();
-
- Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
- server.getAddressSettingsRepository().getMatch("#").setAddressFullMessagePolicy(AddressFullMessagePolicy.BLOCK);
-
- server.start();
-
- final int biggerMessageSize = 10 * 1024;
-
- final int numberOfMessages = 500;
-
- locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setProducerWindowSize(-1).setMinLargeMessageSize(1024 * 1024);
-
- sf = createSessionFactory(locator);
-
- ClientSession session = sf.createSession(false, false, false);
-
- session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
-
- ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
-
- ClientMessage message = null;
-
- byte[] body = new byte[biggerMessageSize];
-
- ByteBuffer bb = ByteBuffer.wrap(body);
-
- for (int j = 1; j <= biggerMessageSize; j++) {
- bb.put(getSamplebyte(j));
- }
-
- for (int i = 0; i < numberOfMessages; i++) {
- message = session.createMessage(true);
-
- ActiveMQBuffer bodyLocal = message.getBodyBuffer();
-
- bodyLocal.writeBytes(body);
-
- message.putIntProperty(new SimpleString("id"), i);
-
- producer.send(message);
-
- if (i % 10 == 0) {
- session.commit();
- }
- }
- session.commit();
-
- session.start();
-
- ClientConsumer cons = session.createConsumer(ADDRESS);
-
- for (int i = 0; i < numberOfMessages; i++) {
- message = cons.receive(5000);
- assertNotNull(message);
- message.acknowledge();
-
- if (i % 10 == 0) {
- session.commit();
- }
- }
-
- session.commit();
-
- }
-
- @Test
- public void testReceiveImmediate() throws Exception {
- clearDataRecreateServerDirs();
-
- Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
-
- server.start();
-
- final int numberOfMessages = 1000;
-
- locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
-
- sf = createSessionFactory(locator);
-
- ClientSession session = sf.createSession(false, false, false);
-
- session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
-
- ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
-
- ClientMessage message = null;
-
- byte[] body = new byte[MESSAGE_SIZE];
-
- ByteBuffer bb = ByteBuffer.wrap(body);
-
- for (int j = 1; j <= MESSAGE_SIZE; j++) {
- bb.put(getSamplebyte(j));
- }
-
- for (int i = 0; i < numberOfMessages; i++) {
- message = session.createMessage(true);
-
- ActiveMQBuffer bodyLocal = message.getBodyBuffer();
-
- bodyLocal.writeBytes(body);
-
- message.putIntProperty(new SimpleString("id"), i);
-
- producer.send(message);
- if (i % 1000 == 0) {
- session.commit();
- }
- }
- session.commit();
- session.close();
-
- session = null;
-
- sf.close();
- locator.close();
-
- server.stop();
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
- server.start();
-
- locator = createInVMNonHALocator();
- sf = createSessionFactory(locator);
-
- Queue queue = server.locateQueue(ADDRESS);
-
- assertEquals(numberOfMessages, getMessageCount(queue));
-
- int msgReceived = 0;
- ClientSession sessionConsumer = sf.createSession(false, false, false);
- sessionConsumer.start();
- ClientConsumer consumer = sessionConsumer.createConsumer(PagingTest.ADDRESS);
- for (int msgCount = 0; msgCount < numberOfMessages; msgCount++) {
- log.info("Received " + msgCount);
- msgReceived++;
- ClientMessage msg = consumer.receiveImmediate();
- if (msg == null) {
- log.info("It's null. leaving now");
- sessionConsumer.commit();
- fail("Didn't receive a message");
- }
- msg.acknowledge();
-
- if (msgCount % 5 == 0) {
- log.info("commit");
- sessionConsumer.commit();
- }
- }
-
- sessionConsumer.commit();
-
- sessionConsumer.close();
-
- sf.close();
-
- locator.close();
-
- assertEquals(0, getMessageCount(queue));
-
- long timeout = System.currentTimeMillis() + 5000;
- while (timeout > System.currentTimeMillis() && queue.getPageSubscription().getPagingStore().isPaging()) {
- Thread.sleep(100);
- }
- assertFalse(queue.getPageSubscription().getPagingStore().isPaging());
-
- }
-
- /**
- * This test will remove all the page directories during a restart, simulating a crash scenario. The server should still start after this
- */
- @Test
- public void testDeletePhysicalPages() throws Exception {
- clearDataRecreateServerDirs();
-
- Configuration config = createDefaultInVMConfig().setPersistDeliveryCountBeforeDelivery(true);
-
- config.setJournalSyncNonTransactional(false);
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
-
- server.start();
-
- final int numberOfMessages = 1000;
-
- locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
-
- sf = createSessionFactory(locator);
-
- ClientSession session = sf.createSession(false, false, false);
-
- session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
-
- ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
-
- ClientMessage message = null;
-
- byte[] body = new byte[MESSAGE_SIZE];
-
- ByteBuffer bb = ByteBuffer.wrap(body);
-
- for (int j = 1; j <= MESSAGE_SIZE; j++) {
- bb.put(getSamplebyte(j));
- }
-
- for (int i = 0; i < numberOfMessages; i++) {
- message = session.createMessage(true);
-
- ActiveMQBuffer bodyLocal = message.getBodyBuffer();
-
- bodyLocal.writeBytes(body);
-
- message.putIntProperty(new SimpleString("id"), i);
-
- producer.send(message);
- if (i % 1000 == 0) {
- session.commit();
- }
- }
- session.commit();
- session.close();
-
- session = null;
-
- sf.close();
- locator.close();
-
- server.stop();
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
- server.start();
-
- locator = createInVMNonHALocator();
- sf = createSessionFactory(locator);
-
- Queue queue = server.locateQueue(ADDRESS);
-
- assertEquals(numberOfMessages, getMessageCount(queue));
-
- int msgReceived = 0;
- ClientSession sessionConsumer = sf.createSession(false, false, false);
- sessionConsumer.start();
- ClientConsumer consumer = sessionConsumer.createConsumer(PagingTest.ADDRESS);
- for (int msgCount = 0; msgCount < numberOfMessages; msgCount++) {
- log.info("Received " + msgCount);
- msgReceived++;
- ClientMessage msg = consumer.receiveImmediate();
- if (msg == null) {
- log.info("It's null. leaving now");
- sessionConsumer.commit();
- fail("Didn't receive a message");
- }
- msg.acknowledge();
-
- if (msgCount % 5 == 0) {
- log.info("commit");
- sessionConsumer.commit();
- }
- }
-
- sessionConsumer.commit();
-
- sessionConsumer.close();
-
- sf.close();
-
- locator.close();
-
- assertEquals(0, getMessageCount(queue));
-
- long timeout = System.currentTimeMillis() + 5000;
- while (timeout > System.currentTimeMillis() && queue.getPageSubscription().getPagingStore().isPaging()) {
- Thread.sleep(100);
- }
- assertFalse(queue.getPageSubscription().getPagingStore().isPaging());
-
- server.stop();
-
- // Deleting the paging data. Simulating a failure
- // a dumb user, or anything that will remove the data
- deleteDirectory(new File(getPageDir()));
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
- server.start();
-
- locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
-
- sf = createSessionFactory(locator);
-
- queue = server.locateQueue(ADDRESS);
-
- sf = createSessionFactory(locator);
- session = sf.createSession(false, false, false);
-
- producer = session.createProducer(PagingTest.ADDRESS);
-
- for (int i = 0; i < numberOfMessages; i++) {
- message = session.createMessage(true);
-
- ActiveMQBuffer bodyLocal = message.getBodyBuffer();
-
- bodyLocal.writeBytes(body);
-
- message.putIntProperty(new SimpleString("id"), i);
-
- producer.send(message);
- if (i % 1000 == 0) {
- session.commit();
- }
- }
-
- session.commit();
-
- server.stop();
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
- server.start();
-
- locator = createInVMNonHALocator();
- sf = createSessionFactory(locator);
-
- queue = server.locateQueue(ADDRESS);
-
- // assertEquals(numberOfMessages, getMessageCount(queue));
-
- msgReceived = 0;
- sessionConsumer = sf.createSession(false, false, false);
- sessionConsumer.start();
- consumer = sessionConsumer.createConsumer(PagingTest.ADDRESS);
- for (int msgCount = 0; msgCount < numberOfMessages; msgCount++) {
- log.info("Received " + msgCount);
- msgReceived++;
- ClientMessage msg = consumer.receiveImmediate();
- if (msg == null) {
- log.info("It's null. leaving now");
- sessionConsumer.commit();
- fail("Didn't receive a message");
- }
- msg.acknowledge();
-
- if (msgCount % 5 == 0) {
- log.info("commit");
- sessionConsumer.commit();
- }
- }
-
- sessionConsumer.commit();
-
- sessionConsumer.close();
-
- }
-
- @Test
- public void testMissingTXEverythingAcked() throws Exception {
- clearDataRecreateServerDirs();
-
- Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
-
- server.start();
-
- final int numberOfMessages = 5000;
-
- final int numberOfTX = 10;
-
- final int messagesPerTX = numberOfMessages / numberOfTX;
-
- try {
- locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
-
- sf = createSessionFactory(locator);
-
- ClientSession session = sf.createSession(false, false, false);
-
- session.createQueue(ADDRESS.toString(), "q1", true);
-
- session.createQueue(ADDRESS.toString(), "q2", true);
-
- ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
-
- ClientMessage message = null;
-
- byte[] body = new byte[MESSAGE_SIZE];
-
- ByteBuffer bb = ByteBuffer.wrap(body);
-
- for (int j = 1; j <= MESSAGE_SIZE; j++) {
- bb.put(getSamplebyte(j));
- }
-
- for (int i = 0; i < numberOfMessages; i++) {
- message = session.createMessage(true);
-
- ActiveMQBuffer bodyLocal = message.getBodyBuffer();
-
- bodyLocal.writeBytes(body);
-
- message.putIntProperty(new SimpleString("id"), i);
-
- producer.send(message);
- if (i % messagesPerTX == 0) {
- session.commit();
- }
- }
- session.commit();
- session.close();
- }
- finally {
- try {
- server.stop();
- }
- catch (Throwable ignored) {
- }
- }
-
- ArrayList<RecordInfo> records = new ArrayList<>();
-
- List<PreparedTransactionInfo> list = new ArrayList<>();
-
- JournalImpl jrn = new JournalImpl(config.getJournalFileSize(), 2, 2, 0, 0, new NIOSequentialFileFactory(server.getConfiguration().getJournalLocation(), 1), "activemq-data", "amq", 1);
- jrn.start();
- jrn.load(records, list, null);
-
- // Delete everything from the journal
- for (RecordInfo info : records) {
- if (!info.isUpdate && info.getUserRecordType() != JournalRecordIds.PAGE_CURSOR_COUNTER_VALUE &&
- info.getUserRecordType() != JournalRecordIds.PAGE_CURSOR_COUNTER_INC &&
- info.getUserRecordType() != JournalRecordIds.PAGE_CURSOR_COMPLETE) {
- jrn.appendDeleteRecord(info.id, false);
- }
- }
-
- jrn.stop();
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
-
- server.start();
-
- ClientSessionFactory csf = createSessionFactory(locator);
-
- ClientSession sess = csf.createSession();
-
- sess.start();
-
- ClientConsumer cons = sess.createConsumer("q1");
-
- assertNull(cons.receiveImmediate());
-
- ClientConsumer cons2 = sess.createConsumer("q2");
- assertNull(cons2.receiveImmediate());
-
- Queue q1 = server.locateQueue(new SimpleString("q1"));
- Queue q2 = server.locateQueue(new SimpleString("q2"));
-
- q1.getPageSubscription().cleanupEntries(false);
- q2.getPageSubscription().cleanupEntries(false);
-
- PageCursorProvider provider = q1.getPageSubscription().getPagingStore().getCursorProvider();
- provider.cleanup();
-
- waitForNotPaging(q1);
-
- sess.close();
- }
-
- @Test
- public void testMissingTXEverythingAcked2() throws Exception {
- clearDataRecreateServerDirs();
-
- Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
-
- server.start();
-
- final int numberOfMessages = 6;
-
- final int numberOfTX = 2;
-
- final int messagesPerTX = numberOfMessages / numberOfTX;
-
- try {
- locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
-
- sf = createSessionFactory(locator);
-
- ClientSession session = sf.createSession(false, false, false);
-
- session.createQueue(ADDRESS.toString(), "q1", true);
-
- session.createQueue(ADDRESS.toString(), "q2", true);
-
- server.getPagingManager().getPageStore(ADDRESS).startPaging();
-
- ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
-
- ClientMessage message = null;
-
- byte[] body = new byte[MESSAGE_SIZE];
-
- ByteBuffer bb = ByteBuffer.wrap(body);
-
- for (int j = 1; j <= MESSAGE_SIZE; j++) {
- bb.put(getSamplebyte(j));
- }
-
- for (int i = 0; i < numberOfMessages; i++) {
- message = session.createMessage(true);
-
- ActiveMQBuffer bodyLocal = message.getBodyBuffer();
-
- bodyLocal.writeBytes(body);
-
- message.putStringProperty("id", "str-" + i);
-
- producer.send(message);
- if ((i + 1) % messagesPerTX == 0) {
- session.commit();
- }
- }
- session.commit();
-
- session.start();
-
- for (int i = 1; i <= 2; i++) {
- ClientConsumer cons = session.createConsumer("q" + i);
-
- for (int j = 0; j < 3; j++) {
- ClientMessage msg = cons.receive(5000);
-
- assertNotNull(msg);
-
- assertEquals("str-" + j, msg.getStringProperty("id"));
-
- msg.acknowledge();
- }
-
- session.commit();
-
- }
-
- session.close();
- }
- finally {
- locator.close();
- try {
- server.stop();
- }
- catch (Throwable ignored) {
- }
- }
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
-
- server.start();
-
- locator = createInVMNonHALocator();
-
- locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
-
- ClientSessionFactory csf = createSessionFactory(locator);
-
- ClientSession session = csf.createSession();
-
- session.start();
-
- for (int i = 1; i <= 2; i++) {
- ClientConsumer cons = session.createConsumer("q" + i);
-
- for (int j = 3; j < 6; j++) {
- ClientMessage msg = cons.receive(5000);
-
- assertNotNull(msg);
-
- assertEquals("str-" + j, msg.getStringProperty("id"));
-
- msg.acknowledge();
- }
-
- session.commit();
- assertNull(cons.receive(500));
-
- }
-
- session.close();
-
- long timeout = System.currentTimeMillis() + 5000;
-
- while (System.currentTimeMillis() < timeout && server.getPagingManager().getPageStore(ADDRESS).isPaging()) {
- Thread.sleep(100);
- }
- }
-
- @Test
- public void testTwoQueuesOneNoRouting() throws Exception {
- boolean persistentMessages = true;
-
- clearDataRecreateServerDirs();
-
- Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
-
- server.start();
-
- final int numberOfMessages = 1000;
-
- locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
-
- sf = createSessionFactory(locator);
-
- ClientSession session = sf.createSession(false, false, false);
-
- session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
- session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS.concat("-invalid"), new SimpleString(ActiveMQServerImpl.GENERIC_IGNORED_FILTER), true);
-
- ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
-
- ClientMessage message = null;
-
- byte[] body = new byte[MESSAGE_SIZE];
-
- for (int i = 0; i < numberOfMessages; i++) {
- message = session.createMessage(persistentMessages);
-
- ActiveMQBuffer bodyLocal = message.getBodyBuffer();
-
- bodyLocal.writeBytes(body);
-
- message.putIntProperty(new SimpleString("id"), i);
-
- producer.send(message);
- if (i % 1000 == 0) {
- session.commit();
- }
- }
-
- session.commit();
-
- session.start();
-
- ClientConsumer consumer = session.createConsumer(PagingTest.ADDRESS);
-
- for (int i = 0; i < numberOfMessages; i++) {
- message = consumer.receive(5000);
- assertNotNull(message);
- message.acknowledge();
-
- assertEquals(i, message.getIntProperty("id").intValue());
- if (i % 1000 == 0) {
- session.commit();
- }
- }
-
- session.commit();
-
- session.commit();
-
- session.commit();
-
- PagingStore store = server.getPagingManager().getPageStore(ADDRESS);
- store.getCursorProvider().cleanup();
-
- long timeout = System.currentTimeMillis() + 5000;
- while (store.isPaging() && timeout > System.currentTimeMillis()) {
- Thread.sleep(100);
- }
-
- // It's async, so need to wait a bit for it happening
- assertFalse(server.getPagingManager().getPageStore(ADDRESS).isPaging());
- }
-
- @Test
- public void testSendReceivePagingPersistent() throws Exception {
- internaltestSendReceivePaging(true);
- }
-
- @Test
- public void testSendReceivePagingNonPersistent() throws Exception {
- internaltestSendReceivePaging(false);
- }
-
- @Test
- public void testWithDiverts() throws Exception {
- internalMultiQueuesTest(true);
- }
-
- @Test
- public void testWithMultiQueues() throws Exception {
- internalMultiQueuesTest(false);
- }
-
- public void internalMultiQueuesTest(final boolean divert) throws Exception {
- clearDataRecreateServerDirs();
-
- Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
-
- if (divert) {
- DivertConfiguration divert1 = new DivertConfiguration().setName("dv1").setRoutingName("nm1").setAddress(PagingTest.ADDRESS.toString()).setForwardingAddress(PagingTest.ADDRESS.toString() + "-1").setExclusive(true);
-
- config.addDivertConfiguration(divert1);
-
- DivertConfiguration divert2 = new DivertConfiguration().setName("dv2").setRoutingName("nm2").setAddress(PagingTest.ADDRESS.toString()).setForwardingAddress(PagingTest.ADDRESS.toString() + "-2").setExclusive(true);
-
- config.addDivertConfiguration(divert2);
- }
-
- server.start();
-
- final int numberOfMessages = 3000;
-
- final byte[] body = new byte[MESSAGE_SIZE];
-
- ByteBuffer bb = ByteBuffer.wrap(body);
-
- for (int j = 1; j <= MESSAGE_SIZE; j++) {
- bb.put(getSamplebyte(j));
- }
-
- final AtomicBoolean running = new AtomicBoolean(true);
-
- class TCount extends Thread {
-
- Queue queue;
-
- TCount(Queue queue) {
- this.queue = queue;
- }
-
- @Override
- public void run() {
- try {
- while (running.get()) {
- // this will be overusing what some users do. flush / getCount
- getMessagesAdded(queue);
- getMessageCount(queue);
- Thread.sleep(10);
- }
- }
- catch (InterruptedException e) {
- log.info("Thread interrupted");
- }
- }
- }
-
- TCount tcount1 = null;
- TCount tcount2 = null;
-
- try {
- {
- locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
-
- sf = createSessionFactory(locator);
-
- ClientSession session = sf.createSession(false, false, false);
-
- if (divert) {
- session.createQueue(PagingTest.ADDRESS + "-1", PagingTest.ADDRESS + "-1", null, true);
-
- session.createQueue(PagingTest.ADDRESS + "-2", PagingTest.ADDRESS + "-2", null, true);
- }
- else {
- session.createQueue(PagingTest.ADDRESS.toString(), PagingTest.ADDRESS + "-1", null, true);
-
- session.createQueue(PagingTest.ADDRESS.toString(), PagingTest.ADDRESS + "-2", null, true);
- }
-
- ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
-
- ClientMessage message = null;
-
- for (int i = 0; i < numberOfMessages; i++) {
- if (i % 500 == 0) {
- log.info("Sent " + i + " messages");
- session.commit();
- }
- message = session.createMessage(true);
-
- ActiveMQBuffer bodyLocal = message.getBodyBuffer();
-
- bodyLocal.writeBytes(body);
-
- message.putIntProperty(new SimpleString("id"), i);
-
- producer.send(message);
- }
-
- session.commit();
-
- session.close();
-
- server.stop();
-
- sf.close();
- locator.close();
- }
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
- server.start();
-
- Queue queue1 = server.locateQueue(PagingTest.ADDRESS.concat("-1"));
-
- Queue queue2 = server.locateQueue(PagingTest.ADDRESS.concat("-2"));
-
- assertNotNull(queue1);
-
- assertNotNull(queue2);
-
- assertNotSame(queue1, queue2);
-
- tcount1 = new TCount(queue1);
-
- tcount2 = new TCount(queue2);
-
- tcount1.start();
- tcount2.start();
-
- locator = createInVMNonHALocator();
- final ClientSessionFactory sf2 = createSessionFactory(locator);
-
- final AtomicInteger errors = new AtomicInteger(0);
-
- Thread[] threads = new Thread[2];
-
- for (int start = 1; start <= 2; start++) {
-
- final String addressToSubscribe = PagingTest.ADDRESS + "-" + start;
-
- threads[start - 1] = new Thread() {
- @Override
- public void run() {
- try {
- ClientSession session = sf2.createSession(null, null, false, true, true, false, 0);
-
- ClientConsumer consumer = session.createConsumer(addressToSubscribe);
-
- session.start();
-
- for (int i = 0; i < numberOfMessages; i++) {
- ClientMessage message2 = consumer.receive(PagingTest.RECEIVE_TIMEOUT);
-
- Assert.assertNotNull(message2);
-
- Assert.assertEquals(i, message2.getIntProperty("id").intValue());
-
- message2.acknowledge();
-
- Assert.assertNotNull(message2);
-
- if (i % 100 == 0) {
- if (i % 5000 == 0) {
- log.info(addressToSubscribe + " consumed " + i + " messages");
- }
- session.commit();
- }
-
- try {
- assertBodiesEqual(body, message2.getBodyBuffer());
- }
- catch (AssertionError e) {
- PagingTest.log.info("Expected buffer:" + ActiveMQTestBase.dumpBytesHex(body, 40));
- PagingTest.log.info("Arriving buffer:" + ActiveMQTestBase.dumpBytesHex(message2.getBodyBuffer().toByteBuffer().array(), 40));
- throw e;
- }
- }
-
- session.commit();
-
- consumer.close();
-
- session.close();
- }
- catch (Throwable e) {
- e.printStackTrace();
- errors.incrementAndGet();
- }
-
- }
- };
- }
-
- for (int i = 0; i < 2; i++) {
- threads[i].start();
- }
-
- for (int i = 0; i < 2; i++) {
- threads[i].join();
- }
-
- sf2.close();
- locator.close();
-
- assertEquals(0, errors.get());
-
- for (int i = 0; i < 20 && server.getPagingManager().getTransactions().size() != 0; i++) {
- if (server.getPagingManager().getTransactions().size() != 0) {
- // The delete may be asynchronous, giving some time case it eventually happen asynchronously
- Thread.sleep(500);
- }
- }
-
- assertEquals(0, server.getPagingManager().getTransactions().size());
-
- }
- finally {
- running.set(false);
-
- if (tcount1 != null) {
- tcount1.interrupt();
- tcount1.join();
- }
-
- if (tcount2 != null) {
- tcount2.interrupt();
- tcount2.join();
- }
-
- try {
- server.stop();
- }
- catch (Throwable ignored) {
- }
- }
-
- }
-
- @Test
- public void testMultiQueuesNonPersistentAndPersistent() throws Exception {
- clearDataRecreateServerDirs();
-
- Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
-
- server.start();
-
- final int numberOfMessages = 3000;
-
- final byte[] body = new byte[MESSAGE_SIZE];
-
- ByteBuffer bb = ByteBuffer.wrap(body);
-
- for (int j = 1; j <= MESSAGE_SIZE; j++) {
- bb.put(getSamplebyte(j));
- }
-
- {
- locator = createInVMNonHALocator();
-
- locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
-
- sf = createSessionFactory(locator);
-
- ClientSession session = sf.createSession(false, false, false);
-
- session.createQueue(PagingTest.ADDRESS.toString(), PagingTest.ADDRESS + "-1", null, true);
-
- session.createQueue(PagingTest.ADDRESS.toString(), PagingTest.ADDRESS + "-2", null, false);
-
- ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
-
- ClientMessage message = null;
-
- for (int i = 0; i < numberOfMessages; i++) {
- if (i % 500 == 0) {
- session.commit();
- }
- message = session.createMessage(true);
-
- ActiveMQBuffer bodyLocal = message.getBodyBuffer();
-
- bodyLocal.writeBytes(body);
-
- message.putIntProperty(new SimpleString("id"), i);
-
- producer.send(message);
- }
-
- session.commit();
-
- session.close();
-
- server.stop();
-
- sf.close();
- locator.close();
- }
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
- server.start();
-
- ServerLocator locator1 = createInVMNonHALocator();
- final ClientSessionFactory sf2 = locator1.createSessionFactory();
-
- final AtomicInteger errors = new AtomicInteger(0);
-
- Thread t = new Thread() {
- @Override
- public void run() {
- try {
- ClientSession session = sf2.createSession(null, null, false, true, true, false, 0);
-
- ClientConsumer consumer = session.createConsumer(PagingTest.ADDRESS + "-1");
-
- session.start();
-
- for (int i = 0; i < numberOfMessages; i++) {
- ClientMessage message2 = consumer.receive(PagingTest.RECEIVE_TIMEOUT);
-
- Assert.assertNotNull(message2);
-
- Assert.assertEquals(i, message2.getIntProperty("id").intValue());
-
- message2.acknowledge();
-
- Assert.assertNotNull(message2);
-
- if (i % 1000 == 0) {
- session.commit();
- }
-
- try {
- assertBodiesEqual(body, message2.getBodyBuffer());
- }
- catch (AssertionError e) {
- PagingTest.log.info("Expected buffer:" + ActiveMQTestBase.dumpBytesHex(body, 40));
- PagingTest.log.info("Arriving buffer:" + ActiveMQTestBase.dumpBytesHex(message2.getBodyBuffer().toByteBuffer().array(), 40));
- throw e;
- }
- }
-
- session.commit();
-
- consumer.close();
-
- session.close();
- }
- catch (Throwable e) {
- e.printStackTrace();
- errors.incrementAndGet();
- }
-
- }
- };
-
- t.start();
- t.join();
-
- assertEquals(0, errors.get());
-
- for (int i = 0; i < 20 && server.getPagingManager().getPageStore(ADDRESS).isPaging(); i++) {
- // The delete may be asynchronous, giving some time case it eventually happen asynchronously
- Thread.sleep(500);
- }
-
- assertFalse(server.getPagingManager().getPageStore(ADDRESS).isPaging());
-
- for (int i = 0; i < 20 && server.getPagingManager().getTransactions().size() != 0; i++) {
- // The delete may be asynchronous, giving some time case it eventually happen asynchronously
- Thread.sleep(500);
- }
-
- assertEquals(0, server.getPagingManager().getTransactions().size());
-
- }
-
- private void internaltestSendReceivePaging(final boolean persistentMessages) throws Exception {
-
- clearDataRecreateServerDirs();
-
- Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
-
- server.start();
-
- final int numberOfIntegers = 256;
-
- final int numberOfMessages = 1000;
- locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
-
- sf = createSessionFactory(locator);
-
- ClientSession session = sf.createSession(null, null, false, true, true, false, 0);
-
- session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
-
- Queue queue = server.locateQueue(ADDRESS);
- queue.getPageSubscription().getPagingStore().startPaging();
-
- ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
-
- ClientMessage message = null;
-
- byte[] body = new byte[numberOfIntegers * 4];
-
- ByteBuffer bb = ByteBuffer.wrap(body);
-
- for (int j = 1; j <= numberOfIntegers; j++) {
- bb.putInt(j);
- }
-
- for (int i = 0; i < numberOfMessages; i++) {
- message = session.createMessage(persistentMessages);
-
- ActiveMQBuffer bodyLocal = message.getBodyBuffer();
-
- bodyLocal.writeBytes(body);
-
- message.putIntProperty(new SimpleString("id"), i);
-
- producer.send(message);
- }
-
- session.close();
- sf.close();
- locator.close();
-
- server.stop();
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
- server.start();
-
- locator = createInVMNonHALocator();
- sf = createSessionFactory(locator);
-
- session = sf.createSession(null, null, false, true, true, false, 0);
-
- ClientConsumer consumer = session.createConsumer(PagingTest.ADDRESS);
-
- session.start();
-
- for (int i = 0; i < numberOfMessages; i++) {
- ClientMessage message2 = consumer.receive(PagingTest.RECEIVE_TIMEOUT);
-
- Assert.assertNotNull(message2);
-
- Assert.assertEquals(i, message2.getIntProperty("id").intValue());
-
- assertEquals(body.length, message2.getBodySize());
-
- message2.acknowledge();
-
- Assert.assertNotNull(message2);
-
- if (i % 1000 == 0) {
- session.commit();
- }
-
- try {
- assertBodiesEqual(body, message2.getBodyBuffer());
- }
- catch (AssertionError e) {
- PagingTest.log.info("Expected buffer:" + ActiveMQTestBase.dumpBytesHex(body, 40));
- PagingTest.log.info("Arriving buffer:" + ActiveMQTestBase.dumpBytesHex(message2.getBodyBuffer().toByteBuffer().array(), 40));
- throw e;
- }
- }
-
- consumer.close();
-
- session.close();
- }
-
- private void assertBodiesEqual(final byte[] body, final ActiveMQBuffer buffer) {
- byte[] other = new byte[body.length];
-
- buffer.readBytes(other);
-
- ActiveMQTestBase.assertEqualsByteArrays(body, other);
- }
-
- /**
- * - Make a destination in page mode
- * - Add stuff to a transaction
- * - Consume the entire destination (not in page mode any more)
- * - Add stuff to a transaction again
- * - Check order
- */
- @Test
- public void testDepageDuringTransaction() throws Exception {
- clearDataRecreateServerDirs();
-
- Configuration config = createDefaultInVMConfig();
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
-
- server.start();
-
- locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
-
- sf = createSessionFactory(locator);
-
- ClientSession session = sf.createSession(null, null, false, true, true, false, 0);
-
- session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
-
- ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
-
- byte[] body = new byte[MESSAGE_SIZE];
- // ActiveMQBuffer bodyLocal = ActiveMQChannelBuffers.buffer(DataConstants.SIZE_INT * numberOfIntegers);
-
- ClientMessage message = null;
-
- int numberOfMessages = 0;
- while (true) {
- message = session.createMessage(true);
- message.getBodyBuffer().writeBytes(body);
-
- // Stop sending message as soon as we start paging
- if (server.getPagingManager().getPageStore(PagingTest.ADDRESS).isPaging()) {
- break;
- }
- numberOfMessages++;
-
- producer.send(message);
- }
-
- Assert.assertTrue(server.getPagingManager().getPageStore(PagingTest.ADDRESS).isPaging());
-
- session.start();
-
- ClientSession sessionTransacted = sf.createSession(null, null, false, false, false, false, 0);
-
- ClientProducer producerTransacted = sessionTransacted.createProducer(PagingTest.ADDRESS);
-
- for (int i = 0; i < 10; i++) {
- message = session.createMessage(true);
- message.getBodyBuffer().writeBytes(body);
- message.putIntProperty(new SimpleString("id"), i);
-
- // Consume messages to force an eventual out of order delivery
- if (i == 5) {
- ClientConsumer consumer = session.createConsumer(PagingTest.ADDRESS);
- for (int j = 0; j < numberOfMessages; j++) {
- ClientMessage msg = consumer.receive(PagingTest.RECEIVE_TIMEOUT);
- msg.acknowledge();
- Assert.assertNotNull(msg);
- }
-
- Assert.assertNull(consumer.receiveImmediate());
- consumer.close();
- }
-
- Integer messageID = (Integer) message.getObjectProperty(new SimpleString("id"));
- Assert.assertNotNull(messageID);
- Assert.assertEquals(messageID.intValue(), i);
-
- producerTransacted.send(message);
- }
-
- ClientConsumer consumer = session.createConsumer(PagingTest.ADDRESS);
-
- Assert.assertNull(consumer.receiveImmediate());
-
- sessionTransacted.commit();
-
- sessionTransacted.close();
-
- for (int i = 0; i < 10; i++) {
- message = consumer.receive(PagingTest.RECEIVE_TIMEOUT);
-
- Assert.assertNotNull(message);
-
- Integer messageID = (Integer) message.getObjectProperty(new SimpleString("id"));
-
- Assert.assertNotNull(messageID);
- Assert.assertEquals("message received out of order", messageID.intValue(), i);
-
- message.acknowledge();
- }
-
- Assert.assertNull(consumer.receiveImmediate());
-
- consumer.close();
-
- session.close();
- }
-
- /**
- * - Make a destination in page mode
- * - Add stuff to a transaction
- * - Consume the entire destination (not in page mode any more)
- * - Add stuff to a transaction again
- * - Check order
- * <br>
- * Test under discussion at : http://community.jboss.org/thread/154061?tstart=0
- */
- @Test
- public void testDepageDuringTransaction2() throws Exception {
- boolean IS_DURABLE_MESSAGE = true;
- clearDataRecreateServerDirs();
-
- Configuration config = createDefaultInVMConfig();
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
-
- server.start();
-
- locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
-
- sf = createSessionFactory(locator);
-
- byte[] body = new byte[MESSAGE_SIZE];
-
- ClientSession sessionTransacted = sf.createSession(null, null, false, false, false, false, 0);
- ClientProducer producerTransacted = sessionTransacted.createProducer(PagingTest.ADDRESS);
-
- ClientSession session = sf.createSession(null, null, false, true, true, false, 0);
- session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
-
- ClientMessage firstMessage = sessionTransacted.createMessage(IS_DURABLE_MESSAGE);
- firstMessage.getBodyBuffer().writeBytes(body);
- firstMessage.putIntProperty(new SimpleString("id"), 0);
-
- producerTransacted.send(firstMessage);
-
- ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
-
- ClientMessage message = null;
-
- int numberOfMessages = 0;
- while (true) {
- message = session.createMessage(IS_DURABLE_MESSAGE);
- message.getBodyBuffer().writeBytes(body);
- message.putIntProperty("id", numberOfMessages);
- message.putBooleanProperty("new", false);
-
- // Stop sending message as soon as we start paging
- if (server.getPagingManager().getPageStore(PagingTest.ADDRESS).isPaging()) {
- break;
- }
- numberOfMessages++;
-
- producer.send(message);
- }
-
- Assert.assertTrue(server.getPagingManager().getPageStore(PagingTest.ADDRESS).isPaging());
-
- session.start();
-
- for (int i = 1; i < 10; i++) {
- message = session.createMessage(true);
- message.getBodyBuffer().writeBytes(body);
- message.putIntProperty(new SimpleString("id"), i);
-
- // Consume messages to force an eventual out of order delivery
- if (i == 5) {
- ClientConsumer consumer = session.createConsumer(PagingTest.ADDRESS);
- for (int j = 0; j < numberOfMessages; j++) {
- ClientMessage msg = consumer.receive(PagingTest.RECEIVE_TIMEOUT);
- msg.acknowledge();
- assertEquals(j, msg.getIntProperty("id").intValue());
- assertFalse(msg.getBooleanProperty("new"));
- Assert.assertNotNull(msg);
- }
-
- ClientMessage msgReceived = consumer.receiveImmediate();
-
- Assert.assertNull(msgReceived);
- consumer.close();
- }
-
- Integer messageID = (Integer) message.getObjectProperty(new SimpleString("id"));
- Assert.assertNotNull(messageID);
- Assert.assertEquals(messageID.intValue(), i);
-
- producerTransacted.send(message);
- }
-
- ClientConsumer consumer = session.createConsumer(PagingTest.ADDRESS);
-
- Assert.assertNull(consumer.receiveImmediate());
-
- sessionTransacted.commit();
-
- sessionTransacted.close();
-
- for (int i = 0; i < 10; i++) {
- message = consumer.receive(PagingTest.RECEIVE_TIMEOUT);
-
- Assert.assertNotNull(message);
-
- Integer messageID = (Integer) message.getObjectProperty(new SimpleString("id"));
-
- // System.out.println(messageID);
- Assert.assertNotNull(messageID);
- Assert.assertEquals("message received out of order", i, messageID.intValue());
-
- message.acknowledge();
- }
-
- Assert.assertNull(consumer.receiveImmediate());
-
- consumer.close();
-
- session.close();
-
- }
-
- @Test
- public void testDepageDuringTransaction3() throws Exception {
- clearDataRecreateServerDirs();
-
- Configuration config = createDefaultInVMConfig();
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
-
- server.start();
-
- locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
-
- sf = createSessionFactory(locator);
-
- byte[] body = new byte[MESSAGE_SIZE];
-
- ClientSession sessionTransacted = sf.createSession(null, null, false, false, false, false, 0);
- ClientProducer producerTransacted = sessionTransacted.createProducer(PagingTest.ADDRESS);
-
- ClientSession sessionNonTX = sf.createSession(true, true, 0);
- sessionNonTX.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
-
- ClientProducer producerNonTransacted = sessionNonTX.createProducer(PagingTest.ADDRESS);
-
- sessionNonTX.start();
-
- for (int i = 0; i < 50; i++) {
- ClientMessage message = sessionNonTX.createMessage(true);
- message.getBodyBuffer().writeBytes(body);
- message.putIntProperty(new SimpleString("id"), i);
- message.putStringProperty(new SimpleString("tst"), new SimpleString("i=" + i));
-
- producerTransacted.send(message);
-
- if (i % 2 == 0) {
- for (int j = 0; j < 20; j++) {
- ClientMessage msgSend = sessionNonTX.createMessage(true);
- msgSend.putStringProperty(new SimpleString("tst"), new SimpleString("i=" + i + ", j=" + j));
- msgSend.getBodyBuffer().writeBytes(new byte[10 * 1024]);
- producerNonTransacted.send(msgSend);
- }
- assertTrue(server.getPagingManager().getPageStore(PagingTest.ADDRESS).isPaging());
- }
- else {
- ClientConsumer consumer = sessionNonTX.createConsumer(PagingTest.ADDRESS);
- for (int j = 0; j < 20; j++) {
- ClientMessage msgReceived = consumer.receive(10000);
- assertNotNull(msgReceived);
- msgReceived.acknowledge();
- }
- consumer.close();
- }
- }
-
- ClientConsumer consumerNonTX = sessionNonTX.createConsumer(PagingTest.ADDRESS);
- while (true) {
- ClientMessage msgReceived = consumerNonTX.receive(1000);
- if (msgReceived == null) {
- break;
- }
- msgReceived.acknowledge();
- }
- consumerNonTX.close();
-
- ClientConsumer consumer = sessionNonTX.createConsumer(PagingTest.ADDRESS);
-
- Assert.assertNull(consumer.receiveImmediate());
-
- sessionTransacted.commit();
-
- sessionTransacted.close();
-
- for (int i = 0; i < 50; i++) {
- ClientMessage message = consumer.receive(PagingTest.RECEIVE_TIMEOUT);
-
- Assert.assertNotNull(message);
-
- Integer messageID = (Integer) message.getObjectProperty(new SimpleString("id"));
-
- Assert.assertNotNull(messageID);
- Assert.assertEquals("message received out of order", i, messageID.intValue());
-
- message.acknowledge();
- }
-
- Assert.assertNull(consumer.receiveImmediate());
-
- consumer.close();
-
- sessionNonTX.close();
- }
-
- @Test
- public void testDepageDuringTransaction4() throws Exception {
- clearDataRecreateServerDirs();
-
- Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false).setJournalSyncTransactional(false);
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX, new HashMap<String, AddressSettings>());
-
- server.start();
-
- final AtomicInteger errors = new AtomicInteger(0);
-
- final int numberOfMessages = 10000;
-
- locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(false);
-
- sf = createSessionFactory(locator);
-
- final byte[] body = new byte[MESSAGE_SIZE];
-
- Thread producerThread = new Thread() {
- @Override
- public void run() {
- ClientSession sessionProducer = null;
- try {
- sessionProducer = sf.createSession(false, false);
- ClientProducer producer = sessionProducer.createProducer(ADDRESS);
-
- for (int i = 0; i < numberOfMessages; i++) {
- ClientMessage msg = sessionProducer.createMessage(true);
- msg.getBodyBuffer().writeBytes(body);
- msg.putIntProperty("count", i);
- producer.send(msg);
-
- if (i % 100 == 0 && i != 0) {
- sessionProducer.commit();
- // Thread.sleep(500);
- }
- }
-
- sessionProducer.commit();
-
- }
- catch (Throwable e) {
- e.printStackTrace(); // >> junit report
- errors.incrementAndGet();
- }
- finally {
- try {
- if (sessionProducer != null) {
- sessionProducer.close();
- }
- }
- catch (Throwable e) {
- e.printStackTrace();
- errors.incrementAndGet();
- }
- }
- }
- };
-
- ClientSession session = sf.createSession(true, true, 0);
- session.start();
- session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
-
- producerThread.start();
-
- ClientConsumer consumer = session.createConsumer(PagingTest.ADDRESS);
-
- for (int i = 0; i < numberOfMessages; i++) {
- ClientMessage msg = consumer.receive(5000);
- assertNotNull(msg);
- assertEquals(i, msg.getIntProperty("count").intValue());
- msg.acknowledge();
- if (i > 0 && i % 10 == 0) {
- session.commit();
- }
- }
- session.commit();
-
- session.close();
-
- producerThread.join();
-
- locator.close();
-
- sf.close();
-
- assertEquals(0, errors.get());
- }
-
- @Test
- public void testOrderingNonTX() throws Exception {
- clearDataRecreateServerDirs();
-
- Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false).setJournalSyncTransactional(false);
-
- server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_SIZE * 2, new HashMap<String, AddressSettings>());
-
- server.getConfiguration();
- server.getConfiguration();
-
- server.start();
-
- final AtomicInteger errors = new AtomicInteger(0);
-
- final int numberOfMessages = 2000;
-
- locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
-
- sf = createSessionFactory(locator);
-
- final CountDownLatch ready = new CountDownLatch(1);
-
- final byte[] body = new byte[MESSAGE_SIZE];
-
- Thread producerThread = new Thread() {
- @Override
- public void run() {
- ClientSession sessionProducer = null;
- try {
- sessionProducer = sf.createSession(true, true);
- ClientProducer producer = sessionProducer.createProducer(ADDRESS);
-
- for (int i = 0; i < numberOfMessages; i++) {
- ClientMessage msg = sessionProducer.createMessage(true);
- msg.getBodyBuffer().writeBytes(body);
- msg.putIntProperty("count", i);
- producer.send(msg);
-
- if (i == 1000) {
- // The session is not TX, but we do this just to perform a round trip to the server
- // and make sure there are no pending messages
- sessionProducer.commit();
-
- assertTrue(server.getPagingManager().getPageStore(ADDRESS).isPaging());
- ready.countDown();
- }
- }
-
- sessionProducer.commit();
-
- log.info("Producer gone");
-
- }
- catch (Throwable e) {
- e.printStackTrace(); // >> junit report
- errors.incrementAndGet();
- }
- finally {
- try {
- if (sessionProducer != null) {
- sessionProducer.close();
- }
- }
- catch (Throwable e) {
- e.printStackTrace();
- errors.incrementAndGet();
- }
- }
- }
- };
-
- ClientSession session = sf.createSession(true, true, 0);
- session.start();
- session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
-
- producerThread.start();
-
- assertTrue(ready.await(100, TimeUnit.SECONDS));
-
- ClientConsumer consumer = session.createConsumer(PagingTest.ADDRESS);
-
- for (int i = 0; i < numberOfMessages; i++) {
- ClientMessage msg = consumer.receive(5000);
- assertNotNull(msg);
- if (i != msg.getIntProperty("count").intValue()) {
- log.info("Received " + i + " with property = " + msg.getIntProperty("count"));
- log.info("###### different");
- }
- // assertEquals(i, msg.getIntProperty("count").intValue());
- msg.acknowledge();
- }
-
- session.close();
-
<TRUNCATED>
[3/7] activemq-artemis git commit: ARTEMIS-581 Implement max disk
usage, and global-max-size
Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/paging/PagingTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/paging/PagingTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/paging/PagingTest.java
new file mode 100644
index 0000000..82ce14f
--- /dev/null
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/paging/PagingTest.java
@@ -0,0 +1,5731 @@
+/*
+ * 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.artemis.tests.integration.paging;
+
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.management.ManagementFactory;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
+import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
+import org.apache.activemq.artemis.api.core.Message;
+import org.apache.activemq.artemis.api.core.Pair;
+import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.api.core.client.ClientConsumer;
+import org.apache.activemq.artemis.api.core.client.ClientMessage;
+import org.apache.activemq.artemis.api.core.client.ClientProducer;
+import org.apache.activemq.artemis.api.core.client.ClientSession;
+import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
+import org.apache.activemq.artemis.api.core.client.MessageHandler;
+import org.apache.activemq.artemis.api.core.client.ServerLocator;
+import org.apache.activemq.artemis.core.client.impl.ClientConsumerInternal;
+import org.apache.activemq.artemis.core.config.Configuration;
+import org.apache.activemq.artemis.core.config.DivertConfiguration;
+import org.apache.activemq.artemis.core.filter.Filter;
+import org.apache.activemq.artemis.core.io.IOCallback;
+import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
+import org.apache.activemq.artemis.core.journal.PreparedTransactionInfo;
+import org.apache.activemq.artemis.core.journal.RecordInfo;
+import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
+import org.apache.activemq.artemis.core.paging.PagingManager;
+import org.apache.activemq.artemis.core.paging.PagingStore;
+import org.apache.activemq.artemis.core.paging.cursor.PageCursorProvider;
+import org.apache.activemq.artemis.core.paging.cursor.impl.PageCursorProviderImpl;
+import org.apache.activemq.artemis.core.paging.cursor.impl.PagePositionImpl;
+import org.apache.activemq.artemis.core.paging.impl.PagingStoreFactoryNIO;
+import org.apache.activemq.artemis.core.persistence.OperationContext;
+import org.apache.activemq.artemis.core.persistence.StorageManager;
+import org.apache.activemq.artemis.core.persistence.impl.journal.AckDescribe;
+import org.apache.activemq.artemis.core.persistence.impl.journal.DescribeJournal;
+import org.apache.activemq.artemis.core.persistence.impl.journal.DescribeJournal.ReferenceDescribe;
+import org.apache.activemq.artemis.core.persistence.impl.journal.JournalRecordIds;
+import org.apache.activemq.artemis.core.persistence.impl.journal.OperationContextImpl;
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import org.apache.activemq.artemis.core.server.Queue;
+import org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl;
+import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy;
+import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
+import org.apache.activemq.artemis.logs.AssertionLoggerHandler;
+import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManagerImpl;
+import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
+import org.jboss.logging.Logger;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class PagingTest extends ActiveMQTestBase {
+
+ private static final Logger logger = Logger.getLogger(PagingTest.class);
+
+ protected ServerLocator locator;
+ protected ActiveMQServer server;
+ protected ClientSessionFactory sf;
+ static final int MESSAGE_SIZE = 1024; // 1k
+
+ protected static final IntegrationTestLogger log = IntegrationTestLogger.LOGGER;
+
+ protected static final int RECEIVE_TIMEOUT = 5000;
+
+ protected static final int PAGE_MAX = 100 * 1024;
+
+ protected static final int PAGE_SIZE = 10 * 1024;
+
+ static final SimpleString ADDRESS = new SimpleString("SimpleAddress");
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ locator = createInVMNonHALocator();
+ }
+
+ @Test
+ public void testPageOnLargeMessageMultipleQueues() throws Exception {
+ Configuration config = createDefaultInVMConfig();
+
+ final int PAGE_MAX = 20 * 1024;
+
+ final int PAGE_SIZE = 10 * 1024;
+
+ ActiveMQServer server = createServer(true, config, PAGE_SIZE, PAGE_MAX);
+ server.start();
+
+ final int numberOfBytes = 1024;
+
+ locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
+
+ ClientSessionFactory sf = addSessionFactory(createSessionFactory(locator));
+
+ ClientSession session = sf.createSession(null, null, false, true, true, false, 0);
+
+ session.createQueue(ADDRESS, ADDRESS.concat("-0"), null, true);
+ session.createQueue(ADDRESS, ADDRESS.concat("-1"), null, true);
+
+ ClientProducer producer = session.createProducer(ADDRESS);
+
+ ClientMessage message = null;
+
+ for (int i = 0; i < 201; i++) {
+ message = session.createMessage(true);
+
+ message.getBodyBuffer().writerIndex(0);
+
+ message.getBodyBuffer().writeBytes(new byte[numberOfBytes]);
+
+ for (int j = 1; j <= numberOfBytes; j++) {
+ message.getBodyBuffer().writeInt(j);
+ }
+
+ producer.send(message);
+ }
+
+ session.close();
+
+ server.stop();
+
+ server = createServer(true, config, PAGE_SIZE, PAGE_MAX);
+ server.start();
+
+ sf = createSessionFactory(locator);
+
+ for (int ad = 0; ad < 2; ad++) {
+ session = sf.createSession(false, false, false);
+
+ ClientConsumer consumer = session.createConsumer(ADDRESS.concat("-" + ad));
+
+ session.start();
+
+ for (int i = 0; i < 201; i++) {
+ ClientMessage message2 = consumer.receive(10000);
+
+ Assert.assertNotNull(message2);
+
+ message2.acknowledge();
+
+ Assert.assertNotNull(message2);
+ }
+
+ if (ad > -1) {
+ session.commit();
+ }
+ else {
+ session.rollback();
+ for (int i = 0; i < 100; i++) {
+ ClientMessage message2 = consumer.receive(10000);
+
+ Assert.assertNotNull(message2);
+
+ message2.acknowledge();
+
+ Assert.assertNotNull(message2);
+ }
+ session.commit();
+
+ }
+
+ consumer.close();
+
+ session.close();
+ }
+ }
+
+ @Test
+ public void testPageCleanup() throws Exception {
+ clearDataRecreateServerDirs();
+
+ Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+
+ server.start();
+
+ final int numberOfMessages = 5000;
+
+ locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
+
+ sf = createSessionFactory(locator);
+
+ ClientSession session = sf.createSession(false, false, false);
+
+ session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
+
+ ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ ClientMessage message = null;
+
+ byte[] body = new byte[MESSAGE_SIZE];
+
+ ByteBuffer bb = ByteBuffer.wrap(body);
+
+ for (int j = 1; j <= MESSAGE_SIZE; j++) {
+ bb.put(getSamplebyte(j));
+ }
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ message = session.createMessage(true);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ producer.send(message);
+ if (i % 1000 == 0) {
+ session.commit();
+ }
+ }
+ session.commit();
+ producer.close();
+ session.close();
+
+ session = sf.createSession(false, false, false);
+ producer = session.createProducer(PagingTest.ADDRESS);
+ producer.send(session.createMessage(true));
+ session.rollback();
+ producer.close();
+ session.close();
+
+ session = sf.createSession(false, false, false);
+ producer = session.createProducer(PagingTest.ADDRESS);
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ message = session.createMessage(true);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ producer.send(message);
+ if (i % 1000 == 0) {
+ session.commit();
+ }
+ }
+ session.commit();
+ producer.close();
+ session.close();
+ //System.out.println("Just sent " + numberOfMessages + " messages.");
+
+ Queue queue = server.locateQueue(PagingTest.ADDRESS);
+
+ session = sf.createSession(false, false, false);
+
+ session.start();
+
+ assertEquals(numberOfMessages * 2, getMessageCount(queue));
+
+ // The consumer has to be created after the getMessageCount(queue) assertion
+ // otherwise delivery could alter the messagecount and give us a false failure
+ ClientConsumer consumer = session.createConsumer(PagingTest.ADDRESS);
+ ClientMessage msg = null;
+
+ for (int i = 0; i < numberOfMessages * 2; i++) {
+ msg = consumer.receive(1000);
+ assertNotNull(msg);
+ msg.acknowledge();
+ if (i % 500 == 0) {
+ session.commit();
+ }
+ }
+ session.commit();
+ consumer.close();
+ session.close();
+
+ sf.close();
+
+ locator.close();
+
+ assertEquals(0, getMessageCount(queue));
+
+ waitForNotPaging(queue);
+
+ server.stop();
+
+ HashMap<Integer, AtomicInteger> counts = countJournalLivingRecords(server.getConfiguration());
+
+ AtomicInteger pgComplete = counts.get((int) JournalRecordIds.PAGE_CURSOR_COMPLETE);
+
+ assertTrue(pgComplete == null || pgComplete.get() == 0);
+
+ System.out.println("pgComplete = " + pgComplete);
+ }
+
+ // First page is complete but it wasn't deleted
+ @Test
+ public void testFirstPageCompleteNotDeleted() throws Exception {
+ clearDataRecreateServerDirs();
+
+ Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+
+ server.start();
+
+ final int numberOfMessages = 20;
+
+ locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
+
+ sf = createSessionFactory(locator);
+
+ ClientSession session = sf.createSession(false, true, true);
+
+ Queue queue = server.createQueue(ADDRESS, ADDRESS, null, true, false);
+
+ queue.getPageSubscription().getPagingStore().startPaging();
+
+ ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ ClientMessage message = null;
+
+ byte[] body = new byte[MESSAGE_SIZE];
+
+ ByteBuffer bb = ByteBuffer.wrap(body);
+
+ for (int j = 1; j <= MESSAGE_SIZE; j++) {
+ bb.put(getSamplebyte(j));
+ }
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ message = session.createMessage(true);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ message.putIntProperty("count", i);
+
+ producer.send(message);
+
+ if ((i + 1) % 5 == 0) {
+ session.commit();
+ queue.getPageSubscription().getPagingStore().forceAnotherPage();
+ }
+ }
+
+ session.commit();
+ producer.close();
+ session.close();
+
+ // This will make the cursor to set the page complete and not actually delete it
+ queue.getPageSubscription().getPagingStore().disableCleanup();
+
+ session = sf.createSession(false, false, false);
+
+ ClientConsumer consumer = session.createConsumer(ADDRESS);
+ session.start();
+
+ for (int i = 0; i < 5; i++) {
+ ClientMessage msg = consumer.receive(2000);
+ assertNotNull(msg);
+ assertEquals(i, msg.getIntProperty("count").intValue());
+
+ msg.individualAcknowledge();
+
+ System.out.println(msg);
+ }
+
+ session.commit();
+
+ session.close();
+
+ server.stop();
+
+ server.start();
+
+ sf = createSessionFactory(locator);
+
+ session = sf.createSession(false, false, false);
+
+ consumer = session.createConsumer(ADDRESS);
+ session.start();
+
+ for (int i = 5; i < numberOfMessages; i++) {
+ ClientMessage msg = consumer.receive(2000);
+ assertNotNull(msg);
+ assertEquals(i, msg.getIntProperty("count").intValue());
+ msg.acknowledge();
+ System.out.println(msg);
+ }
+
+ assertNull(consumer.receiveImmediate());
+ session.commit();
+
+ session.close();
+ sf.close();
+ locator.close();
+
+ }
+
+ @Test
+ public void testPreparedACKAndRestart() throws Exception {
+ clearDataRecreateServerDirs();
+
+ Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+
+ server.start();
+
+ final int numberOfMessages = 50;
+
+ locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setAckBatchSize(0);
+
+ sf = createSessionFactory(locator);
+
+ ClientSession session = sf.createSession(false, true, true);
+
+ session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
+
+ Queue queue = server.locateQueue(PagingTest.ADDRESS);
+
+ ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ byte[] body = new byte[MESSAGE_SIZE];
+
+ ByteBuffer bb = ByteBuffer.wrap(body);
+
+ for (int j = 1; j <= MESSAGE_SIZE; j++) {
+ bb.put(getSamplebyte(j));
+ }
+
+ queue.getPageSubscription().getPagingStore().startPaging();
+
+ forcePage(queue);
+
+ // Send many messages, 5 on each page
+ for (int i = 0; i < numberOfMessages; i++) {
+ ClientMessage message = session.createMessage(true);
+
+ message.putIntProperty("count", i);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ producer.send(message);
+
+ if ((i + 1) % 5 == 0) {
+ System.out.println("Forcing at " + i);
+ session.commit();
+ queue.getPageSubscription().getPagingStore().forceAnotherPage();
+ }
+ }
+
+ session.close();
+
+ session = sf.createSession(true, false, false);
+
+ Xid xidConsumeNoCommit = newXID();
+ session.start(xidConsumeNoCommit, XAResource.TMNOFLAGS);
+
+ ClientConsumer cons = session.createConsumer(ADDRESS);
+
+ session.start();
+
+ // First message is consumed, prepared, will be rolled back later
+ ClientMessage firstMessageConsumed = cons.receive(5000);
+ assertNotNull(firstMessageConsumed);
+ firstMessageConsumed.acknowledge();
+
+ session.end(xidConsumeNoCommit, XAResource.TMSUCCESS);
+
+ session.prepare(xidConsumeNoCommit);
+
+ Xid xidConsumeCommit = newXID();
+ session.start(xidConsumeCommit, XAResource.TMNOFLAGS);
+
+ Xid neverCommittedXID = newXID();
+
+ for (int i = 1; i < numberOfMessages; i++) {
+ if (i == 20) {
+ // I elected a single message to be in prepared state, it won't ever be committed
+ session.end(xidConsumeCommit, XAResource.TMSUCCESS);
+ session.commit(xidConsumeCommit, true);
+ session.start(neverCommittedXID, XAResource.TMNOFLAGS);
+ }
+ ClientMessage message = cons.receive(5000);
+ assertNotNull(message);
+ System.out.println("ACK " + i);
+ message.acknowledge();
+ assertEquals(i, message.getIntProperty("count").intValue());
+ if (i == 20) {
+ session.end(neverCommittedXID, XAResource.TMSUCCESS);
+ session.prepare(neverCommittedXID);
+ xidConsumeCommit = newXID();
+ session.start(xidConsumeCommit, XAResource.TMNOFLAGS);
+ }
+ }
+
+ session.end(xidConsumeCommit, XAResource.TMSUCCESS);
+
+ session.commit(xidConsumeCommit, true);
+
+ session.close();
+ sf.close();
+
+ // Restart the server, and we expect cleanup to not destroy any page with prepared data
+ server.stop();
+
+ server.start();
+
+ sf = createSessionFactory(locator);
+
+ session = sf.createSession(false, true, true);
+
+ queue = server.locateQueue(ADDRESS);
+
+ assertTrue(queue.getPageSubscription().getPagingStore().isPaging());
+
+ producer = session.createProducer(ADDRESS);
+
+ for (int i = numberOfMessages; i < numberOfMessages * 2; i++) {
+ ClientMessage message = session.createMessage(true);
+
+ message.putIntProperty("count", i);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ producer.send(message);
+
+ if ((i + 1) % 5 == 0) {
+ session.commit();
+ queue.getPageSubscription().getPagingStore().forceAnotherPage();
+ }
+ }
+
+ cons = session.createConsumer(ADDRESS);
+
+ session.start();
+
+ for (int i = numberOfMessages; i < numberOfMessages * 2; i++) {
+ ClientMessage message = cons.receive(5000);
+ assertNotNull(message);
+ assertEquals(i, message.getIntProperty("count").intValue());
+ message.acknowledge();
+ }
+ assertNull(cons.receiveImmediate());
+ session.commit();
+
+ System.out.println("count = " + getMessageCount(queue));
+
+ session.commit();
+
+ session.close();
+
+ session = sf.createSession(true, false, false);
+
+ session.rollback(xidConsumeNoCommit);
+
+ session.start();
+
+ xidConsumeCommit = newXID();
+
+ session.start(xidConsumeCommit, XAResource.TMNOFLAGS);
+ cons = session.createConsumer(ADDRESS);
+
+ session.start();
+
+ ClientMessage message = cons.receive(5000);
+ assertNotNull(message);
+ message.acknowledge();
+
+ session.end(xidConsumeCommit, XAResource.TMSUCCESS);
+
+ session.commit(xidConsumeCommit, true);
+
+ session.close();
+ }
+
+ /**
+ * @param queue
+ * @throws InterruptedException
+ */
+ private void forcePage(Queue queue) throws InterruptedException {
+ for (long timeout = System.currentTimeMillis() + 5000; timeout > System.currentTimeMillis() && !queue.getPageSubscription().getPagingStore().isPaging(); ) {
+ Thread.sleep(10);
+ }
+ assertTrue(queue.getPageSubscription().getPagingStore().isPaging());
+ }
+
+ @Test
+ public void testMoveExpire() throws Exception {
+ clearDataRecreateServerDirs();
+
+ Configuration config = createDefaultInVMConfig().setJournalDirectory(getJournalDir()).setJournalSyncNonTransactional(false).setJournalCompactMinFiles(0) // disable compact
+ .setMessageExpiryScanPeriod(500);
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+
+ AddressSettings defaultSetting = new AddressSettings().setPageSizeBytes(PAGE_SIZE).setMaxSizeBytes(PAGE_MAX).setExpiryAddress(new SimpleString("EXP")).setAddressFullMessagePolicy(AddressFullMessagePolicy.PAGE);
+
+ server.getAddressSettingsRepository().clear();
+
+ server.getAddressSettingsRepository().addMatch("#", defaultSetting);
+
+ server.start();
+
+ final int numberOfMessages = 5000;
+
+ locator = createInVMNonHALocator().setConsumerWindowSize(10 * 1024 * 1024).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
+
+ ClientSessionFactory sf = locator.createSessionFactory();
+
+ ClientSession session = sf.createSession(false, false, false);
+
+ session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
+
+ session.createQueue("EXP", "EXP", null, true);
+
+ Queue queue1 = server.locateQueue(ADDRESS);
+ Queue qEXP = server.locateQueue(new SimpleString("EXP"));
+
+ ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ final int MESSAGE_SIZE = 1024;
+
+ byte[] body = new byte[MESSAGE_SIZE];
+
+ ByteBuffer bb = ByteBuffer.wrap(body);
+
+ for (int j = 1; j <= MESSAGE_SIZE; j++) {
+ bb.put(getSamplebyte(j));
+ }
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ ClientMessage message = session.createMessage(true);
+
+ if (i < 1000) {
+ message.setExpiration(System.currentTimeMillis() + 1000);
+ }
+
+ message.putIntProperty("tst-count", i);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ producer.send(message);
+ if (i % 1000 == 0) {
+ session.commit();
+ }
+ }
+ session.commit();
+ producer.close();
+
+ for (long timeout = System.currentTimeMillis() + 60000; timeout > System.currentTimeMillis() && getMessageCount(qEXP) < 1000; ) {
+ System.out.println("count = " + getMessageCount(qEXP));
+ Thread.sleep(100);
+ }
+
+ assertEquals(1000, getMessageCount(qEXP));
+
+ session.start();
+
+ ClientConsumer consumer = session.createConsumer(ADDRESS);
+
+ for (int i = 0; i < numberOfMessages - 1000; i++) {
+ ClientMessage message = consumer.receive(5000);
+ assertNotNull(message);
+ message.acknowledge();
+ assertTrue(message.getIntProperty("tst-count") >= 1000);
+ }
+
+ session.commit();
+
+ assertNull(consumer.receiveImmediate());
+
+ for (long timeout = System.currentTimeMillis() + 5000; timeout > System.currentTimeMillis() && getMessageCount(queue1) != 0; ) {
+ Thread.sleep(100);
+ }
+ assertEquals(0, getMessageCount(queue1));
+
+ consumer.close();
+
+ consumer = session.createConsumer("EXP");
+
+ for (int i = 0; i < 1000; i++) {
+ ClientMessage message = consumer.receive(5000);
+ assertNotNull(message);
+ message.acknowledge();
+ assertTrue(message.getIntProperty("tst-count") < 1000);
+ }
+
+ assertNull(consumer.receiveImmediate());
+
+ // This is just to hold some messages as being delivered
+ ClientConsumerInternal cons = (ClientConsumerInternal) session.createConsumer(ADDRESS);
+
+ session.commit();
+ producer.close();
+ session.close();
+
+ server.stop();
+ }
+
+ @Test
+ public void testDeleteQueueRestart() throws Exception {
+ clearDataRecreateServerDirs();
+
+ Configuration config = createDefaultInVMConfig().setJournalDirectory(getJournalDir()).setJournalSyncNonTransactional(false).setJournalCompactMinFiles(0); // disable compact
+
+ ActiveMQServer server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+
+ server.start();
+
+ final int numberOfMessages = 5000;
+
+ locator = createInVMNonHALocator().setConsumerWindowSize(10 * 1024 * 1024).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
+
+ SimpleString QUEUE2 = ADDRESS.concat("-2");
+
+ ClientSessionFactory sf = locator.createSessionFactory();
+
+ ClientSession session = sf.createSession(false, false, false);
+
+ session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
+
+ session.createQueue(PagingTest.ADDRESS, QUEUE2, null, true);
+
+ ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ // This is just to hold some messages as being delivered
+ ClientConsumerInternal cons = (ClientConsumerInternal) session.createConsumer(ADDRESS);
+ ClientConsumerInternal cons2 = (ClientConsumerInternal) session.createConsumer(QUEUE2);
+
+ ClientMessage message = null;
+
+ byte[] body = new byte[MESSAGE_SIZE];
+
+ ByteBuffer bb = ByteBuffer.wrap(body);
+
+ for (int j = 1; j <= MESSAGE_SIZE; j++) {
+ bb.put(getSamplebyte(j));
+ }
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ message = session.createMessage(true);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ producer.send(message);
+ if (i % 1000 == 0) {
+ session.commit();
+ }
+ }
+ session.commit();
+ producer.close();
+ session.start();
+
+ long timeout = System.currentTimeMillis() + 30000;
+
+ // I want the buffer full to make sure there are pending messages on the server's side
+ while (System.currentTimeMillis() < timeout && (cons.getBufferSize() < 1000 || cons2.getBufferSize() < 1000)) {
+ System.out.println("cons1 buffer = " + cons.getBufferSize() + ", cons2 buffer = " + cons2.getBufferSize());
+ Thread.sleep(100);
+ }
+
+ assertTrue(cons.getBufferSize() >= 1000);
+ assertTrue(cons2.getBufferSize() >= 1000);
+
+ session.close();
+
+ Queue queue = server.locateQueue(QUEUE2);
+
+ long deletedQueueID = queue.getID();
+
+ server.destroyQueue(QUEUE2);
+
+ sf.close();
+ locator.close();
+ locator = null;
+ sf = null;
+
+ server.stop();
+
+ final HashMap<Integer, AtomicInteger> recordsType = countJournal(config);
+
+ for (Map.Entry<Integer, AtomicInteger> entry : recordsType.entrySet()) {
+ System.out.println(entry.getKey() + "=" + entry.getValue());
+ }
+
+ assertNull("The system is acking page records instead of just delete data", recordsType.get(new Integer(JournalRecordIds.ACKNOWLEDGE_CURSOR)));
+
+ Pair<List<RecordInfo>, List<PreparedTransactionInfo>> journalData = loadMessageJournal(config);
+
+ HashSet<Long> deletedQueueReferences = new HashSet<>();
+
+ for (RecordInfo info : journalData.getA()) {
+ if (info.getUserRecordType() == JournalRecordIds.ADD_REF) {
+ DescribeJournal.ReferenceDescribe ref = (ReferenceDescribe) DescribeJournal.newObjectEncoding(info);
+
+ if (ref.refEncoding.queueID == deletedQueueID) {
+ deletedQueueReferences.add(new Long(info.id));
+ }
+ }
+ else if (info.getUserRecordType() == JournalRecordIds.ACKNOWLEDGE_REF) {
+ AckDescribe ref = (AckDescribe) DescribeJournal.newObjectEncoding(info);
+
+ if (ref.refEncoding.queueID == deletedQueueID) {
+ deletedQueueReferences.remove(new Long(info.id));
+ }
+ }
+ }
+
+ if (!deletedQueueReferences.isEmpty()) {
+ for (Long value : deletedQueueReferences) {
+ System.out.println("Deleted Queue still has a reference:" + value);
+ }
+
+ fail("Deleted queue still have references");
+ }
+
+ server.start();
+
+ locator = createInVMNonHALocator();
+ locator.setConsumerWindowSize(10 * 1024 * 1024);
+ sf = locator.createSessionFactory();
+ session = sf.createSession(false, false, false);
+ cons = (ClientConsumerInternal) session.createConsumer(ADDRESS);
+ session.start();
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ message = cons.receive(5000);
+ assertNotNull(message);
+ message.acknowledge();
+ if (i % 1000 == 0) {
+ session.commit();
+ }
+ }
+ session.commit();
+ producer.close();
+ session.close();
+
+ queue = server.locateQueue(PagingTest.ADDRESS);
+
+ assertEquals(0, getMessageCount(queue));
+
+ timeout = System.currentTimeMillis() + 10000;
+ while (timeout > System.currentTimeMillis() && queue.getPageSubscription().getPagingStore().isPaging()) {
+ Thread.sleep(100);
+ }
+ assertFalse(queue.getPageSubscription().getPagingStore().isPaging());
+
+ server.stop();
+ }
+
+ @Test
+ public void testPreparePersistent() throws Exception {
+ clearDataRecreateServerDirs();
+
+ Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+
+ server.start();
+
+ final int numberOfMessages = 5000;
+
+ final int numberOfTX = 10;
+
+ final int messagesPerTX = numberOfMessages / numberOfTX;
+
+ locator = createInVMNonHALocator();
+
+ locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
+
+ sf = createSessionFactory(locator);
+
+ ClientSession session = sf.createSession(false, false, false);
+
+ session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
+
+ ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ ClientMessage message = null;
+
+ byte[] body = new byte[MESSAGE_SIZE];
+
+ ByteBuffer bb = ByteBuffer.wrap(body);
+
+ for (int j = 1; j <= MESSAGE_SIZE; j++) {
+ bb.put(getSamplebyte(j));
+ }
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ message = session.createMessage(true);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ message.putIntProperty(new SimpleString("id"), i);
+
+ producer.send(message);
+ if (i % 1000 == 0) {
+ session.commit();
+ }
+ }
+ session.commit();
+ session.close();
+ session = null;
+
+ sf.close();
+ locator.close();
+
+ server.stop();
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+ server.start();
+
+ locator = createInVMNonHALocator();
+ sf = createSessionFactory(locator);
+
+ Queue queue = server.locateQueue(ADDRESS);
+
+ assertEquals(numberOfMessages, getMessageCount(queue));
+
+ LinkedList<Xid> xids = new LinkedList<>();
+
+ int msgReceived = 0;
+ for (int i = 0; i < numberOfTX; i++) {
+ ClientSession sessionConsumer = sf.createSession(true, false, false);
+ Xid xid = newXID();
+ xids.add(xid);
+ sessionConsumer.start(xid, XAResource.TMNOFLAGS);
+ sessionConsumer.start();
+ ClientConsumer consumer = sessionConsumer.createConsumer(PagingTest.ADDRESS);
+ for (int msgCount = 0; msgCount < messagesPerTX; msgCount++) {
+ if (msgReceived == numberOfMessages) {
+ break;
+ }
+ msgReceived++;
+ ClientMessage msg = consumer.receive(10000);
+ assertNotNull(msg);
+ msg.acknowledge();
+ }
+ sessionConsumer.end(xid, XAResource.TMSUCCESS);
+ sessionConsumer.prepare(xid);
+ sessionConsumer.close();
+ }
+
+ ClientSession sessionCheck = sf.createSession(true, true);
+
+ ClientConsumer consumer = sessionCheck.createConsumer(PagingTest.ADDRESS);
+
+ assertNull(consumer.receiveImmediate());
+
+ sessionCheck.close();
+
+ assertEquals(numberOfMessages, getMessageCount(queue));
+
+ sf.close();
+ locator.close();
+
+ server.stop();
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+ server.start();
+
+ waitForServerToStart(server);
+
+ queue = server.locateQueue(ADDRESS);
+
+ locator = createInVMNonHALocator();
+ sf = createSessionFactory(locator);
+
+ session = sf.createSession(true, false, false);
+
+ consumer = session.createConsumer(PagingTest.ADDRESS);
+
+ session.start();
+
+ assertEquals(numberOfMessages, getMessageCount(queue));
+
+ ClientMessage msg = consumer.receive(5000);
+ if (msg != null) {
+ while (true) {
+ ClientMessage msg2 = consumer.receive(1000);
+ if (msg2 == null) {
+ break;
+ }
+ }
+ }
+ assertNull(msg);
+
+ for (int i = xids.size() - 1; i >= 0; i--) {
+ Xid xid = xids.get(i);
+ session.rollback(xid);
+ }
+
+ xids.clear();
+
+ session.close();
+
+ session = sf.createSession(false, false, false);
+
+ session.start();
+
+ consumer = session.createConsumer(PagingTest.ADDRESS);
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ msg = consumer.receive(1000);
+ assertNotNull(msg);
+ msg.acknowledge();
+
+ assertEquals(i, msg.getIntProperty("id").intValue());
+
+ if (i % 500 == 0) {
+ session.commit();
+ }
+ }
+
+ session.commit();
+
+ session.close();
+
+ sf.close();
+
+ locator.close();
+
+ assertEquals(0, getMessageCount(queue));
+
+ waitForNotPaging(queue);
+ }
+
+ @Test
+ public void testSendOverBlockingNoFlowControl() throws Exception {
+ clearDataRecreateServerDirs();
+
+ Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+ server.getAddressSettingsRepository().getMatch("#").setAddressFullMessagePolicy(AddressFullMessagePolicy.BLOCK);
+
+ server.start();
+
+ final int biggerMessageSize = 10 * 1024;
+
+ final int numberOfMessages = 500;
+
+ locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setProducerWindowSize(-1).setMinLargeMessageSize(1024 * 1024);
+
+ sf = createSessionFactory(locator);
+
+ ClientSession session = sf.createSession(false, false, false);
+
+ session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
+
+ ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ ClientMessage message = null;
+
+ byte[] body = new byte[biggerMessageSize];
+
+ ByteBuffer bb = ByteBuffer.wrap(body);
+
+ for (int j = 1; j <= biggerMessageSize; j++) {
+ bb.put(getSamplebyte(j));
+ }
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ message = session.createMessage(true);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ message.putIntProperty(new SimpleString("id"), i);
+
+ producer.send(message);
+
+ if (i % 10 == 0) {
+ session.commit();
+ }
+ }
+ session.commit();
+
+ session.start();
+
+ ClientConsumer cons = session.createConsumer(ADDRESS);
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ message = cons.receive(5000);
+ assertNotNull(message);
+ message.acknowledge();
+
+ if (i % 10 == 0) {
+ session.commit();
+ }
+ }
+
+ session.commit();
+
+ }
+
+ @Test
+ public void testReceiveImmediate() throws Exception {
+ clearDataRecreateServerDirs();
+
+ Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+
+ server.start();
+
+ final int numberOfMessages = 1000;
+
+ locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
+
+ sf = createSessionFactory(locator);
+
+ ClientSession session = sf.createSession(false, false, false);
+
+ session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
+
+ ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ ClientMessage message = null;
+
+ byte[] body = new byte[MESSAGE_SIZE];
+
+ ByteBuffer bb = ByteBuffer.wrap(body);
+
+ for (int j = 1; j <= MESSAGE_SIZE; j++) {
+ bb.put(getSamplebyte(j));
+ }
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ message = session.createMessage(true);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ message.putIntProperty(new SimpleString("id"), i);
+
+ producer.send(message);
+ if (i % 1000 == 0) {
+ session.commit();
+ }
+ }
+ session.commit();
+ session.close();
+
+ session = null;
+
+ sf.close();
+ locator.close();
+
+ server.stop();
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+ server.start();
+
+ locator = createInVMNonHALocator();
+ sf = createSessionFactory(locator);
+
+ Queue queue = server.locateQueue(ADDRESS);
+
+ assertEquals(numberOfMessages, getMessageCount(queue));
+
+ int msgReceived = 0;
+ ClientSession sessionConsumer = sf.createSession(false, false, false);
+ sessionConsumer.start();
+ ClientConsumer consumer = sessionConsumer.createConsumer(PagingTest.ADDRESS);
+ for (int msgCount = 0; msgCount < numberOfMessages; msgCount++) {
+ log.info("Received " + msgCount);
+ msgReceived++;
+ ClientMessage msg = consumer.receiveImmediate();
+ if (msg == null) {
+ log.info("It's null. leaving now");
+ sessionConsumer.commit();
+ fail("Didn't receive a message");
+ }
+ msg.acknowledge();
+
+ if (msgCount % 5 == 0) {
+ log.info("commit");
+ sessionConsumer.commit();
+ }
+ }
+
+ sessionConsumer.commit();
+
+ sessionConsumer.close();
+
+ sf.close();
+
+ locator.close();
+
+ assertEquals(0, getMessageCount(queue));
+
+ long timeout = System.currentTimeMillis() + 5000;
+ while (timeout > System.currentTimeMillis() && queue.getPageSubscription().getPagingStore().isPaging()) {
+ Thread.sleep(100);
+ }
+ assertFalse(queue.getPageSubscription().getPagingStore().isPaging());
+
+ }
+
+ /**
+ * This test will remove all the page directories during a restart, simulating a crash scenario. The server should still start after this
+ */
+ @Test
+ public void testDeletePhysicalPages() throws Exception {
+ clearDataRecreateServerDirs();
+
+ Configuration config = createDefaultInVMConfig().setPersistDeliveryCountBeforeDelivery(true);
+
+ config.setJournalSyncNonTransactional(false);
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+
+ server.start();
+
+ final int numberOfMessages = 1000;
+
+ locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
+
+ sf = createSessionFactory(locator);
+
+ ClientSession session = sf.createSession(false, false, false);
+
+ session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
+
+ ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ ClientMessage message = null;
+
+ byte[] body = new byte[MESSAGE_SIZE];
+
+ ByteBuffer bb = ByteBuffer.wrap(body);
+
+ for (int j = 1; j <= MESSAGE_SIZE; j++) {
+ bb.put(getSamplebyte(j));
+ }
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ message = session.createMessage(true);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ message.putIntProperty(new SimpleString("id"), i);
+
+ producer.send(message);
+ if (i % 1000 == 0) {
+ session.commit();
+ }
+ }
+ session.commit();
+ session.close();
+
+ session = null;
+
+ sf.close();
+ locator.close();
+
+ server.stop();
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+ server.start();
+
+ locator = createInVMNonHALocator();
+ sf = createSessionFactory(locator);
+
+ Queue queue = server.locateQueue(ADDRESS);
+
+ assertEquals(numberOfMessages, getMessageCount(queue));
+
+ int msgReceived = 0;
+ ClientSession sessionConsumer = sf.createSession(false, false, false);
+ sessionConsumer.start();
+ ClientConsumer consumer = sessionConsumer.createConsumer(PagingTest.ADDRESS);
+ for (int msgCount = 0; msgCount < numberOfMessages; msgCount++) {
+ log.info("Received " + msgCount);
+ msgReceived++;
+ ClientMessage msg = consumer.receiveImmediate();
+ if (msg == null) {
+ log.info("It's null. leaving now");
+ sessionConsumer.commit();
+ fail("Didn't receive a message");
+ }
+ msg.acknowledge();
+
+ if (msgCount % 5 == 0) {
+ log.info("commit");
+ sessionConsumer.commit();
+ }
+ }
+
+ sessionConsumer.commit();
+
+ sessionConsumer.close();
+
+ sf.close();
+
+ locator.close();
+
+ assertEquals(0, getMessageCount(queue));
+
+ long timeout = System.currentTimeMillis() + 5000;
+ while (timeout > System.currentTimeMillis() && queue.getPageSubscription().getPagingStore().isPaging()) {
+ Thread.sleep(100);
+ }
+ assertFalse(queue.getPageSubscription().getPagingStore().isPaging());
+
+ server.stop();
+
+ // Deleting the paging data. Simulating a failure
+ // a dumb user, or anything that will remove the data
+ deleteDirectory(new File(getPageDir()));
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+ server.start();
+
+ locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
+
+ sf = createSessionFactory(locator);
+
+ queue = server.locateQueue(ADDRESS);
+
+ sf = createSessionFactory(locator);
+ session = sf.createSession(false, false, false);
+
+ producer = session.createProducer(PagingTest.ADDRESS);
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ message = session.createMessage(true);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ message.putIntProperty(new SimpleString("id"), i);
+
+ producer.send(message);
+ if (i % 1000 == 0) {
+ session.commit();
+ }
+ }
+
+ session.commit();
+
+ server.stop();
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+ server.start();
+
+ locator = createInVMNonHALocator();
+ sf = createSessionFactory(locator);
+
+ queue = server.locateQueue(ADDRESS);
+
+ // assertEquals(numberOfMessages, getMessageCount(queue));
+
+ msgReceived = 0;
+ sessionConsumer = sf.createSession(false, false, false);
+ sessionConsumer.start();
+ consumer = sessionConsumer.createConsumer(PagingTest.ADDRESS);
+ for (int msgCount = 0; msgCount < numberOfMessages; msgCount++) {
+ log.info("Received " + msgCount);
+ msgReceived++;
+ ClientMessage msg = consumer.receiveImmediate();
+ if (msg == null) {
+ log.info("It's null. leaving now");
+ sessionConsumer.commit();
+ fail("Didn't receive a message");
+ }
+ msg.acknowledge();
+
+ if (msgCount % 5 == 0) {
+ log.info("commit");
+ sessionConsumer.commit();
+ }
+ }
+
+ sessionConsumer.commit();
+
+ sessionConsumer.close();
+
+ }
+
+ @Test
+ public void testMissingTXEverythingAcked() throws Exception {
+ clearDataRecreateServerDirs();
+
+ Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+
+ server.start();
+
+ final int numberOfMessages = 5000;
+
+ final int numberOfTX = 10;
+
+ final int messagesPerTX = numberOfMessages / numberOfTX;
+
+ try {
+ locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
+
+ sf = createSessionFactory(locator);
+
+ ClientSession session = sf.createSession(false, false, false);
+
+ session.createQueue(ADDRESS.toString(), "q1", true);
+
+ session.createQueue(ADDRESS.toString(), "q2", true);
+
+ ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ ClientMessage message = null;
+
+ byte[] body = new byte[MESSAGE_SIZE];
+
+ ByteBuffer bb = ByteBuffer.wrap(body);
+
+ for (int j = 1; j <= MESSAGE_SIZE; j++) {
+ bb.put(getSamplebyte(j));
+ }
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ message = session.createMessage(true);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ message.putIntProperty(new SimpleString("id"), i);
+
+ producer.send(message);
+ if (i % messagesPerTX == 0) {
+ session.commit();
+ }
+ }
+ session.commit();
+ session.close();
+ }
+ finally {
+ try {
+ server.stop();
+ }
+ catch (Throwable ignored) {
+ }
+ }
+
+ ArrayList<RecordInfo> records = new ArrayList<>();
+
+ List<PreparedTransactionInfo> list = new ArrayList<>();
+
+ JournalImpl jrn = new JournalImpl(config.getJournalFileSize(), 2, 2, 0, 0, new NIOSequentialFileFactory(server.getConfiguration().getJournalLocation(), 1), "activemq-data", "amq", 1);
+ jrn.start();
+ jrn.load(records, list, null);
+
+ // Delete everything from the journal
+ for (RecordInfo info : records) {
+ if (!info.isUpdate && info.getUserRecordType() != JournalRecordIds.PAGE_CURSOR_COUNTER_VALUE &&
+ info.getUserRecordType() != JournalRecordIds.PAGE_CURSOR_COUNTER_INC &&
+ info.getUserRecordType() != JournalRecordIds.PAGE_CURSOR_COMPLETE) {
+ jrn.appendDeleteRecord(info.id, false);
+ }
+ }
+
+ jrn.stop();
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+
+ server.start();
+
+ ClientSessionFactory csf = createSessionFactory(locator);
+
+ ClientSession sess = csf.createSession();
+
+ sess.start();
+
+ ClientConsumer cons = sess.createConsumer("q1");
+
+ assertNull(cons.receiveImmediate());
+
+ ClientConsumer cons2 = sess.createConsumer("q2");
+ assertNull(cons2.receiveImmediate());
+
+ Queue q1 = server.locateQueue(new SimpleString("q1"));
+ Queue q2 = server.locateQueue(new SimpleString("q2"));
+
+ q1.getPageSubscription().cleanupEntries(false);
+ q2.getPageSubscription().cleanupEntries(false);
+
+ PageCursorProvider provider = q1.getPageSubscription().getPagingStore().getCursorProvider();
+ provider.cleanup();
+
+ waitForNotPaging(q1);
+
+ sess.close();
+ }
+
+ @Test
+ public void testMissingTXEverythingAcked2() throws Exception {
+ clearDataRecreateServerDirs();
+
+ Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+
+ server.start();
+
+ final int numberOfMessages = 6;
+
+ final int numberOfTX = 2;
+
+ final int messagesPerTX = numberOfMessages / numberOfTX;
+
+ try {
+ locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
+
+ sf = createSessionFactory(locator);
+
+ ClientSession session = sf.createSession(false, false, false);
+
+ session.createQueue(ADDRESS.toString(), "q1", true);
+
+ session.createQueue(ADDRESS.toString(), "q2", true);
+
+ server.getPagingManager().getPageStore(ADDRESS).startPaging();
+
+ ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ ClientMessage message = null;
+
+ byte[] body = new byte[MESSAGE_SIZE];
+
+ ByteBuffer bb = ByteBuffer.wrap(body);
+
+ for (int j = 1; j <= MESSAGE_SIZE; j++) {
+ bb.put(getSamplebyte(j));
+ }
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ message = session.createMessage(true);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ message.putStringProperty("id", "str-" + i);
+
+ producer.send(message);
+ if ((i + 1) % messagesPerTX == 0) {
+ session.commit();
+ }
+ }
+ session.commit();
+
+ session.start();
+
+ for (int i = 1; i <= 2; i++) {
+ ClientConsumer cons = session.createConsumer("q" + i);
+
+ for (int j = 0; j < 3; j++) {
+ ClientMessage msg = cons.receive(5000);
+
+ assertNotNull(msg);
+
+ assertEquals("str-" + j, msg.getStringProperty("id"));
+
+ msg.acknowledge();
+ }
+
+ session.commit();
+
+ }
+
+ session.close();
+ }
+ finally {
+ locator.close();
+ try {
+ server.stop();
+ }
+ catch (Throwable ignored) {
+ }
+ }
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+
+ server.start();
+
+ locator = createInVMNonHALocator();
+
+ locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
+
+ ClientSessionFactory csf = createSessionFactory(locator);
+
+ ClientSession session = csf.createSession();
+
+ session.start();
+
+ for (int i = 1; i <= 2; i++) {
+ ClientConsumer cons = session.createConsumer("q" + i);
+
+ for (int j = 3; j < 6; j++) {
+ ClientMessage msg = cons.receive(5000);
+
+ assertNotNull(msg);
+
+ assertEquals("str-" + j, msg.getStringProperty("id"));
+
+ msg.acknowledge();
+ }
+
+ session.commit();
+ assertNull(cons.receive(500));
+
+ }
+
+ session.close();
+
+ long timeout = System.currentTimeMillis() + 5000;
+
+ while (System.currentTimeMillis() < timeout && server.getPagingManager().getPageStore(ADDRESS).isPaging()) {
+ Thread.sleep(100);
+ }
+ }
+
+ @Test
+ public void testTwoQueuesOneNoRouting() throws Exception {
+ boolean persistentMessages = true;
+
+ clearDataRecreateServerDirs();
+
+ Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+
+ server.start();
+
+ final int numberOfMessages = 1000;
+
+ locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
+
+ sf = createSessionFactory(locator);
+
+ ClientSession session = sf.createSession(false, false, false);
+
+ session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
+ session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS.concat("-invalid"), new SimpleString(ActiveMQServerImpl.GENERIC_IGNORED_FILTER), true);
+
+ ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ ClientMessage message = null;
+
+ byte[] body = new byte[MESSAGE_SIZE];
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ message = session.createMessage(persistentMessages);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ message.putIntProperty(new SimpleString("id"), i);
+
+ producer.send(message);
+ if (i % 1000 == 0) {
+ session.commit();
+ }
+ }
+
+ session.commit();
+
+ session.start();
+
+ ClientConsumer consumer = session.createConsumer(PagingTest.ADDRESS);
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ message = consumer.receive(5000);
+ assertNotNull(message);
+ message.acknowledge();
+
+ assertEquals(i, message.getIntProperty("id").intValue());
+ if (i % 1000 == 0) {
+ session.commit();
+ }
+ }
+
+ session.commit();
+
+ session.commit();
+
+ session.commit();
+
+ PagingStore store = server.getPagingManager().getPageStore(ADDRESS);
+ store.getCursorProvider().cleanup();
+
+ long timeout = System.currentTimeMillis() + 5000;
+ while (store.isPaging() && timeout > System.currentTimeMillis()) {
+ Thread.sleep(100);
+ }
+
+ // It's async, so need to wait a bit for it happening
+ assertFalse(server.getPagingManager().getPageStore(ADDRESS).isPaging());
+ }
+
+ @Test
+ public void testSendReceivePagingPersistent() throws Exception {
+ internaltestSendReceivePaging(true);
+ }
+
+ @Test
+ public void testSendReceivePagingNonPersistent() throws Exception {
+ internaltestSendReceivePaging(false);
+ }
+
+ @Test
+ public void testWithDiverts() throws Exception {
+ internalMultiQueuesTest(true);
+ }
+
+ @Test
+ public void testWithMultiQueues() throws Exception {
+ internalMultiQueuesTest(false);
+ }
+
+ public void internalMultiQueuesTest(final boolean divert) throws Exception {
+ clearDataRecreateServerDirs();
+
+ Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+
+ if (divert) {
+ DivertConfiguration divert1 = new DivertConfiguration().setName("dv1").setRoutingName("nm1").setAddress(PagingTest.ADDRESS.toString()).setForwardingAddress(PagingTest.ADDRESS.toString() + "-1").setExclusive(true);
+
+ config.addDivertConfiguration(divert1);
+
+ DivertConfiguration divert2 = new DivertConfiguration().setName("dv2").setRoutingName("nm2").setAddress(PagingTest.ADDRESS.toString()).setForwardingAddress(PagingTest.ADDRESS.toString() + "-2").setExclusive(true);
+
+ config.addDivertConfiguration(divert2);
+ }
+
+ server.start();
+
+ final int numberOfMessages = 3000;
+
+ final byte[] body = new byte[MESSAGE_SIZE];
+
+ ByteBuffer bb = ByteBuffer.wrap(body);
+
+ for (int j = 1; j <= MESSAGE_SIZE; j++) {
+ bb.put(getSamplebyte(j));
+ }
+
+ final AtomicBoolean running = new AtomicBoolean(true);
+
+ class TCount extends Thread {
+
+ Queue queue;
+
+ TCount(Queue queue) {
+ this.queue = queue;
+ }
+
+ @Override
+ public void run() {
+ try {
+ while (running.get()) {
+ // this will be overusing what some users do. flush / getCount
+ getMessagesAdded(queue);
+ getMessageCount(queue);
+ Thread.sleep(10);
+ }
+ }
+ catch (InterruptedException e) {
+ log.info("Thread interrupted");
+ }
+ }
+ }
+
+ TCount tcount1 = null;
+ TCount tcount2 = null;
+
+ try {
+ {
+ locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
+
+ sf = createSessionFactory(locator);
+
+ ClientSession session = sf.createSession(false, false, false);
+
+ if (divert) {
+ session.createQueue(PagingTest.ADDRESS + "-1", PagingTest.ADDRESS + "-1", null, true);
+
+ session.createQueue(PagingTest.ADDRESS + "-2", PagingTest.ADDRESS + "-2", null, true);
+ }
+ else {
+ session.createQueue(PagingTest.ADDRESS.toString(), PagingTest.ADDRESS + "-1", null, true);
+
+ session.createQueue(PagingTest.ADDRESS.toString(), PagingTest.ADDRESS + "-2", null, true);
+ }
+
+ ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ ClientMessage message = null;
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ if (i % 500 == 0) {
+ log.info("Sent " + i + " messages");
+ session.commit();
+ }
+ message = session.createMessage(true);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ message.putIntProperty(new SimpleString("id"), i);
+
+ producer.send(message);
+ }
+
+ session.commit();
+
+ session.close();
+
+ server.stop();
+
+ sf.close();
+ locator.close();
+ }
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+ server.start();
+
+ Queue queue1 = server.locateQueue(PagingTest.ADDRESS.concat("-1"));
+
+ Queue queue2 = server.locateQueue(PagingTest.ADDRESS.concat("-2"));
+
+ assertNotNull(queue1);
+
+ assertNotNull(queue2);
+
+ assertNotSame(queue1, queue2);
+
+ tcount1 = new TCount(queue1);
+
+ tcount2 = new TCount(queue2);
+
+ tcount1.start();
+ tcount2.start();
+
+ locator = createInVMNonHALocator();
+ final ClientSessionFactory sf2 = createSessionFactory(locator);
+
+ final AtomicInteger errors = new AtomicInteger(0);
+
+ Thread[] threads = new Thread[2];
+
+ for (int start = 1; start <= 2; start++) {
+
+ final String addressToSubscribe = PagingTest.ADDRESS + "-" + start;
+
+ threads[start - 1] = new Thread() {
+ @Override
+ public void run() {
+ try {
+ ClientSession session = sf2.createSession(null, null, false, true, true, false, 0);
+
+ ClientConsumer consumer = session.createConsumer(addressToSubscribe);
+
+ session.start();
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ ClientMessage message2 = consumer.receive(PagingTest.RECEIVE_TIMEOUT);
+
+ Assert.assertNotNull(message2);
+
+ Assert.assertEquals(i, message2.getIntProperty("id").intValue());
+
+ message2.acknowledge();
+
+ Assert.assertNotNull(message2);
+
+ if (i % 100 == 0) {
+ if (i % 5000 == 0) {
+ log.info(addressToSubscribe + " consumed " + i + " messages");
+ }
+ session.commit();
+ }
+
+ try {
+ assertBodiesEqual(body, message2.getBodyBuffer());
+ }
+ catch (AssertionError e) {
+ PagingTest.log.info("Expected buffer:" + ActiveMQTestBase.dumpBytesHex(body, 40));
+ PagingTest.log.info("Arriving buffer:" + ActiveMQTestBase.dumpBytesHex(message2.getBodyBuffer().toByteBuffer().array(), 40));
+ throw e;
+ }
+ }
+
+ session.commit();
+
+ consumer.close();
+
+ session.close();
+ }
+ catch (Throwable e) {
+ e.printStackTrace();
+ errors.incrementAndGet();
+ }
+
+ }
+ };
+ }
+
+ for (int i = 0; i < 2; i++) {
+ threads[i].start();
+ }
+
+ for (int i = 0; i < 2; i++) {
+ threads[i].join();
+ }
+
+ sf2.close();
+ locator.close();
+
+ assertEquals(0, errors.get());
+
+ for (int i = 0; i < 20 && server.getPagingManager().getTransactions().size() != 0; i++) {
+ if (server.getPagingManager().getTransactions().size() != 0) {
+ // The delete may be asynchronous, giving some time case it eventually happen asynchronously
+ Thread.sleep(500);
+ }
+ }
+
+ assertEquals(0, server.getPagingManager().getTransactions().size());
+
+ }
+ finally {
+ running.set(false);
+
+ if (tcount1 != null) {
+ tcount1.interrupt();
+ tcount1.join();
+ }
+
+ if (tcount2 != null) {
+ tcount2.interrupt();
+ tcount2.join();
+ }
+
+ try {
+ server.stop();
+ }
+ catch (Throwable ignored) {
+ }
+ }
+
+ }
+
+ @Test
+ public void testMultiQueuesNonPersistentAndPersistent() throws Exception {
+ clearDataRecreateServerDirs();
+
+ Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+
+ server.start();
+
+ final int numberOfMessages = 3000;
+
+ final byte[] body = new byte[MESSAGE_SIZE];
+
+ ByteBuffer bb = ByteBuffer.wrap(body);
+
+ for (int j = 1; j <= MESSAGE_SIZE; j++) {
+ bb.put(getSamplebyte(j));
+ }
+
+ {
+ locator = createInVMNonHALocator();
+
+ locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
+
+ sf = createSessionFactory(locator);
+
+ ClientSession session = sf.createSession(false, false, false);
+
+ session.createQueue(PagingTest.ADDRESS.toString(), PagingTest.ADDRESS + "-1", null, true);
+
+ session.createQueue(PagingTest.ADDRESS.toString(), PagingTest.ADDRESS + "-2", null, false);
+
+ ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ ClientMessage message = null;
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ if (i % 500 == 0) {
+ session.commit();
+ }
+ message = session.createMessage(true);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ message.putIntProperty(new SimpleString("id"), i);
+
+ producer.send(message);
+ }
+
+ session.commit();
+
+ session.close();
+
+ server.stop();
+
+ sf.close();
+ locator.close();
+ }
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+ server.start();
+
+ ServerLocator locator1 = createInVMNonHALocator();
+ final ClientSessionFactory sf2 = locator1.createSessionFactory();
+
+ final AtomicInteger errors = new AtomicInteger(0);
+
+ Thread t = new Thread() {
+ @Override
+ public void run() {
+ try {
+ ClientSession session = sf2.createSession(null, null, false, true, true, false, 0);
+
+ ClientConsumer consumer = session.createConsumer(PagingTest.ADDRESS + "-1");
+
+ session.start();
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ ClientMessage message2 = consumer.receive(PagingTest.RECEIVE_TIMEOUT);
+
+ Assert.assertNotNull(message2);
+
+ Assert.assertEquals(i, message2.getIntProperty("id").intValue());
+
+ message2.acknowledge();
+
+ Assert.assertNotNull(message2);
+
+ if (i % 1000 == 0) {
+ session.commit();
+ }
+
+ try {
+ assertBodiesEqual(body, message2.getBodyBuffer());
+ }
+ catch (AssertionError e) {
+ PagingTest.log.info("Expected buffer:" + ActiveMQTestBase.dumpBytesHex(body, 40));
+ PagingTest.log.info("Arriving buffer:" + ActiveMQTestBase.dumpBytesHex(message2.getBodyBuffer().toByteBuffer().array(), 40));
+ throw e;
+ }
+ }
+
+ session.commit();
+
+ consumer.close();
+
+ session.close();
+ }
+ catch (Throwable e) {
+ e.printStackTrace();
+ errors.incrementAndGet();
+ }
+
+ }
+ };
+
+ t.start();
+ t.join();
+
+ assertEquals(0, errors.get());
+
+ for (int i = 0; i < 20 && server.getPagingManager().getPageStore(ADDRESS).isPaging(); i++) {
+ // The delete may be asynchronous, giving some time case it eventually happen asynchronously
+ Thread.sleep(500);
+ }
+
+ assertFalse(server.getPagingManager().getPageStore(ADDRESS).isPaging());
+
+ for (int i = 0; i < 20 && server.getPagingManager().getTransactions().size() != 0; i++) {
+ // The delete may be asynchronous, giving some time case it eventually happen asynchronously
+ Thread.sleep(500);
+ }
+
+ assertEquals(0, server.getPagingManager().getTransactions().size());
+
+ }
+
+ private void internaltestSendReceivePaging(final boolean persistentMessages) throws Exception {
+
+ clearDataRecreateServerDirs();
+
+ Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+
+ server.start();
+
+ final int numberOfIntegers = 256;
+
+ final int numberOfMessages = 1000;
+ locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
+
+ sf = createSessionFactory(locator);
+
+ ClientSession session = sf.createSession(null, null, false, true, true, false, 0);
+
+ session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
+
+ Queue queue = server.locateQueue(ADDRESS);
+ queue.getPageSubscription().getPagingStore().startPaging();
+
+ ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ ClientMessage message = null;
+
+ byte[] body = new byte[numberOfIntegers * 4];
+
+ ByteBuffer bb = ByteBuffer.wrap(body);
+
+ for (int j = 1; j <= numberOfIntegers; j++) {
+ bb.putInt(j);
+ }
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ message = session.createMessage(persistentMessages);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ message.putIntProperty(new SimpleString("id"), i);
+
+ producer.send(message);
+ }
+
+ session.close();
+ sf.close();
+ locator.close();
+
+ server.stop();
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+ server.start();
+
+ locator = createInVMNonHALocator();
+ sf = createSessionFactory(locator);
+
+ session = sf.createSession(null, null, false, true, true, false, 0);
+
+ ClientConsumer consumer = session.createConsumer(PagingTest.ADDRESS);
+
+ session.start();
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ ClientMessage message2 = consumer.receive(PagingTest.RECEIVE_TIMEOUT);
+
+ Assert.assertNotNull(message2);
+
+ Assert.assertEquals(i, message2.getIntProperty("id").intValue());
+
+ assertEquals(body.length, message2.getBodySize());
+
+ message2.acknowledge();
+
+ Assert.assertNotNull(message2);
+
+ if (i % 1000 == 0) {
+ session.commit();
+ }
+
+ try {
+ assertBodiesEqual(body, message2.getBodyBuffer());
+ }
+ catch (AssertionError e) {
+ PagingTest.log.info("Expected buffer:" + ActiveMQTestBase.dumpBytesHex(body, 40));
+ PagingTest.log.info("Arriving buffer:" + ActiveMQTestBase.dumpBytesHex(message2.getBodyBuffer().toByteBuffer().array(), 40));
+ throw e;
+ }
+ }
+
+ consumer.close();
+
+ session.close();
+ }
+
+ private void assertBodiesEqual(final byte[] body, final ActiveMQBuffer buffer) {
+ byte[] other = new byte[body.length];
+
+ buffer.readBytes(other);
+
+ ActiveMQTestBase.assertEqualsByteArrays(body, other);
+ }
+
+ /**
+ * - Make a destination in page mode
+ * - Add stuff to a transaction
+ * - Consume the entire destination (not in page mode any more)
+ * - Add stuff to a transaction again
+ * - Check order
+ */
+ @Test
+ public void testDepageDuringTransaction() throws Exception {
+ clearDataRecreateServerDirs();
+
+ Configuration config = createDefaultInVMConfig();
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+
+ server.start();
+
+ locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
+
+ sf = createSessionFactory(locator);
+
+ ClientSession session = sf.createSession(null, null, false, true, true, false, 0);
+
+ session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
+
+ ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ byte[] body = new byte[MESSAGE_SIZE];
+ // ActiveMQBuffer bodyLocal = ActiveMQChannelBuffers.buffer(DataConstants.SIZE_INT * numberOfIntegers);
+
+ ClientMessage message = null;
+
+ int numberOfMessages = 0;
+ while (true) {
+ message = session.createMessage(true);
+ message.getBodyBuffer().writeBytes(body);
+
+ // Stop sending message as soon as we start paging
+ if (server.getPagingManager().getPageStore(PagingTest.ADDRESS).isPaging()) {
+ break;
+ }
+ numberOfMessages++;
+
+ producer.send(message);
+ }
+
+ Assert.assertTrue(server.getPagingManager().getPageStore(PagingTest.ADDRESS).isPaging());
+
+ session.start();
+
+ ClientSession sessionTransacted = sf.createSession(null, null, false, false, false, false, 0);
+
+ ClientProducer producerTransacted = sessionTransacted.createProducer(PagingTest.ADDRESS);
+
+ for (int i = 0; i < 10; i++) {
+ message = session.createMessage(true);
+ message.getBodyBuffer().writeBytes(body);
+ message.putIntProperty(new SimpleString("id"), i);
+
+ // Consume messages to force an eventual out of order delivery
+ if (i == 5) {
+ ClientConsumer consumer = session.createConsumer(PagingTest.ADDRESS);
+ for (int j = 0; j < numberOfMessages; j++) {
+ ClientMessage msg = consumer.receive(PagingTest.RECEIVE_TIMEOUT);
+ msg.acknowledge();
+ Assert.assertNotNull(msg);
+ }
+
+ Assert.assertNull(consumer.receiveImmediate());
+ consumer.close();
+ }
+
+ Integer messageID = (Integer) message.getObjectProperty(new SimpleString("id"));
+ Assert.assertNotNull(messageID);
+ Assert.assertEquals(messageID.intValue(), i);
+
+ producerTransacted.send(message);
+ }
+
+ ClientConsumer consumer = session.createConsumer(PagingTest.ADDRESS);
+
+ Assert.assertNull(consumer.receiveImmediate());
+
+ sessionTransacted.commit();
+
+ sessionTransacted.close();
+
+ for (int i = 0; i < 10; i++) {
+ message = consumer.receive(PagingTest.RECEIVE_TIMEOUT);
+
+ Assert.assertNotNull(message);
+
+ Integer messageID = (Integer) message.getObjectProperty(new SimpleString("id"));
+
+ Assert.assertNotNull(messageID);
+ Assert.assertEquals("message received out of order", messageID.intValue(), i);
+
+ message.acknowledge();
+ }
+
+ Assert.assertNull(consumer.receiveImmediate());
+
+ consumer.close();
+
+ session.close();
+ }
+
+ /**
+ * - Make a destination in page mode
+ * - Add stuff to a transaction
+ * - Consume the entire destination (not in page mode any more)
+ * - Add stuff to a transaction again
+ * - Check order
+ * <br>
+ * Test under discussion at : http://community.jboss.org/thread/154061?tstart=0
+ */
+ @Test
+ public void testDepageDuringTransaction2() throws Exception {
+ boolean IS_DURABLE_MESSAGE = true;
+ clearDataRecreateServerDirs();
+
+ Configuration config = createDefaultInVMConfig();
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+
+ server.start();
+
+ locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
+
+ sf = createSessionFactory(locator);
+
+ byte[] body = new byte[MESSAGE_SIZE];
+
+ ClientSession sessionTransacted = sf.createSession(null, null, false, false, false, false, 0);
+ ClientProducer producerTransacted = sessionTransacted.createProducer(PagingTest.ADDRESS);
+
+ ClientSession session = sf.createSession(null, null, false, true, true, false, 0);
+ session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
+
+ ClientMessage firstMessage = sessionTransacted.createMessage(IS_DURABLE_MESSAGE);
+ firstMessage.getBodyBuffer().writeBytes(body);
+ firstMessage.putIntProperty(new SimpleString("id"), 0);
+
+ producerTransacted.send(firstMessage);
+
+ ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ ClientMessage message = null;
+
+ int numberOfMessages = 0;
+ while (true) {
+ System.out.println("Sending message " + numberOfMessages);
+ message = session.createMessage(IS_DURABLE_MESSAGE);
+ message.getBodyBuffer().writeBytes(body);
+ message.putIntProperty("id", numberOfMessages);
+ message.putBooleanProperty("new", false);
+
+ // Stop sending message as soon as we start paging
+ if (server.getPagingManager().getPageStore(PagingTest.ADDRESS).isPaging()) {
+ break;
+ }
+ numberOfMessages++;
+
+ producer.send(message);
+ }
+
+ Assert.assertTrue(server.getPagingManager().getPageStore(PagingTest.ADDRESS).isPaging());
+
+ session.start();
+
+ for (int i = 1; i < 10; i++) {
+ message = session.createMessage(true);
+ message.getBodyBuffer().writeBytes(body);
+ message.putIntProperty(new SimpleString("id"), i);
+
+ // Consume messages to force an eventual out of order delivery
+ if (i == 5) {
+ ClientConsumer consumer = session.createConsumer(PagingTest.ADDRESS);
+ for (int j = 0; j < numberOfMessages; j++) {
+ ClientMessage msg = consumer.receive(PagingTest.RECEIVE_TIMEOUT);
+ msg.acknowledge();
+ assertEquals(j, msg.getIntProperty("id").intValue());
+ assertFalse(msg.getBooleanProperty("new"));
+ Assert.assertNotNull(msg);
+ }
+
+ ClientMessage msgReceived = consumer.receiveImmediate();
+
+ Assert.assertNull(msgReceived);
+ consumer.close();
+ }
+
+ Integer messageID = (Integer) message.getObjectProperty(new SimpleString("id"));
+ Assert.assertNotNull(messageID);
+ Assert.assertEquals(messageID.intValue(), i);
+
+ producerTransacted.send(message);
+ }
+
+ ClientConsumer consumer = session.createConsumer(PagingTest.ADDRESS);
+
+ Assert.assertNull(consumer.receiveImmediate());
+
+ sessionTransacted.commit();
+
+ sessionTransacted.close();
+
+ for (int i = 0; i < 10; i++) {
+ message = consumer.receive(PagingTest.RECEIVE_TIMEOUT);
+
+ Assert.assertNotNull(message);
+
+ Integer messageID = (Integer) message.getObjectProperty(new SimpleString("id"));
+
+ // System.out.println(messageID);
+ Assert.assertNotNull(messageID);
+ Assert.assertEquals("message received out of order", i, messageID.intValue());
+
+ message.acknowledge();
+ }
+
+ Assert.assertNull(consumer.receiveImmediate());
+
+ consumer.close();
+
+ session.close();
+
+ }
+
+ @Test
+ public void testDepageDuringTransaction3() throws Exception {
+ clearDataRecreateServerDirs();
+
+ Configuration config = createDefaultInVMConfig();
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+
+ server.start();
+
+ locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
+
+ sf = createSessionFactory(locator);
+
+ byte[] body = new byte[MESSAGE_SIZE];
+
+ ClientSession sessionTransacted = sf.createSession(null, null, false, false, false, false, 0);
+ ClientProducer producerTransacted = sessionTransacted.createProducer(PagingTest.ADDRESS);
+
+ ClientSession sessionNonTX = sf.createSession(true, true, 0);
+ sessionNonTX.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
+
+ ClientProducer producerNonTransacted = sessionNonTX.createProducer(PagingTest.ADDRESS);
+
+ sessionNonTX.start();
+
+ for (int i = 0; i < 50; i++) {
+ ClientMessage message = sessionNonTX.createMessage(true);
+ message.getBodyBuffer().writeBytes(body);
+ message.putIntProperty(new SimpleString("id"), i);
+ message.putStringProperty(new SimpleString("tst"), new SimpleString("i=" + i));
+
+ producerTransacted.send(message);
+
+ if (i % 2 == 0) {
+ for (int j = 0; j < 20; j++) {
+ ClientMessage msgSend = sessionNonTX.createMessage(true);
+ msgSend.putStringProperty(new SimpleString("tst"), new SimpleString("i=" + i + ", j=" + j));
+ msgSend.getBodyBuffer().writeBytes(new byte[10 * 1024]);
+ producerNonTransacted.send(msgSend);
+ }
+ assertTrue(server.getPagingManager().getPageStore(PagingTest.ADDRESS).isPaging());
+ }
+ else {
+ ClientConsumer consumer = sessionNonTX.createConsumer(PagingTest.ADDRESS);
+ for (int j = 0; j < 20; j++) {
+ ClientMessage msgReceived = consumer.receive(10000);
+ assertNotNull(msgReceived);
+ msgReceived.acknowledge();
+ }
+ consumer.close();
+ }
+ }
+
+ ClientConsumer consumerNonTX = sessionNonTX.createConsumer(PagingTest.ADDRESS);
+ while (true) {
+ ClientMessage msgReceived = consumerNonTX.receive(1000);
+ if (msgReceived == null) {
+ break;
+ }
+ msgReceived.acknowledge();
+ }
+ consumerNonTX.close();
+
+ ClientConsumer consumer = sessionNonTX.createConsumer(PagingTest.ADDRESS);
+
+ Assert.assertNull(consumer.receiveImmediate());
+
+ sessionTransacted.commit();
+
+ sessionTransacted.close();
+
+ for (int i = 0; i < 50; i++) {
+ ClientMessage message = consumer.receive(PagingTest.RECEIVE_TIMEOUT);
+
+ Assert.assertNotNull(message);
+
+ Integer messageID = (Integer) message.getObjectProperty(new SimpleString("id"));
+
+ Assert.assertNotNull(messageID);
+ Assert.assertEquals("message received out of order", i, messageID.intValue());
+
+ message.acknowledge();
+ }
+
+ Assert.assertNull(consumer.receiveImmediate());
+
+ consumer.close();
+
+ sessionNonTX.close();
+ }
+
+ @Test
+ public void testDepageDuringTransaction4() throws Exception {
+ clearDataRecreateServerDirs();
+
+ Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false).setJournalSyncTransactional(false);
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+
+ server.start();
+
+ final AtomicInteger errors = new AtomicInteger(0);
+
+ final int numberOfMessages = 10000;
+
+ locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(false);
+
+ sf = createSessionFactory(locator);
+
+ final byte[] body = new byte[MESSAGE_SIZE];
+
+ Thread producerThread = new Thread() {
+ @Override
+ public void run() {
+ ClientSession sessionProducer = null;
+ try {
+ sessionProducer = sf.createSession(false, false);
+ ClientProducer producer = sessionProducer.createProducer(ADDRESS);
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ ClientMessage msg = sessionProducer.createMessage(true);
+ msg.getBodyBuffer().writeBytes(body);
+ msg.putIntProperty("count", i);
+ producer.send(msg);
+
+ if (i % 100 == 0 && i != 0) {
+ sessionProducer.commit();
+ // Thread.sleep(500);
+ }
+ }
+
+ sessionProducer.commit();
+
+ }
+ catch (Throwable e) {
+ e.printStackTrace(); // >> junit report
+ errors.incrementAndGet();
+ }
+ finally {
+ try {
+ if (sessionProducer != null) {
+ sessionProducer.close();
+ }
+ }
+ catch (Throwable e) {
+ e.printStackTrace();
+ errors.incrementAndGet();
+ }
+ }
+ }
+ };
+
+ ClientSession session = sf.createSession(true, true, 0);
+ session.start();
+ session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
+
+ producerThread.start();
+
+ ClientConsumer consumer = session.createConsumer(PagingTest.ADDRESS);
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ ClientMessage msg = consumer.receive(5000);
+ assertNotNull(msg);
+ assertEquals(i, msg.getIntProperty("count").intValue());
+ msg.acknowledge();
+ if (i > 0 && i % 10 == 0) {
+ session.commit();
+ }
+ }
+ session.commit();
+
+ session.close();
+
+ producerThread.join();
+
+ locator.close();
+
+ sf.close();
+
+ assertEquals(0, errors.get());
+ }
+
+ @Test
+ public void testOrderingNonTX() throws Exception {
+ clearDataRecreateServerDirs();
+
+ Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false).setJournalSyncTransactional(false);
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_SIZE * 2);
+
+ server.getConfiguration();
+ server.getConfiguration();
+
+ server.start();
+
+ final AtomicInteger errors = new AtomicInteger(0);
+
+ final int numberOfMessages = 2000;
+
+ locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
+
+ sf = createSessionFactory(locator);
+
+ final CountDownLatch ready = new CountDownLatch(1);
+
+ final byte[] body = new byte[MESSAGE_SIZE];
+
+ Thread producerThread = new Thread() {
+ @Override
+ public void run() {
+ ClientSession sessionProducer = null;
+ try {
+ sessionProducer = sf.createSession(true, true);
+ ClientProducer producer = sessionProducer.createProducer(ADDRESS);
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ ClientMessage msg = sessionProducer.createMessage(true);
+ msg.getBodyBuffer().writeBytes(body);
+ msg.putIntProperty("count", i);
+ producer.send(msg);
+
+ if (i == 1000) {
+ // The session is not TX, but we do this just to perform a round trip to the server
+ // and make sure there are no pending messages
+ sessionProducer.commit();
+
+ assertTrue(server.getPagingManager().getPageStore(ADDRESS).isPaging());
+ ready.countDown();
+ }
+ }
+
+ sessionProducer.commit();
+
+ log.info("Producer gone");
+
+ }
+ catch (Throwable e) {
+ e.printStackTrace(); // >> junit report
+ errors.incrementAndGet();
+ }
+ finally {
+ try {
+ if (sessionProducer != null) {
+ sessionProducer.close();
+ }
+ }
+ catch (Throwable e) {
+ e.printStackTrace();
+ errors.incrementAndGet();
+ }
+ }
+ }
+ };
+
+ ClientSession session = sf.createSession(true, true, 0);
+ session.start();
+ session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
+
+ producerThread.start();
+
+ assertTrue(ready.await(100, TimeUnit.SECONDS));
+
+ ClientConsumer consumer = session.createConsumer(PagingTest.ADDRESS);
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ ClientMessage msg = consumer.receive(5000);
+ assertNotNull(msg);
+ if (i != msg.getIntProperty("count").intValue()) {
+ log.info("Received " + i + " with property = " + msg.getIntProperty("count"));
+ log.info("###### different");
+ }
+ // assertEquals(i, msg.getIntProperty("count").intValue());
+ msg.acknowledge();
+ }
+
+ session.close();
+
+ producerThread.join();
+
+ assertEquals(0, errors.get());
+ }
+
+ @Test
+ public void testPageOnSchedulingNoRestart() throws Exception {
+ internalTestPageOnScheduling(false);
+ }
+
+ @Test
+ public void testPageOnSchedulingRestart() throws Exception {
+ internalTestPageOnScheduling(true);
+ }
+
+ public void internalTestPageOnScheduling(final boolean restart) throws Exception {
+ clearDataRecreateServerDirs();
+
+ Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+
+ server.start();
+
+ final int numberOfMessages = 1000;
+
+ final int numberOfBytes = 1024;
+
+ locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
+
+ sf = createSessionFactory(locator);
+ ClientSession session = sf.createSession(null, null, false, true, true, false, 0);
+
+ session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
+
+ ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ ClientMessage message = null;
+
+ byte[] body = new byte[numberOfBytes];
+
+ for (int j = 0; j < numberOfBytes; j++) {
+ body[j] = ActiveMQTestBase.getSamplebyte(j);
+ }
+
+ long scheduledTime = Sys
<TRUNCATED>
[7/7] activemq-artemis git commit: ARTEMIS-581 Implement max disk
usage, and global-max-size
Posted by ma...@apache.org.
ARTEMIS-581 Implement max disk usage, and global-max-size
max-disk-usage = how much of a disk we can use before the system blocks
global-max-size = how much bytes we can take from memory for messages before we start enter into the configured page mode
This will also change the default created configuration into page-mode as that's more reliable for systems.
Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/4472aa0e
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/4472aa0e
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/4472aa0e
Branch: refs/heads/master
Commit: 4472aa0e36b73b776fc173816b13f9d72d3c45b1
Parents: bfc2095
Author: Clebert Suconic <cl...@apache.org>
Authored: Fri Sep 2 16:30:44 2016 -0400
Committer: Martyn Taylor <mt...@redhat.com>
Committed: Tue Sep 6 15:07:49 2016 +0100
----------------------------------------------------------------------
.../artemis/cli/commands/etc/broker.xml | 16 +-
.../config/ActiveMQDefaultConfiguration.java | 19 +
.../protocol/AbstractRemotingConnection.java | 4 +
.../spi/core/protocol/RemotingConnection.java | 8 +
.../core/protocol/mqtt/MQTTConnection.java | 5 +
.../core/protocol/stomp/StompConnection.java | 4 +
.../artemis/core/config/Configuration.java | 16 +-
.../core/config/impl/ConfigurationImpl.java | 39 +
.../deployers/impl/FileConfigurationParser.java | 12 +
.../artemis/core/paging/PagingManager.java | 16 +
.../artemis/core/paging/PagingStore.java | 3 +
.../artemis/core/paging/PagingStoreFactory.java | 3 +
.../artemis/core/paging/impl/PageSyncTimer.java | 2 +
.../core/paging/impl/PagingManagerImpl.java | 93 +-
.../core/paging/impl/PagingStoreFactoryNIO.java | 8 +-
.../core/paging/impl/PagingStoreImpl.java | 95 +-
.../core/persistence/StorageManager.java | 4 +
.../impl/journal/JournalStorageManager.java | 12 +-
.../impl/nullpm/NullStorageManager.java | 6 +
.../core/server/ActiveMQMessageBundle.java | 5 +
.../core/server/ActiveMQScheduledComponent.java | 101 +
.../core/server/ActiveMQServerLogger.java | 10 +
.../core/server/files/FileMoveManager.java | 218 +
.../core/server/files/FileStoreMonitor.java | 127 +
.../core/server/impl/ActiveMQServerImpl.java | 39 +-
.../core/server/impl/FileMoveManager.java | 218 -
.../core/server/impl/ServerSessionImpl.java | 17 +-
.../core/server/reload/ReloadManagerImpl.java | 50 +-
.../resources/schema/artemis-configuration.xsd | 24 +
.../core/config/impl/FileConfigurationTest.java | 3 +
.../core/server/files/FileMoveManagerTest.java | 346 ++
.../core/server/files/FileStoreMonitorTest.java | 161 +
.../core/server/impl/FileMoveManagerTest.java | 346 --
.../transaction/impl/TransactionImplTest.java | 6 +
.../artemis/tests/util/ActiveMQTestBase.java | 20 +-
.../resources/ConfigurationTest-full-config.xml | 3 +
docs/user-manual/en/configuration-index.md | 3 +
docs/user-manual/en/paging.md | 15 +-
.../integration/client/HangConsumerTest.java | 2 +-
.../integration/client/LargeMessageTest.java | 2 +-
.../integration/client/PagingOrderTest.java | 714 ---
.../integration/client/PagingSyncTest.java | 109 -
.../tests/integration/client/PagingTest.java | 5734 ------------------
.../cluster/failover/BackupSyncJournalTest.java | 2 +-
.../cluster/failover/FailoverTest.java | 2 +-
.../paging/AddressFullLoggingTest.java | 152 +
.../integration/paging/GlobalPagingTest.java | 183 +
.../integration/paging/PagingOrderTest.java | 714 +++
.../integration/paging/PagingSyncTest.java | 109 +
.../tests/integration/paging/PagingTest.java | 5731 +++++++++++++++++
.../server/AddressFullLoggingTest.java | 131 -
.../tests/integration/stomp/StompTest.java | 42 +
.../tests/integration/stomp/StompTestBase.java | 2 +-
.../storage/PersistMultiThreadTest.java | 5 +
.../core/paging/impl/PagingStoreImplTest.java | 6 +
.../tests/unit/util/FakePagingManager.java | 54 +-
56 files changed, 8383 insertions(+), 7388 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/broker.xml
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/broker.xml b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/broker.xml
index 520a231..fe28246 100644
--- a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/broker.xml
+++ b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/broker.xml
@@ -50,6 +50,17 @@ under the License.
<journal-pool-files>-1</journal-pool-files>
${journal-buffer.settings}
${connector-config.settings}
+ <!-- how often we are looking for how many bytes are being used on the disk in ms -->
+ <disk-scan-period>5000</disk-scan-period>
+
+ <!-- once the disk hits this limit the system will block, or close the connection in certain protocols
+ that won't support flow control. -->
+ <max-disk-usage>90</max-disk-usage>
+
+ <!-- the system will enter into page mode once you hit this limit.
+ This is an estimate in bytes of how much the messages are using in memory -->
+ <global-max-size>104857600</global-max-size>
+
<acceptors>
<!-- Default ActiveMQ Artemis Acceptor. Multi-protocol adapter. Currently supports ActiveMQ Artemis Core, OpenWire, STOMP, AMQP, MQTT, and HornetQ Core. -->
<!-- performance tests have shown that openWire performs best with these buffer sizes -->
@@ -78,9 +89,10 @@ ${cluster-security.settings}${cluster.settings}${replicated.settings}${shared-st
<dead-letter-address>jms.queue.DLQ</dead-letter-address>
<expiry-address>jms.queue.ExpiryQueue</expiry-address>
<redelivery-delay>0</redelivery-delay>
- <max-size-bytes>10485760</max-size-bytes>
+ <!-- with -1 only the global-max-size is in use for limiting -->
+ <max-size-bytes>-1</max-size-bytes>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
- <address-full-policy>BLOCK</address-full-policy>
+ <address-full-policy>PAGE</address-full-policy>
</address-setting>
</address-settings>
</core>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java
index aecf902..4ba7329 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java
@@ -429,6 +429,12 @@ public final class ActiveMQDefaultConfiguration {
// Default period to wait between configuration file checks
public static final long DEFAULT_CONFIGURATION_FILE_REFRESH_PERIOD = 5000;
+ public static final long DEFAULT_GLOBAL_MAX_SIZE = -1;
+
+ public static final int DEFAULT_MAX_DISK_USAGE = 100;
+
+ public static final int DEFAULT_DISK_SCAN = 5000;
+
/**
* If true then the ActiveMQ Artemis Server will make use of any Protocol Managers that are in available on the classpath. If false then only the core protocol will be available, unless in Embedded mode where users can inject their own Protocol Managers.
*/
@@ -1144,4 +1150,17 @@ public final class ActiveMQDefaultConfiguration {
public static long getDefaultConfigurationFileRefreshPeriod() {
return DEFAULT_CONFIGURATION_FILE_REFRESH_PERIOD;
}
+
+ /** The default global max size. -1 = no global max size. */
+ public static long getDefaultMaxGlobalSize() {
+ return DEFAULT_GLOBAL_MAX_SIZE;
+ }
+
+ public static int getDefaultMaxDiskUsage() {
+ return DEFAULT_MAX_DISK_USAGE;
+ }
+
+ public static int getDefaultDiskScanPeriod() {
+ return DEFAULT_DISK_SCAN;
+ }
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/protocol/AbstractRemotingConnection.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/protocol/AbstractRemotingConnection.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/protocol/AbstractRemotingConnection.java
index c438766..e512adf 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/protocol/AbstractRemotingConnection.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/protocol/AbstractRemotingConnection.java
@@ -219,4 +219,8 @@ public abstract class AbstractRemotingConnection implements RemotingConnection {
dataReceived = true;
}
+ @Override
+ public boolean isSupportsFlowControl() {
+ return true;
+ }
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/protocol/RemotingConnection.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/protocol/RemotingConnection.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/protocol/RemotingConnection.java
index 0f5abf3..253986f 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/protocol/RemotingConnection.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/protocol/RemotingConnection.java
@@ -196,4 +196,12 @@ public interface RemotingConnection extends BufferHandler {
* @return
*/
boolean isSupportReconnect();
+
+ /**
+ * Return true if the protocol supports flow control.
+ * This is because in some cases we may need to hold message producers in cases like disk full.
+ * If the protocol doesn't support it we trash the connection and throw exceptions.
+ * @return
+ */
+ boolean isSupportsFlowControl();
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-protocols/artemis-mqtt-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/mqtt/MQTTConnection.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-mqtt-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/mqtt/MQTTConnection.java b/artemis-protocols/artemis-mqtt-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/mqtt/MQTTConnection.java
index aa87bd8..31486ff 100644
--- a/artemis-protocols/artemis-mqtt-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/mqtt/MQTTConnection.java
+++ b/artemis-protocols/artemis-mqtt-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/mqtt/MQTTConnection.java
@@ -221,4 +221,9 @@ public class MQTTConnection implements RemotingConnection {
public boolean isSupportReconnect() {
return false;
}
+
+ @Override
+ public boolean isSupportsFlowControl() {
+ return false;
+ }
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompConnection.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompConnection.java b/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompConnection.java
index 36f440c..b918b75 100644
--- a/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompConnection.java
+++ b/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompConnection.java
@@ -738,4 +738,8 @@ public final class StompConnection implements RemotingConnection {
//unsupported
}
+ @Override
+ public boolean isSupportsFlowControl() {
+ return false;
+ }
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java
index fc38155..e78479a 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java
@@ -561,10 +561,10 @@ public interface Configuration {
*/
Configuration setJournalCompactMinFiles(int minFiles);
- /** Number of files that would be acceptable to keep on a pool. Default value is {@link org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration#DEFAULT_JOURNAL_POOL_SIZE}.*/
+ /** Number of files that would be acceptable to keep on a pool. Default value is {@link org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration#DEFAULT_JOURNAL_POOL_FILES}.*/
int getJournalPoolFiles();
- /** Number of files that would be acceptable to keep on a pool. Default value is {@link org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration#DEFAULT_JOURNAL_POOL_SIZE}.*/
+ /** Number of files that would be acceptable to keep on a pool. Default value is {@link org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration#DEFAULT_JOURNAL_POOL_FILES}.*/
Configuration setJournalPoolFiles(int poolSize);
@@ -968,4 +968,16 @@ public interface Configuration {
Configuration setConfigurationFileRefreshPeriod(long configurationFileRefreshPeriod);
+ long getGlobalMaxSize();
+
+ Configuration setGlobalMaxSize(long globalMaxSize);
+
+ int getMaxDiskUsage();
+
+ Configuration setMaxDiskUsage(int maxDiskUsage);
+
+ Configuration setDiskScanPeriod(int diskScanPeriod);
+
+ int getDiskScanPeriod();
+
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java
index 0604c44..51b633f 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java
@@ -246,6 +246,12 @@ public class ConfigurationImpl implements Configuration, Serializable {
private long configurationFileRefreshPeriod = ActiveMQDefaultConfiguration.getDefaultConfigurationFileRefreshPeriod();
+ private long globalMaxSize = ActiveMQDefaultConfiguration.getDefaultMaxGlobalSize();
+
+ private int maxDiskUsage = ActiveMQDefaultConfiguration.getDefaultMaxDiskUsage();
+
+ private int diskScanPeriod = ActiveMQDefaultConfiguration.getDefaultDiskScanPeriod();
+
/**
* Parent folder for all data folders.
*/
@@ -264,6 +270,28 @@ public class ConfigurationImpl implements Configuration, Serializable {
}
@Override
+ public int getMaxDiskUsage() {
+ return maxDiskUsage;
+ }
+
+ @Override
+ public ConfigurationImpl setMaxDiskUsage(int maxDiskUsage) {
+ this.maxDiskUsage = maxDiskUsage;
+ return this;
+ }
+
+ @Override
+ public ConfigurationImpl setGlobalMaxSize(long maxSize) {
+ this.globalMaxSize = maxSize;
+ return this;
+ }
+
+ @Override
+ public long getGlobalMaxSize() {
+ return globalMaxSize;
+ }
+
+ @Override
public ConfigurationImpl setPersistenceEnabled(final boolean enable) {
persistenceEnabled = enable;
return this;
@@ -1784,6 +1812,17 @@ public class ConfigurationImpl implements Configuration, Serializable {
return this;
}
+ @Override
+ public int getDiskScanPeriod() {
+ return diskScanPeriod;
+ }
+
+ @Override
+ public ConfigurationImpl setDiskScanPeriod(int diskScanPeriod) {
+ this.diskScanPeriod = diskScanPeriod;
+ return this;
+ }
+
/**
* It will find the right location of a subFolder, related to artemisInstance
*/
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
index c77157b..f700e32 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
@@ -175,6 +175,12 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
private static final String MAX_QUEUES_NODE_NAME = "max-queues";
+ private static final String GLOBAL_MAX_SIZE = "global-max-size";
+
+ private static final String MAX_DISK_USAGE = "max-disk-usage";
+
+ private static final String DISK_SCAN_PERIOD = "disk-scan-period";
+
// Attributes ----------------------------------------------------
private boolean validateAIO = false;
@@ -282,6 +288,12 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
config.setConfigurationFileRefreshPeriod(getLong(e, "configuration-file-refresh-period", config.getConfigurationFileRefreshPeriod(), Validators.GT_ZERO));
+ config.setGlobalMaxSize(getLong(e, GLOBAL_MAX_SIZE, config.getGlobalMaxSize(), Validators.MINUS_ONE_OR_GT_ZERO));
+
+ config.setMaxDiskUsage(getInteger(e, MAX_DISK_USAGE, config.getMaxDiskUsage(), Validators.PERCENTAGE));
+
+ config.setDiskScanPeriod(getInteger(e, DISK_SCAN_PERIOD, config.getDiskScanPeriod(), Validators.MINUS_ONE_OR_GT_ZERO));
+
// parsing cluster password
String passwordText = getString(e, "cluster-password", null, Validators.NO_CHECK);
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingManager.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingManager.java
index d55c09f..b70626a 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingManager.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingManager.java
@@ -20,6 +20,7 @@ import java.util.Map;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.core.server.ActiveMQComponent;
+import org.apache.activemq.artemis.core.server.files.FileStoreMonitor;
import org.apache.activemq.artemis.core.settings.HierarchicalRepositoryChangeListener;
/**
@@ -78,6 +79,10 @@ public interface PagingManager extends ActiveMQComponent, HierarchicalRepository
void resumeCleanup();
+ void addBlockedStore(PagingStore store);
+
+ void injectMonitor(FileStoreMonitor monitor) throws Exception;
+
/**
* Lock the manager. This method should not be called during normal PagingManager usage.
*/
@@ -89,4 +94,15 @@ public interface PagingManager extends ActiveMQComponent, HierarchicalRepository
* @see #lock()
*/
void unlock();
+
+ /** Add size at the global count level.
+ * if totalSize > globalMaxSize it will return true */
+ PagingManager addSize(int size);
+
+ boolean isUsingGlobalSize();
+
+ boolean isGlobalFull();
+
+ boolean isDiskFull();
+
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStore.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStore.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStore.java
index 79fb115..a4a41ef 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStore.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStore.java
@@ -130,6 +130,9 @@ public interface PagingStore extends ActiveMQComponent {
boolean isRejectingMessages();
+ /** It will return true if the destination is leaving blocking. */
+ boolean checkReleasedMemory();
+
/**
* Write lock the PagingStore.
*
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStoreFactory.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStoreFactory.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStoreFactory.java
index 7c52c63..942ff80 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStoreFactory.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/PagingStoreFactory.java
@@ -23,6 +23,7 @@ import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.paging.cursor.PageCursorProvider;
import org.apache.activemq.artemis.core.persistence.StorageManager;
+import org.apache.activemq.artemis.core.server.files.FileStoreMonitor;
import org.apache.activemq.artemis.core.settings.HierarchicalRepository;
import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
@@ -43,4 +44,6 @@ public interface PagingStoreFactory {
SequentialFileFactory newFileFactory(SimpleString address) throws Exception;
+ void injectMonitor(FileStoreMonitor monitor) throws Exception;
+
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PageSyncTimer.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PageSyncTimer.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PageSyncTimer.java
index a595721..bf90750 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PageSyncTimer.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PageSyncTimer.java
@@ -67,6 +67,8 @@ final class PageSyncTimer {
ctx.pageSyncLineUp();
if (!pendingSync) {
pendingSync = true;
+
+ // this is a single event
scheduledExecutor.schedule(runnable, timeSync, TimeUnit.NANOSECONDS);
}
syncOperations.add(ctx);
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingManagerImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingManagerImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingManagerImpl.java
index 3c76059..a657a22 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingManagerImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingManagerImpl.java
@@ -16,11 +16,14 @@
*/
package org.apache.activemq.artemis.core.paging.impl;
+import java.nio.file.FileStore;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.activemq.artemis.api.core.SimpleString;
@@ -28,8 +31,11 @@ import org.apache.activemq.artemis.core.paging.PageTransactionInfo;
import org.apache.activemq.artemis.core.paging.PagingManager;
import org.apache.activemq.artemis.core.paging.PagingStore;
import org.apache.activemq.artemis.core.paging.PagingStoreFactory;
+import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
+import org.apache.activemq.artemis.core.server.files.FileStoreMonitor;
import org.apache.activemq.artemis.core.settings.HierarchicalRepository;
import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
+import org.apache.activemq.artemis.utils.ConcurrentHashSet;
import org.jboss.logging.Logger;
public final class PagingManagerImpl implements PagingManager {
@@ -46,14 +52,22 @@ public final class PagingManagerImpl implements PagingManager {
*/
private final ReentrantReadWriteLock syncLock = new ReentrantReadWriteLock();
+ private final Set<PagingStore> blockedStored = new ConcurrentHashSet<>();
+
private final ConcurrentMap<SimpleString, PagingStore> stores = new ConcurrentHashMap<>();
private final HierarchicalRepository<AddressSettings> addressSettingsRepository;
private final PagingStoreFactory pagingStoreFactory;
+ private final AtomicLong globalSizeBytes = new AtomicLong(0);
+
+ private final long maxSize;
+
private volatile boolean cleanupEnabled = true;
+ private volatile boolean diskFull = false;
+
private final ConcurrentMap</*TransactionID*/Long, PageTransactionInfo> transactions = new ConcurrentHashMap<>();
// Static
@@ -63,10 +77,21 @@ public final class PagingManagerImpl implements PagingManager {
// --------------------------------------------------------------------------------------------------------------------
public PagingManagerImpl(final PagingStoreFactory pagingSPI,
- final HierarchicalRepository<AddressSettings> addressSettingsRepository) {
+ final HierarchicalRepository<AddressSettings> addressSettingsRepository,
+ final long maxSize) {
pagingStoreFactory = pagingSPI;
this.addressSettingsRepository = addressSettingsRepository;
addressSettingsRepository.registerListener(this);
+ this.maxSize = maxSize;
+ }
+
+ public PagingManagerImpl(final PagingStoreFactory pagingSPI,
+ final HierarchicalRepository<AddressSettings> addressSettingsRepository) {
+ this(pagingSPI, addressSettingsRepository, -1);
+ }
+
+ public void addBlockedStore(PagingStore store) {
+ blockedStored.add(store);
}
@Override
@@ -82,6 +107,72 @@ public final class PagingManagerImpl implements PagingManager {
}
@Override
+ public PagingManagerImpl addSize(int size) {
+ globalSizeBytes.addAndGet(size);
+
+ if (size < 0) {
+ checkMemoryRelease();
+ }
+ return this;
+ }
+
+ protected void checkMemoryRelease() {
+ if (!diskFull && (maxSize < 0 || globalSizeBytes.get() < maxSize) && !blockedStored.isEmpty()) {
+ Iterator<PagingStore> storeIterator = blockedStored.iterator();
+ while (storeIterator.hasNext()) {
+ PagingStore store = storeIterator.next();
+ if (store.checkReleasedMemory()) {
+ storeIterator.remove();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void injectMonitor(FileStoreMonitor monitor) throws Exception {
+ pagingStoreFactory.injectMonitor(monitor);
+ monitor.addCallback(new LocalMonitor());
+ }
+
+ class LocalMonitor implements FileStoreMonitor.Callback {
+
+ @Override
+ public void tick(FileStore store, double usage) {
+ logger.tracef("Tick from store:: %s, usage at %f", store, usage);
+ }
+
+ @Override
+ public void over(FileStore store, double usage) {
+ if (!diskFull) {
+ ActiveMQServerLogger.LOGGER.diskBeyondCapacity();
+ diskFull = true;
+ }
+ }
+
+ @Override
+ public void under(FileStore store, double usage) {
+ if (diskFull) {
+ ActiveMQServerLogger.LOGGER.diskCapacityRestored();
+ diskFull = false;
+ checkMemoryRelease();
+ }
+ }
+ }
+
+ @Override
+ public boolean isDiskFull() {
+ return diskFull;
+ }
+
+ public boolean isUsingGlobalSize() {
+ return maxSize > 0;
+ }
+
+ public boolean isGlobalFull() {
+ return diskFull || maxSize > 0 && globalSizeBytes.get() > maxSize;
+ }
+
+ @Override
public void disableCleanup() {
if (!cleanupEnabled) {
return;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryNIO.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryNIO.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryNIO.java
index c95f214..5093033 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryNIO.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreFactoryNIO.java
@@ -40,7 +40,8 @@ import org.apache.activemq.artemis.core.paging.cursor.PageCursorProvider;
import org.apache.activemq.artemis.core.paging.cursor.impl.PageCursorProviderImpl;
import org.apache.activemq.artemis.core.persistence.StorageManager;
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
-import org.apache.activemq.artemis.core.server.impl.FileMoveManager;
+import org.apache.activemq.artemis.core.server.files.FileMoveManager;
+import org.apache.activemq.artemis.core.server.files.FileStoreMonitor;
import org.apache.activemq.artemis.core.settings.HierarchicalRepository;
import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
import org.apache.activemq.artemis.utils.ExecutorFactory;
@@ -96,6 +97,11 @@ public class PagingStoreFactoryNIO implements PagingStoreFactory {
}
@Override
+ public void injectMonitor(FileStoreMonitor monitor) throws Exception {
+ monitor.addStore(this.directory);
+ }
+
+ @Override
public PageCursorProvider newCursorProvider(PagingStore store, StorageManager storageManager, AddressSettings addressSettings, Executor executor) {
return new PageCursorProviderImpl(store, storageManager, executor, addressSettings.getPageCacheMaxSize());
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreImpl.java
index 7e6cda8..356ea45 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/paging/impl/PagingStoreImpl.java
@@ -98,6 +98,8 @@ public class PagingStoreImpl implements PagingStore {
private final PagingManager pagingManager;
+ private final boolean usingGlobalMaxSize;
+
private final Executor executor;
// Bytes consumed by the queue on the memory
@@ -176,6 +178,7 @@ public class PagingStoreImpl implements PagingStore {
this.cursorProvider = storeFactory.newCursorProvider(this, this.storageManager, addressSettings, executor);
+ this.usingGlobalMaxSize = pagingManager.isUsingGlobalSize();
}
/**
@@ -242,7 +245,13 @@ public class PagingStoreImpl implements PagingStore {
@Override
public long getMaxSize() {
- return maxSize;
+ if (maxSize < 0) {
+ // if maxSize < 0, we will return 2 pages for depage purposes
+ return pageSize * 2;
+ }
+ else {
+ return maxSize;
+ }
}
@Override
@@ -626,7 +635,7 @@ public class PagingStoreImpl implements PagingStore {
}
- private final Queue<OurRunnable> onMemoryFreedRunnables = new ConcurrentLinkedQueue<>();
+ private final Queue<OverSizedRunnable> onMemoryFreedRunnables = new ConcurrentLinkedQueue<>();
private class MemoryFreedRunnablesExecutor implements Runnable {
@@ -642,13 +651,14 @@ public class PagingStoreImpl implements PagingStore {
private final Runnable memoryFreedRunnablesExecutor = new MemoryFreedRunnablesExecutor();
- private static final class OurRunnable implements Runnable {
+ // To be used when the memory is oversized either by local settings or global settings on blocking addresses
+ private static final class OverSizedRunnable implements Runnable {
private boolean ran;
private final Runnable runnable;
- private OurRunnable(final Runnable runnable) {
+ private OverSizedRunnable(final Runnable runnable) {
this.runnable = runnable;
}
@@ -664,9 +674,15 @@ public class PagingStoreImpl implements PagingStore {
@Override
public boolean checkMemory(final Runnable runWhenAvailable) {
- if (addressFullMessagePolicy == AddressFullMessagePolicy.BLOCK && maxSize != -1) {
- if (sizeInBytes.get() > maxSize) {
- OurRunnable ourRunnable = new OurRunnable(runWhenAvailable);
+
+ if (addressFullMessagePolicy == AddressFullMessagePolicy.FAIL && (maxSize != -1 || usingGlobalMaxSize || pagingManager.isDiskFull())) {
+ if (isFull()) {
+ return false;
+ }
+ }
+ else if (pagingManager.isDiskFull() || addressFullMessagePolicy == AddressFullMessagePolicy.BLOCK && (maxSize != -1 || usingGlobalMaxSize)) {
+ if (pagingManager.isDiskFull() || maxSize > 0 && sizeInBytes.get() > maxSize || pagingManager.isGlobalFull()) {
+ OverSizedRunnable ourRunnable = new OverSizedRunnable(runWhenAvailable);
onMemoryFreedRunnables.add(ourRunnable);
@@ -674,23 +690,24 @@ public class PagingStoreImpl implements PagingStore {
// has been added, but the check to execute was done before the element was added
// NOTE! We do not fix this race by locking the whole thing, doing this check provides
// MUCH better performance in a highly concurrent environment
- if (sizeInBytes.get() <= maxSize) {
+ if (!pagingManager.isGlobalFull() && (sizeInBytes.get() <= maxSize || maxSize < 0)) {
// run it now
ourRunnable.run();
}
- else if (!blocking.get()) {
- ActiveMQServerLogger.LOGGER.blockingMessageProduction(address, sizeInBytes.get(), maxSize);
- blocking.set(true);
+ else {
+ if (usingGlobalMaxSize || pagingManager.isDiskFull()) {
+ pagingManager.addBlockedStore(this);
+ }
+
+ if (!blocking.get()) {
+ ActiveMQServerLogger.LOGGER.blockingMessageProduction(address, sizeInBytes.get(), maxSize);
+ blocking.set(true);
+ }
}
return true;
}
}
- else if (addressFullMessagePolicy == AddressFullMessagePolicy.FAIL && maxSize != -1) {
- if (sizeInBytes.get() > maxSize) {
- return false;
- }
- }
runWhenAvailable.run();
@@ -699,40 +716,48 @@ public class PagingStoreImpl implements PagingStore {
@Override
public void addSize(final int size) {
+
+ boolean globalFull = pagingManager.addSize(size).isGlobalFull();
+ long newSize = sizeInBytes.addAndGet(size);
+
if (addressFullMessagePolicy == AddressFullMessagePolicy.BLOCK) {
- if (maxSize != -1) {
- long newSize = sizeInBytes.addAndGet(size);
-
- if (newSize <= maxSize) {
- if (!onMemoryFreedRunnables.isEmpty()) {
- executor.execute(memoryFreedRunnablesExecutor);
- if (blocking.get()) {
- ActiveMQServerLogger.LOGGER.unblockingMessageProduction(address, sizeInBytes.get(), maxSize);
- blocking.set(false);
- }
- }
- }
+ if (usingGlobalMaxSize && !globalFull || maxSize != -1) {
+ checkReleaseMemory(globalFull, newSize);
}
return;
}
else if (addressFullMessagePolicy == AddressFullMessagePolicy.PAGE) {
- final long addressSize = sizeInBytes.addAndGet(size);
-
if (size > 0) {
- if (maxSize > 0 && addressSize > maxSize) {
+ if (maxSize != -1 && newSize > maxSize || globalFull) {
if (startPaging()) {
- ActiveMQServerLogger.LOGGER.pageStoreStart(storeName, addressSize, maxSize);
+ ActiveMQServerLogger.LOGGER.pageStoreStart(storeName, newSize, maxSize);
}
}
}
return;
}
- else if (addressFullMessagePolicy == AddressFullMessagePolicy.DROP || addressFullMessagePolicy == AddressFullMessagePolicy.FAIL) {
- sizeInBytes.addAndGet(size);
+ }
+
+ @Override
+ public boolean checkReleasedMemory() {
+ return checkReleaseMemory(pagingManager.isGlobalFull(), sizeInBytes.get());
+ }
+
+ public boolean checkReleaseMemory(boolean globalOversized, long newSize) {
+ if (!globalOversized && (newSize <= maxSize || maxSize < 0)) {
+ if (!onMemoryFreedRunnables.isEmpty()) {
+ executor.execute(memoryFreedRunnablesExecutor);
+ if (blocking.get()) {
+ ActiveMQServerLogger.LOGGER.unblockingMessageProduction(address, sizeInBytes.get(), maxSize);
+ blocking.set(false);
+ return true;
+ }
+ }
}
+ return false;
}
@Override
@@ -1073,7 +1098,7 @@ public class PagingStoreImpl implements PagingStore {
// To be used on isDropMessagesWhenFull
@Override
public boolean isFull() {
- return maxSize > 0 && getAddressSize() > maxSize;
+ return maxSize > 0 && getAddressSize() > maxSize || pagingManager.isGlobalFull();
}
@Override
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/StorageManager.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/StorageManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/StorageManager.java
index d08b84d..7dcd9d3 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/StorageManager.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/StorageManager.java
@@ -46,6 +46,7 @@ import org.apache.activemq.artemis.core.server.LargeServerMessage;
import org.apache.activemq.artemis.core.server.MessageReference;
import org.apache.activemq.artemis.core.server.RouteContextList;
import org.apache.activemq.artemis.core.server.ServerMessage;
+import org.apache.activemq.artemis.core.server.files.FileStoreMonitor;
import org.apache.activemq.artemis.core.server.group.impl.GroupBinding;
import org.apache.activemq.artemis.core.server.impl.JournalLoader;
import org.apache.activemq.artemis.core.transaction.ResourceManager;
@@ -413,4 +414,7 @@ public interface StorageManager extends IDGenerator, ActiveMQComponent {
* {@link org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl}
*/
void persistIdGenerator();
+
+
+ void injectMonitor(FileStoreMonitor monitor) throws Exception;
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JournalStorageManager.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JournalStorageManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JournalStorageManager.java
index b50e117..d8c28d2 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JournalStorageManager.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/JournalStorageManager.java
@@ -60,6 +60,7 @@ import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
import org.apache.activemq.artemis.core.server.JournalType;
import org.apache.activemq.artemis.core.server.LargeServerMessage;
import org.apache.activemq.artemis.core.server.ServerMessage;
+import org.apache.activemq.artemis.core.server.files.FileStoreMonitor;
import org.apache.activemq.artemis.utils.ExecutorFactory;
import org.jboss.logging.Logger;
@@ -68,6 +69,8 @@ public class JournalStorageManager extends AbstractJournalStorageManager {
private SequentialFileFactory journalFF;
+ private SequentialFileFactory bindingsFF;
+
SequentialFileFactory largeMessagesFactory;
private Journal originalMessageJournal;
@@ -95,7 +98,7 @@ public class JournalStorageManager extends AbstractJournalStorageManager {
throw ActiveMQMessageBundle.BUNDLE.invalidJournal();
}
- SequentialFileFactory bindingsFF = new NIOSequentialFileFactory(config.getBindingsLocation(), criticalErrorListener, config.getJournalMaxIO_NIO());
+ bindingsFF = new NIOSequentialFileFactory(config.getBindingsLocation(), criticalErrorListener, config.getJournalMaxIO_NIO());
Journal localBindings = new JournalImpl(1024 * 1024, 2, config.getJournalCompactMinFiles(), config.getJournalPoolFiles(), config.getJournalCompactPercentage(), bindingsFF, "activemq-bindings", "bindings", 1);
@@ -726,4 +729,11 @@ public class JournalStorageManager extends AbstractJournalStorageManager {
readUnLock();
}
}
+
+ @Override
+ public void injectMonitor(FileStoreMonitor monitor) throws Exception {
+ monitor.addStore(journalFF.getDirectory());
+ monitor.addStore(largeMessagesFactory.getDirectory());
+ monitor.addStore(bindingsFF.getDirectory());
+ }
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageManager.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageManager.java
index 21a9fd9..f13d2fa 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageManager.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/nullpm/NullStorageManager.java
@@ -52,6 +52,7 @@ import org.apache.activemq.artemis.core.server.LargeServerMessage;
import org.apache.activemq.artemis.core.server.MessageReference;
import org.apache.activemq.artemis.core.server.RouteContextList;
import org.apache.activemq.artemis.core.server.ServerMessage;
+import org.apache.activemq.artemis.core.server.files.FileStoreMonitor;
import org.apache.activemq.artemis.core.server.group.impl.GroupBinding;
import org.apache.activemq.artemis.core.server.impl.JournalLoader;
import org.apache.activemq.artemis.core.transaction.ResourceManager;
@@ -83,6 +84,11 @@ public class NullStorageManager implements StorageManager {
}
+ @Override
+ public void injectMonitor(FileStoreMonitor monitor) throws Exception {
+
+ }
+
private static final OperationContext dummyContext = new OperationContext() {
@Override
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQMessageBundle.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQMessageBundle.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQMessageBundle.java
index d7b893f..d416a97 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQMessageBundle.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQMessageBundle.java
@@ -24,6 +24,7 @@ import org.apache.activemq.artemis.api.core.ActiveMQConnectionTimedOutException;
import org.apache.activemq.artemis.api.core.ActiveMQDisconnectedException;
import org.apache.activemq.artemis.api.core.ActiveMQDuplicateMetaDataException;
import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.api.core.ActiveMQIOErrorException;
import org.apache.activemq.artemis.api.core.ActiveMQIllegalStateException;
import org.apache.activemq.artemis.api.core.ActiveMQIncompatibleClientServerException;
import org.apache.activemq.artemis.api.core.ActiveMQInternalErrorException;
@@ -370,4 +371,8 @@ public interface ActiveMQMessageBundle {
@Message(id = 119118, value = "Management method not applicable for current server configuration")
IllegalStateException methodNotApplicable();
+
+ @Message(id = 119119, value = "Disk Capacity is Low, cannot produce more messages.")
+ ActiveMQIOErrorException diskBeyondLimit();
+
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQScheduledComponent.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQScheduledComponent.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQScheduledComponent.java
new file mode 100644
index 0000000..dadf171
--- /dev/null
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQScheduledComponent.java
@@ -0,0 +1,101 @@
+/**
+ * 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.artemis.core.server;
+
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+import org.jboss.logging.Logger;
+
+/** This is for components with a scheduled at a fixed rate. */
+public abstract class ActiveMQScheduledComponent implements ActiveMQComponent, Runnable {
+
+ private static final Logger logger = Logger.getLogger(ActiveMQScheduledComponent.class);
+ private final ScheduledExecutorService scheduledExecutorService;
+ private long period;
+ private TimeUnit timeUnit;
+ private ScheduledFuture future;
+
+ public ActiveMQScheduledComponent(ScheduledExecutorService scheduledExecutorService,
+ long checkPeriod,
+ TimeUnit timeUnit) {
+ this.scheduledExecutorService = scheduledExecutorService;
+ this.period = checkPeriod;
+ this.timeUnit = timeUnit;
+ }
+
+ @Override
+ public synchronized void start() {
+ if (future != null) {
+ return;
+ }
+ if (period >= 0) {
+ future = scheduledExecutorService.scheduleWithFixedDelay(this, period, period, timeUnit);
+ }
+ else {
+ logger.tracef("did not start scheduled executor on %s because period was configured as %d", this, period);
+ }
+ }
+
+ public long getPeriod() {
+ return period;
+ }
+
+ public synchronized ActiveMQScheduledComponent setPeriod(long period) {
+ this.period = period;
+ restartIfNeeded();
+ return this;
+ }
+
+ public TimeUnit getTimeUnit() {
+ return timeUnit;
+ }
+
+ public synchronized ActiveMQScheduledComponent setTimeUnit(TimeUnit timeUnit) {
+ this.timeUnit = timeUnit;
+ restartIfNeeded();
+ return this;
+ }
+
+ @Override
+ public synchronized void stop() {
+ if (future == null) {
+ return; // no big deal
+ }
+
+ future.cancel(false);
+ future = null;
+
+ }
+
+ @Override
+ public synchronized boolean isStarted() {
+ return future != null;
+ }
+
+
+ // this will restart the schedulped component upon changes
+ private void restartIfNeeded() {
+ if (isStarted()) {
+ stop();
+ start();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java
index 7ff773b..7696c01 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java
@@ -1242,6 +1242,16 @@ public interface ActiveMQServerLogger extends BasicLogger {
format = Message.Format.MESSAGE_FORMAT)
void impossibleToRouteGrouped();
+ @LogMessage(level = Logger.Level.WARN)
+ @Message(id = 222210, value = "Storage usage is beyond max-disk-usage. System will start blocking producers.",
+ format = Message.Format.MESSAGE_FORMAT)
+ void diskBeyondCapacity();
+
+ @LogMessage(level = Logger.Level.WARN)
+ @Message(id = 222211, value = "Storage is back to stable now, under max-disk-usage.",
+ format = Message.Format.MESSAGE_FORMAT)
+ void diskCapacityRestored();
+
@LogMessage(level = Logger.Level.ERROR)
@Message(id = 224000, value = "Failure in initialisation", format = Message.Format.MESSAGE_FORMAT)
void initializationError(@Cause Throwable e);
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/files/FileMoveManager.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/files/FileMoveManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/files/FileMoveManager.java
new file mode 100644
index 0000000..3e250f6
--- /dev/null
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/files/FileMoveManager.java
@@ -0,0 +1,218 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.artemis.core.server.files;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.Arrays;
+
+import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
+import org.jboss.logging.Logger;
+
+/**
+ * Used to move files away.
+ * Each time a backup starts its formeter data will be moved to a backup folder called bkp.1, bkp.2, ... etc
+ * We may control the maximum number of folders so we remove old ones.
+ */
+public class FileMoveManager {
+ private static final Logger logger = Logger.getLogger(FileMoveManager.class);
+
+ private final File folder;
+ private int maxFolders;
+ public static final String PREFIX = "oldreplica.";
+
+ private static final FilenameFilter isPrefix = new FilenameFilter() {
+ @Override
+ public boolean accept(File dir, String name) {
+ boolean prefixed = name.contains(PREFIX);
+
+ if (prefixed) {
+ try {
+ Integer.parseInt(name.substring(PREFIX.length()));
+ }
+ catch (NumberFormatException e) {
+ // This function is not really used a lot
+ // so I don't really mind about performance here
+ // this is good enough for what we need
+ prefixed = false;
+ }
+ }
+
+ return prefixed;
+ }
+ };
+
+ private static final FilenameFilter notPrefix = new FilenameFilter() {
+ @Override
+ public boolean accept(File dir, String name) {
+ return !isPrefix.accept(dir, name);
+ }
+ };
+
+
+ public FileMoveManager(File folder) {
+ this(folder, -1);
+ }
+
+ public FileMoveManager(File folder, int maxFolders) {
+ this.folder = folder;
+ this.maxFolders = maxFolders;
+ }
+
+ public int getMaxFolders() {
+ return maxFolders;
+ }
+
+ public FileMoveManager setMaxFolders(int maxFolders) {
+ this.maxFolders = maxFolders;
+ return this;
+ }
+
+ public void doMove() throws IOException {
+ String[] files = getFiles();
+
+ if (files == null || files.length == 0) {
+ // if no files, nothing to be done, no backup, no deletes... nothing!
+ return;
+ }
+
+ // Since we will create one folder, we are already taking that one into consideration
+ internalCheckOldFolders(1);
+
+ int whereToMove = getMaxID() + 1;
+
+ File folderTo = getFolder(whereToMove);
+ folderTo.mkdirs();
+
+ ActiveMQServerLogger.LOGGER.backupMovingDataAway(folder.getPath(), folderTo.getPath());
+
+ for (String fileMove : files) {
+ File fileFrom = new File(folder, fileMove);
+ File fileTo = new File(folderTo, fileMove);
+ logger.tracef("doMove:: moving %s as %s", fileFrom, fileTo);
+ Files.move(fileFrom.toPath(), fileTo.toPath());
+ }
+
+ }
+
+ public void checkOldFolders() {
+ internalCheckOldFolders(0);
+ }
+
+ private void internalCheckOldFolders(int creating) {
+ if (maxFolders > 0) {
+ int folders = getNumberOfFolders();
+
+ // We are counting the next one to be created
+ int foldersToDelete = folders + creating - maxFolders;
+
+ if (foldersToDelete > 0) {
+ logger.tracef("There are %d folders to delete", foldersToDelete);
+ int[] ids = getIDlist();
+ for (int i = 0; i < foldersToDelete; i++) {
+ File file = getFolder(ids[i]);
+ ActiveMQServerLogger.LOGGER.removingBackupData(file.getPath());
+ deleteTree(file);
+ }
+ }
+ }
+ }
+
+ /**
+ * It will return non backup folders
+ */
+ public String[] getFiles() {
+ return folder.list(notPrefix);
+ }
+
+
+ public int getNumberOfFolders() {
+ return getFolders().length;
+ }
+
+ public String[] getFolders() {
+ String[] list = folder.list(isPrefix);
+
+ if (list == null) {
+ list = new String[0];
+ }
+
+
+ return list;
+ }
+
+
+ public int getMinID() {
+ int[] list = getIDlist();
+
+ if (list.length == 0) {
+ return 0;
+ }
+
+ return list[0];
+ }
+
+ public int getMaxID() {
+ int[] list = getIDlist();
+
+ if (list.length == 0) {
+ return 0;
+ }
+
+ return list[list.length - 1];
+ }
+
+
+ public int[] getIDlist() {
+ String[] list = getFolders();
+ int[] ids = new int[list.length];
+ for (int i = 0; i < ids.length; i++) {
+ ids[i] = getID(list[i]);
+ }
+
+ Arrays.sort(ids);
+
+ return ids;
+ }
+
+ public int getID(String folderName) {
+ return Integer.parseInt(folderName.substring(PREFIX.length()));
+ }
+
+
+ public File getFolder(int id) {
+ return new File(folder, PREFIX + id);
+ }
+
+
+ private void deleteTree(File file) {
+ File[] files = file.listFiles();
+
+ if (files != null) {
+ for (File fileDelete : files) {
+ deleteTree(fileDelete);
+ }
+ }
+
+ file.delete();
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/files/FileStoreMonitor.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/files/FileStoreMonitor.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/files/FileStoreMonitor.java
new file mode 100644
index 0000000..f75f6c6
--- /dev/null
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/files/FileStoreMonitor.java
@@ -0,0 +1,127 @@
+/**
+ * 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.artemis.core.server.files;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileStore;
+import java.nio.file.Files;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.activemq.artemis.core.server.ActiveMQScheduledComponent;
+import org.jboss.logging.Logger;
+
+/** This will keep a list of fileStores. It will make a comparisson on all file stores registered. if any is over the limit,
+ * all Callbacks will be called with over.
+ *
+ * For instance: if Large Messages folder is registered on a different folder and it's over capacity,
+ * the whole system will be waiting it to be released.
+ * */
+public class FileStoreMonitor extends ActiveMQScheduledComponent {
+
+ private static final Logger logger = Logger.getLogger(FileStoreMonitor.class);
+
+ private final Set<Callback> callbackList = new HashSet<>();
+ private final Set<FileStore> stores = new HashSet<>();
+ private double maxUsage;
+
+ public FileStoreMonitor(ScheduledExecutorService scheduledExecutorService,
+ long checkPeriod,
+ TimeUnit timeUnit,
+ double maxUsage) {
+ super(scheduledExecutorService, checkPeriod, timeUnit);
+ this.maxUsage = maxUsage;
+ }
+
+ public synchronized FileStoreMonitor addCallback(Callback callback) {
+ callbackList.add(callback);
+ return this;
+ }
+
+ public synchronized FileStoreMonitor addStore(File file) throws IOException {
+ if (file.exists()) {
+ addStore(Files.getFileStore(file.toPath()));
+ }
+ return this;
+ }
+
+ public synchronized FileStoreMonitor addStore(FileStore store) {
+ stores.add(store);
+ return this;
+ }
+
+
+ public void run() {
+ tick();
+ }
+
+ public synchronized void tick() {
+ boolean over = false;
+
+ FileStore lastStore = null;
+ double usage = 0;
+
+ for (FileStore store : stores) {
+ try {
+ lastStore = store;
+ usage = calculateUsage(store);
+ over = usage > maxUsage;
+ if (over) {
+ break;
+ }
+ }
+ catch (Exception e) {
+ logger.warn(e.getMessage(), e);
+ }
+ }
+
+ for (Callback callback : callbackList) {
+ callback.tick(lastStore, usage);
+
+ if (over) {
+ callback.over(lastStore, usage);
+ }
+ else {
+ callback.under(lastStore, usage);
+ }
+ }
+ }
+
+ public double getMaxUsage() {
+ return maxUsage;
+ }
+
+ public FileStoreMonitor setMaxUsage(double maxUsage) {
+ this.maxUsage = maxUsage;
+ return this;
+ }
+
+ protected double calculateUsage(FileStore store) throws IOException {
+ return 1.0 - (double)store.getUsableSpace() / (double)store.getTotalSpace();
+ }
+
+ public interface Callback {
+ void tick(FileStore store, double usage);
+ void over(FileStore store, double usage);
+ void under(FileStore store, double usage);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
index dba7e5b..680af8a 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
@@ -123,6 +123,8 @@ import org.apache.activemq.artemis.core.server.cluster.BackupManager;
import org.apache.activemq.artemis.core.server.cluster.ClusterManager;
import org.apache.activemq.artemis.core.server.cluster.Transformer;
import org.apache.activemq.artemis.core.server.cluster.ha.HAPolicy;
+import org.apache.activemq.artemis.core.server.files.FileMoveManager;
+import org.apache.activemq.artemis.core.server.files.FileStoreMonitor;
import org.apache.activemq.artemis.core.server.group.GroupingHandler;
import org.apache.activemq.artemis.core.server.group.impl.GroupingHandlerConfiguration;
import org.apache.activemq.artemis.core.server.group.impl.LocalGroupingHandler;
@@ -249,6 +251,8 @@ public class ActiveMQServerImpl implements ActiveMQServer {
private ReloadManager reloadManager;
+ private FileStoreMonitor fileStoreMonitor;
+
/**
* This will be set by the JMS Queue Manager.
*/
@@ -756,6 +760,11 @@ public class ActiveMQServerImpl implements ActiveMQServer {
}
state = SERVER_STATE.STOPPING;
+ if (fileStoreMonitor != null) {
+ fileStoreMonitor.stop();
+ fileStoreMonitor = null;
+ }
+
activation.sendLiveIsStopping();
stopComponent(connectorsService);
@@ -1277,7 +1286,10 @@ public class ActiveMQServerImpl implements ActiveMQServer {
SessionCallback callback,
OperationContext context,
boolean autoCreateJMSQueues) throws Exception {
- return new ServerSessionImpl(name, username, password, validatedUser, minLargeMessageSize, autoCommitSends, autoCommitAcks, preAcknowledge, configuration.isPersistDeliveryCountBeforeDelivery(), xa, connection, storageManager, postOffice, resourceManager, securityStore, managementService, this, configuration.getManagementAddress(), defaultAddress == null ? null : new SimpleString(defaultAddress), callback, context, autoCreateJMSQueues ? jmsQueueCreator : null);
+ return new ServerSessionImpl(name, username, password, validatedUser, minLargeMessageSize, autoCommitSends, autoCommitAcks, preAcknowledge, configuration.isPersistDeliveryCountBeforeDelivery(),
+ xa, connection, storageManager, postOffice, resourceManager, securityStore, managementService, this, configuration.getManagementAddress(),
+ defaultAddress == null ? null : new SimpleString(defaultAddress), callback, context, autoCreateJMSQueues ? jmsQueueCreator : null,
+ pagingManager);
}
@Override
@@ -1771,8 +1783,7 @@ public class ActiveMQServerImpl implements ActiveMQServer {
}
protected PagingManager createPagingManager() {
-
- return new PagingManagerImpl(getPagingStoreFactory(), addressSettingsRepository);
+ return new PagingManagerImpl(getPagingStoreFactory(), addressSettingsRepository, configuration.getGlobalMaxSize());
}
protected PagingStoreFactoryNIO getPagingStoreFactory() {
@@ -2042,6 +2053,25 @@ public class ActiveMQServerImpl implements ActiveMQServer {
// We can only do this after everything is started otherwise we may get nasty races with expired messages
postOffice.startExpiryScanner();
}
+
+ try {
+ injectMonitor(new FileStoreMonitor(getScheduledPool(), configuration.getDiskScanPeriod(), TimeUnit.MILLISECONDS, configuration.getMaxDiskUsage() / 100f));
+ }
+ catch (Exception e) {
+ logger.warn(e.getMessage(), e);
+ }
+ }
+
+ /** This method exists for a possibility of test cases replacing the FileStoreMonitor for an extension that would for instance pretend a disk full on certain tests. */
+ public void injectMonitor(FileStoreMonitor storeMonitor) throws Exception {
+ this.fileStoreMonitor = storeMonitor;
+ pagingManager.injectMonitor(storeMonitor);
+ storageManager.injectMonitor(storeMonitor);
+ fileStoreMonitor.start();
+ }
+
+ public FileStoreMonitor getMonitor() {
+ return fileStoreMonitor;
}
public void completeActivation() throws Exception {
@@ -2075,8 +2105,9 @@ public class ActiveMQServerImpl implements ActiveMQServer {
addressCount++;
}
+
long maxMemory = Runtime.getRuntime().maxMemory();
- if (totalMaxSizeBytes >= maxMemory) {
+ if (totalMaxSizeBytes >= maxMemory && configuration.getGlobalMaxSize() < 0) {
ActiveMQServerLogger.LOGGER.potentialOOME(addressCount, totalMaxSizeBytes, maxMemory);
}
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/FileMoveManager.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/FileMoveManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/FileMoveManager.java
deleted file mode 100644
index efe1bb2..0000000
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/FileMoveManager.java
+++ /dev/null
@@ -1,218 +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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.artemis.core.server.impl;
-
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.util.Arrays;
-
-import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
-import org.jboss.logging.Logger;
-
-/**
- * Used to move files away.
- * Each time a backup starts its formeter data will be moved to a backup folder called bkp.1, bkp.2, ... etc
- * We may control the maximum number of folders so we remove old ones.
- */
-public class FileMoveManager {
- private static final Logger logger = Logger.getLogger(FileMoveManager.class);
-
- private final File folder;
- private int maxFolders;
- public static final String PREFIX = "oldreplica.";
-
- private static final FilenameFilter isPrefix = new FilenameFilter() {
- @Override
- public boolean accept(File dir, String name) {
- boolean prefixed = name.contains(PREFIX);
-
- if (prefixed) {
- try {
- Integer.parseInt(name.substring(PREFIX.length()));
- }
- catch (NumberFormatException e) {
- // This function is not really used a lot
- // so I don't really mind about performance here
- // this is good enough for what we need
- prefixed = false;
- }
- }
-
- return prefixed;
- }
- };
-
- private static final FilenameFilter notPrefix = new FilenameFilter() {
- @Override
- public boolean accept(File dir, String name) {
- return !isPrefix.accept(dir, name);
- }
- };
-
-
- public FileMoveManager(File folder) {
- this(folder, -1);
- }
-
- public FileMoveManager(File folder, int maxFolders) {
- this.folder = folder;
- this.maxFolders = maxFolders;
- }
-
- public int getMaxFolders() {
- return maxFolders;
- }
-
- public FileMoveManager setMaxFolders(int maxFolders) {
- this.maxFolders = maxFolders;
- return this;
- }
-
- public void doMove() throws IOException {
- String[] files = getFiles();
-
- if (files == null || files.length == 0) {
- // if no files, nothing to be done, no backup, no deletes... nothing!
- return;
- }
-
- // Since we will create one folder, we are already taking that one into consideration
- internalCheckOldFolders(1);
-
- int whereToMove = getMaxID() + 1;
-
- File folderTo = getFolder(whereToMove);
- folderTo.mkdirs();
-
- ActiveMQServerLogger.LOGGER.backupMovingDataAway(folder.getPath(), folderTo.getPath());
-
- for (String fileMove : files) {
- File fileFrom = new File(folder, fileMove);
- File fileTo = new File(folderTo, fileMove);
- logger.tracef("doMove:: moving %s as %s", fileFrom, fileTo);
- Files.move(fileFrom.toPath(), fileTo.toPath());
- }
-
- }
-
- public void checkOldFolders() {
- internalCheckOldFolders(0);
- }
-
- private void internalCheckOldFolders(int creating) {
- if (maxFolders > 0) {
- int folders = getNumberOfFolders();
-
- // We are counting the next one to be created
- int foldersToDelete = folders + creating - maxFolders;
-
- if (foldersToDelete > 0) {
- logger.tracef("There are %d folders to delete", foldersToDelete);
- int[] ids = getIDlist();
- for (int i = 0; i < foldersToDelete; i++) {
- File file = getFolder(ids[i]);
- ActiveMQServerLogger.LOGGER.removingBackupData(file.getPath());
- deleteTree(file);
- }
- }
- }
- }
-
- /**
- * It will return non backup folders
- */
- public String[] getFiles() {
- return folder.list(notPrefix);
- }
-
-
- public int getNumberOfFolders() {
- return getFolders().length;
- }
-
- public String[] getFolders() {
- String[] list = folder.list(isPrefix);
-
- if (list == null) {
- list = new String[0];
- }
-
-
- return list;
- }
-
-
- public int getMinID() {
- int[] list = getIDlist();
-
- if (list.length == 0) {
- return 0;
- }
-
- return list[0];
- }
-
- public int getMaxID() {
- int[] list = getIDlist();
-
- if (list.length == 0) {
- return 0;
- }
-
- return list[list.length - 1];
- }
-
-
- public int[] getIDlist() {
- String[] list = getFolders();
- int[] ids = new int[list.length];
- for (int i = 0; i < ids.length; i++) {
- ids[i] = getID(list[i]);
- }
-
- Arrays.sort(ids);
-
- return ids;
- }
-
- public int getID(String folderName) {
- return Integer.parseInt(folderName.substring(PREFIX.length()));
- }
-
-
- public File getFolder(int id) {
- return new File(folder, PREFIX + id);
- }
-
-
- private void deleteTree(File file) {
- File[] files = file.listFiles();
-
- if (files != null) {
- for (File fileDelete : files) {
- deleteTree(fileDelete);
- }
- }
-
- file.delete();
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
index 893b615..d20fa43 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
@@ -32,6 +32,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.api.core.ActiveMQIOErrorException;
import org.apache.activemq.artemis.api.core.ActiveMQIllegalStateException;
import org.apache.activemq.artemis.api.core.ActiveMQNonExistentQueueException;
import org.apache.activemq.artemis.api.core.Message;
@@ -47,6 +48,7 @@ import org.apache.activemq.artemis.core.filter.Filter;
import org.apache.activemq.artemis.core.filter.impl.FilterImpl;
import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.core.message.impl.MessageInternal;
+import org.apache.activemq.artemis.core.paging.PagingManager;
import org.apache.activemq.artemis.core.paging.PagingStore;
import org.apache.activemq.artemis.core.persistence.OperationContext;
import org.apache.activemq.artemis.core.persistence.StorageManager;
@@ -128,6 +130,8 @@ public class ServerSessionImpl implements ServerSession, FailureListener {
protected boolean xa;
+ protected final PagingManager pagingManager;
+
protected final StorageManager storageManager;
private final ResourceManager resourceManager;
@@ -199,7 +203,8 @@ public class ServerSessionImpl implements ServerSession, FailureListener {
final SimpleString defaultAddress,
final SessionCallback callback,
final OperationContext context,
- final QueueCreator queueCreator) throws Exception {
+ final QueueCreator queueCreator,
+ final PagingManager pagingManager) throws Exception {
this.username = username;
this.password = password;
@@ -224,6 +229,8 @@ public class ServerSessionImpl implements ServerSession, FailureListener {
this.securityStore = securityStore;
+ this.pagingManager = pagingManager;
+
timeoutSeconds = resourceManager.getTimeoutSeconds();
this.xa = xa;
@@ -1249,6 +1256,14 @@ public class ServerSessionImpl implements ServerSession, FailureListener {
@Override
public RoutingStatus send(final ServerMessage message, final boolean direct, boolean noAutoCreateQueue) throws Exception {
+
+ // If the protocol doesn't support flow control, we have no choice other than fail the communication
+ if (!this.getRemotingConnection().isSupportsFlowControl() && pagingManager.isDiskFull()) {
+ ActiveMQIOErrorException exception = ActiveMQMessageBundle.BUNDLE.diskBeyondLimit();
+ this.getRemotingConnection().fail(exception);
+ throw exception;
+ }
+
RoutingStatus result = RoutingStatus.OK;
//large message may come from StompSession directly, in which
//case the id header already generated.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/reload/ReloadManagerImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/reload/ReloadManagerImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/reload/ReloadManagerImpl.java
index a735b93..7686ac5 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/reload/ReloadManagerImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/reload/ReloadManagerImpl.java
@@ -24,33 +24,25 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
+import org.apache.activemq.artemis.core.server.ActiveMQScheduledComponent;
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
import org.jboss.logging.Logger;
-public class ReloadManagerImpl implements ReloadManager {
+public class ReloadManagerImpl extends ActiveMQScheduledComponent implements ReloadManager {
private static final Logger logger = Logger.getLogger(ReloadManagerImpl.class);
- private final ScheduledExecutorService scheduledExecutorService;
- private final long checkPeriod;
- private ScheduledFuture future;
private volatile Runnable tick;
private Map<URL, ReloadRegistry> registry = new HashMap<>();
public ReloadManagerImpl(ScheduledExecutorService scheduledExecutorService, long checkPeriod) {
- this.scheduledExecutorService = scheduledExecutorService;
- this.checkPeriod = checkPeriod;
+ super(scheduledExecutorService, checkPeriod, TimeUnit.MILLISECONDS);
}
- @Override
- public synchronized void start() {
- if (future != null) {
- return;
- }
- future = scheduledExecutorService.scheduleWithFixedDelay(new ConfigurationFileReloader(), checkPeriod, checkPeriod, TimeUnit.MILLISECONDS);
+ public void run() {
+ tick();
}
@Override
@@ -59,24 +51,8 @@ public class ReloadManagerImpl implements ReloadManager {
}
@Override
- public synchronized void stop() {
- if (future == null) {
- return; // no big deal
- }
-
- future.cancel(false);
- future = null;
-
- }
-
- @Override
- public synchronized boolean isStarted() {
- return future != null;
- }
-
- @Override
public synchronized void addCallback(URL uri, ReloadCallback callback) {
- if (future == null) {
+ if (!isStarted()) {
start();
}
ReloadRegistry uriRegistry = getRegistry(uri);
@@ -104,20 +80,6 @@ public class ReloadManagerImpl implements ReloadManager {
return uriRegistry;
}
-
-
- private final class ConfigurationFileReloader implements Runnable {
- @Override
- public void run() {
- try {
- tick();
- }
- catch (Exception e) {
- ActiveMQServerLogger.LOGGER.configurationReloadFailed(e);
- }
- }
- }
-
class ReloadRegistry {
private final File file;
private final URL uri;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/main/resources/schema/artemis-configuration.xsd
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/resources/schema/artemis-configuration.xsd b/artemis-server/src/main/resources/schema/artemis-configuration.xsd
index 56c5e26..4d4abd7 100644
--- a/artemis-server/src/main/resources/schema/artemis-configuration.xsd
+++ b/artemis-server/src/main/resources/schema/artemis-configuration.xsd
@@ -676,6 +676,30 @@
</xsd:annotation>
</xsd:element>
+ <xsd:element name="global-max-size" type="xsd:long" default="-1" maxOccurs="1" minOccurs="0">
+ <xsd:annotation>
+ <xsd:documentation>
+ Global Max Size before all addresses will enter into their Full Policy configured upon messages being produced.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+
+ <xsd:element name="max-disk-usage" type="xsd:int" default="90" maxOccurs="1" minOccurs="0">
+ <xsd:annotation>
+ <xsd:documentation>
+ Max percentage of disk usage before the system blocks or fail clients.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+
+ <xsd:element name="disk-scan-period" type="xsd:long" default="5000" maxOccurs="1" minOccurs="0">
+ <xsd:annotation>
+ <xsd:documentation>
+ how often (in ms) to scan the disks for full disks.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+
<xsd:element name="memory-warning-threshold" type="xsd:int" default="25" maxOccurs="1" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java
index ba2cb7f..6045c8d 100644
--- a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java
+++ b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java
@@ -356,6 +356,9 @@ public class FileConfigurationTest extends ConfigurationImplTest {
assertFalse(a2Role.isCreateNonDurableQueue());
assertTrue(a2Role.isDeleteNonDurableQueue());
assertFalse(a2Role.isManage());
+ assertEquals(1234567, conf.getGlobalMaxSize());
+ assertEquals(37, conf.getMaxDiskUsage());
+ assertEquals(123, conf.getDiskScanPeriod());
}
@Test
[4/7] activemq-artemis git commit: ARTEMIS-581 Implement max disk
usage, and global-max-size
Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/BackupSyncJournalTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/BackupSyncJournalTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/BackupSyncJournalTest.java
index c32ebc1..b80df4e 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/BackupSyncJournalTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/BackupSyncJournalTest.java
@@ -41,7 +41,7 @@ import org.apache.activemq.artemis.core.paging.PagingStore;
import org.apache.activemq.artemis.core.persistence.impl.journal.DescribeJournal;
import org.apache.activemq.artemis.core.persistence.impl.journal.JournalStorageManager;
import org.apache.activemq.artemis.core.server.Queue;
-import org.apache.activemq.artemis.core.server.impl.FileMoveManager;
+import org.apache.activemq.artemis.core.server.files.FileMoveManager;
import org.apache.activemq.artemis.tests.integration.cluster.util.BackupSyncDelay;
import org.apache.activemq.artemis.tests.integration.cluster.util.TestableServer;
import org.apache.activemq.artemis.tests.util.TransportConfigurationUtils;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailoverTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailoverTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailoverTest.java
index f915a31..9e4a650 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailoverTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/FailoverTest.java
@@ -51,7 +51,7 @@ import org.apache.activemq.artemis.core.server.cluster.ha.ReplicaPolicy;
import org.apache.activemq.artemis.core.server.cluster.ha.ReplicatedPolicy;
import org.apache.activemq.artemis.core.server.cluster.ha.SharedStoreMasterPolicy;
import org.apache.activemq.artemis.core.server.cluster.ha.SharedStoreSlavePolicy;
-import org.apache.activemq.artemis.core.server.impl.FileMoveManager;
+import org.apache.activemq.artemis.core.server.files.FileMoveManager;
import org.apache.activemq.artemis.core.server.impl.InVMNodeManager;
import org.apache.activemq.artemis.core.transaction.impl.XidImpl;
import org.apache.activemq.artemis.jms.client.ActiveMQTextMessage;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/paging/AddressFullLoggingTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/paging/AddressFullLoggingTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/paging/AddressFullLoggingTest.java
new file mode 100644
index 0000000..f6003c5
--- /dev/null
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/paging/AddressFullLoggingTest.java
@@ -0,0 +1,152 @@
+/*
+ * 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.artemis.tests.integration.paging;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.api.core.client.ClientConsumer;
+import org.apache.activemq.artemis.api.core.client.ClientMessage;
+import org.apache.activemq.artemis.api.core.client.ClientProducer;
+import org.apache.activemq.artemis.api.core.client.ClientSession;
+import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
+import org.apache.activemq.artemis.api.core.client.ServerLocator;
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy;
+import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
+import org.apache.activemq.artemis.logs.AssertionLoggerHandler;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
+import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class AddressFullLoggingTest extends ActiveMQTestBase {
+
+ @BeforeClass
+ public static void prepareLogger() {
+ AssertionLoggerHandler.startCapture();
+ }
+
+ @Test
+ public void testBlockLogging() throws Exception {
+ final int MAX_MESSAGES = 200;
+ final String MY_ADDRESS = "myAddress";
+ final String MY_QUEUE = "myQueue";
+
+ ActiveMQServer server = createServer(false);
+
+ AddressSettings defaultSetting = new AddressSettings().setPageSizeBytes(10 * 1024).setMaxSizeBytes(20 * 1024).setAddressFullMessagePolicy(AddressFullMessagePolicy.BLOCK);
+ server.getAddressSettingsRepository().addMatch("#", defaultSetting);
+ server.start();
+
+ internalTest(MAX_MESSAGES, MY_ADDRESS, MY_QUEUE, server);
+ }
+
+ @Test
+ public void testGlobalBlockLogging() throws Exception {
+ final int MAX_MESSAGES = 200;
+ final String MY_ADDRESS = "myAddress";
+ final String MY_QUEUE = "myQueue";
+
+ ActiveMQServer server = createServer(false);
+
+ AddressSettings defaultSetting = new AddressSettings().setAddressFullMessagePolicy(AddressFullMessagePolicy.BLOCK);
+ server.getAddressSettingsRepository().addMatch("#", defaultSetting);
+ server.getConfiguration().setGlobalMaxSize(20 * 1024);
+
+ server.start();
+
+
+ internalTest(MAX_MESSAGES, MY_ADDRESS, MY_QUEUE, server);
+ }
+
+ private void internalTest(int MAX_MESSAGES,
+ String MY_ADDRESS,
+ String MY_QUEUE,
+ ActiveMQServer server) throws Exception {
+ ServerLocator locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
+
+ ClientSessionFactory factory = createSessionFactory(locator);
+ ClientSession session = factory.createSession(false, true, true);
+
+ session.createQueue(MY_ADDRESS, MY_QUEUE, true);
+
+ final ClientProducer producer = session.createProducer(MY_ADDRESS);
+
+ final ClientMessage message = session.createMessage(false);
+ message.getBodyBuffer().writeBytes(new byte[1024]);
+
+ ExecutorService executor = Executors.newFixedThreadPool(1, ActiveMQThreadFactory.defaultThreadFactory());
+ Callable<Object> sendMessageTask = new Callable<Object>() {
+ @Override
+ public Object call() throws ActiveMQException {
+ producer.send(message);
+ return null;
+ }
+ };
+
+ int sendCount = 0;
+
+ for (int i = 0; i < MAX_MESSAGES; i++) {
+ Future<Object> future = executor.submit(sendMessageTask);
+ try {
+ future.get(3, TimeUnit.SECONDS);
+ sendCount++;
+ }
+ catch (TimeoutException ex) {
+ // message sending has been blocked
+ break;
+ }
+ finally {
+ future.cancel(true); // may or may not desire this
+ }
+ }
+
+ executor.shutdown();
+ session.close();
+
+ session = factory.createSession(false, true, true);
+ session.start();
+ ClientConsumer consumer = session.createConsumer(MY_QUEUE);
+ for (int i = 0; i < sendCount; i++) {
+ ClientMessage msg = consumer.receive(250);
+ if (msg == null)
+ break;
+ msg.acknowledge();
+ }
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ // Using the code only so the test doesn't fail just because someone edits the log text
+ Assert.assertTrue("Expected to find AMQ222183", AssertionLoggerHandler.findText("AMQ222183", "myAddress"));
+ Assert.assertTrue("Expected to find AMQ221046", AssertionLoggerHandler.findText("AMQ221046", "myAddress"));
+ }
+
+ @AfterClass
+ public static void clearLogger() {
+ AssertionLoggerHandler.stopCapture();
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/paging/GlobalPagingTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/paging/GlobalPagingTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/paging/GlobalPagingTest.java
new file mode 100644
index 0000000..ee975ca
--- /dev/null
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/paging/GlobalPagingTest.java
@@ -0,0 +1,183 @@
+/*
+ * 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.artemis.tests.integration.paging;
+
+import java.nio.ByteBuffer;
+import java.util.Map;
+
+import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
+import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.api.core.client.ClientConsumer;
+import org.apache.activemq.artemis.api.core.client.ClientMessage;
+import org.apache.activemq.artemis.api.core.client.ClientProducer;
+import org.apache.activemq.artemis.api.core.client.ClientSession;
+import org.apache.activemq.artemis.core.config.Configuration;
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import org.apache.activemq.artemis.core.server.ActiveMQServers;
+import org.apache.activemq.artemis.core.server.Queue;
+import org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl;
+import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy;
+import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class GlobalPagingTest extends PagingTest {
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected ActiveMQServer createServer(final boolean realFiles,
+ final Configuration configuration,
+ final long pageSize,
+ final long maxAddressSize,
+ final Map<String, AddressSettings> settings) {
+ ActiveMQServer server = addServer(ActiveMQServers.newActiveMQServer(configuration, realFiles));
+
+ if (settings != null) {
+ for (Map.Entry<String, AddressSettings> setting : settings.entrySet()) {
+ server.getAddressSettingsRepository().addMatch(setting.getKey(), setting.getValue());
+ }
+ }
+
+ server.getConfiguration().setGlobalMaxSize(maxAddressSize);
+ AddressSettings defaultSetting = new AddressSettings().setPageSizeBytes(pageSize).setMaxSizeBytes(-1).setAddressFullMessagePolicy(AddressFullMessagePolicy.PAGE);
+
+ server.getAddressSettingsRepository().addMatch("#", defaultSetting);
+
+ return server;
+ }
+
+
+
+ @Test
+ public void testPagingOverFullDisk() throws Exception {
+ clearDataRecreateServerDirs();
+
+ Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
+
+ server = createServer(true, config, PagingTest.PAGE_SIZE, PagingTest.PAGE_MAX);
+ server.getConfiguration().setGlobalMaxSize(-1);
+
+ server.start();
+
+ ActiveMQServerImpl serverImpl = (ActiveMQServerImpl)server;
+ serverImpl.getMonitor().stop(); // stop the scheduled executor, we will do it manually only
+ serverImpl.getMonitor().tick();
+
+ final int numberOfMessages = 500;
+
+ locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
+
+ sf = createSessionFactory(locator);
+
+ final ClientSession session = sf.createSession(false, false, false);
+
+ session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
+
+ final ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ ClientMessage message = null;
+
+ final byte[] body = new byte[MESSAGE_SIZE];
+
+ ByteBuffer bb = ByteBuffer.wrap(body);
+
+ for (int j = 1; j <= MESSAGE_SIZE; j++) {
+ bb.put(getSamplebyte(j));
+ }
+
+
+ Queue queue = server.locateQueue(ADDRESS);
+ queue.getPageSubscription().getPagingStore().forceAnotherPage();
+
+ sendFewMessages(numberOfMessages, session, producer, body);
+
+ serverImpl.getMonitor().setMaxUsage(0); // forcing disk full (faking it)
+
+ serverImpl.getMonitor().tick();
+
+ Thread t = new Thread() {
+ public void run() {
+ try {
+ sendFewMessages(numberOfMessages, session, producer, body);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ };
+
+ t.start();
+
+ t.join(1000);
+ Assert.assertTrue(t.isAlive());
+
+ // releasing the disk
+ serverImpl.getMonitor().setMaxUsage(1).tick();
+ t.join(5000);
+ Assert.assertFalse(t.isAlive());
+
+
+ session.start();
+
+ assertEquals(numberOfMessages * 2, getMessageCount(queue));
+
+ // The consumer has to be created after the getMessageCount(queue) assertion
+ // otherwise delivery could alter the messagecount and give us a false failure
+ ClientConsumer consumer = session.createConsumer(PagingTest.ADDRESS);
+ ClientMessage msg = null;
+
+ for (int i = 0; i < numberOfMessages * 2; i++) {
+ msg = consumer.receive(1000);
+ assertNotNull(msg);
+ msg.acknowledge();
+ if (i % 500 == 0) {
+ session.commit();
+ }
+ }
+ session.commit();
+
+ assertEquals(0, getMessageCount(queue));
+ }
+
+ protected void sendFewMessages(int numberOfMessages,
+ ClientSession session,
+ ClientProducer producer,
+ byte[] body) throws ActiveMQException {
+ ClientMessage message;
+ for (int i = 0; i < numberOfMessages; i++) {
+ message = session.createMessage(true);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ producer.send(message);
+ if (i % 1000 == 0) {
+ session.commit();
+ }
+ }
+ session.commit();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/paging/PagingOrderTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/paging/PagingOrderTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/paging/PagingOrderTest.java
new file mode 100644
index 0000000..54c658f
--- /dev/null
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/paging/PagingOrderTest.java
@@ -0,0 +1,714 @@
+/*
+ * 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.artemis.tests.integration.paging;
+
+import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
+import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.api.core.TransportConfiguration;
+import org.apache.activemq.artemis.api.core.client.ClientConsumer;
+import org.apache.activemq.artemis.api.core.client.ClientMessage;
+import org.apache.activemq.artemis.api.core.client.ClientProducer;
+import org.apache.activemq.artemis.api.core.client.ClientSession;
+import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
+import org.apache.activemq.artemis.api.core.client.ServerLocator;
+import org.apache.activemq.artemis.api.jms.ActiveMQJMSClient;
+import org.apache.activemq.artemis.api.jms.JMSFactoryType;
+import org.apache.activemq.artemis.core.config.Configuration;
+import org.apache.activemq.artemis.core.paging.PagingStore;
+import org.apache.activemq.artemis.core.postoffice.Binding;
+import org.apache.activemq.artemis.core.postoffice.Bindings;
+import org.apache.activemq.artemis.core.postoffice.impl.LocalQueueBinding;
+import org.apache.activemq.artemis.core.registry.JndiBindingRegistry;
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import org.apache.activemq.artemis.core.server.Queue;
+import org.apache.activemq.artemis.core.server.impl.QueueImpl;
+import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy;
+import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
+import org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory;
+import org.apache.activemq.artemis.jms.server.impl.JMSServerManagerImpl;
+import org.apache.activemq.artemis.tests.unit.util.InVMNamingContext;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
+import org.junit.Test;
+
+import javax.jms.BytesMessage;
+import javax.jms.Connection;
+import javax.jms.DeliveryMode;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * A PagingOrderTest. PagingTest has a lot of tests already. I decided to create a newer one more
+ * specialized on Ordering and counters
+ */
+public class PagingOrderTest extends ActiveMQTestBase {
+
+ private static final int PAGE_MAX = 100 * 1024;
+
+ private static final int PAGE_SIZE = 10 * 1024;
+
+ // Attributes ----------------------------------------------------
+
+ // Static --------------------------------------------------------
+
+ static final SimpleString ADDRESS = new SimpleString("SimpleAddress");
+
+ private Connection conn;
+
+ @Test
+ public void testOrder1() throws Throwable {
+ boolean persistentMessages = true;
+
+ Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
+
+ ActiveMQServer server = createServer(true, config, PAGE_SIZE, PAGE_MAX, new HashMap<String, AddressSettings>());
+
+ server.start();
+
+ final int messageSize = 1024;
+
+ final int numberOfMessages = 500;
+
+ ServerLocator locator = createInVMNonHALocator().setClientFailureCheckPeriod(1000).setConnectionTTL(2000).setReconnectAttempts(0).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setConsumerWindowSize(1024 * 1024);
+
+ ClientSessionFactory sf = createSessionFactory(locator);
+
+ ClientSession session = sf.createSession(false, false, false);
+
+ server.createQueue(ADDRESS, ADDRESS, null, true, false);
+
+ ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ byte[] body = new byte[messageSize];
+
+ ByteBuffer bb = ByteBuffer.wrap(body);
+
+ for (int j = 1; j <= messageSize; j++) {
+ bb.put(getSamplebyte(j));
+ }
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ ClientMessage message = session.createMessage(persistentMessages);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ message.putIntProperty(new SimpleString("id"), i);
+
+ producer.send(message);
+ if (i % 1000 == 0) {
+ session.commit();
+ }
+ }
+
+ session.commit();
+
+ session.close();
+
+ session = sf.createSession(true, true, 0);
+
+ session.start();
+
+ ClientConsumer consumer = session.createConsumer(ADDRESS);
+
+ for (int i = 0; i < numberOfMessages / 2; i++) {
+ ClientMessage message = consumer.receive(5000);
+ assertNotNull(message);
+ assertEquals(i, message.getIntProperty("id").intValue());
+
+ if (i < 100) {
+ // Do not consume the last one so we could restart
+ message.acknowledge();
+ }
+ }
+
+ session.close();
+
+ sf.close();
+ sf = createSessionFactory(locator);
+
+ session = sf.createSession(true, true, 0);
+
+ session.start();
+
+ consumer = session.createConsumer(ADDRESS);
+
+ for (int i = 100; i < numberOfMessages; i++) {
+ ClientMessage message = consumer.receive(5000);
+ assertNotNull(message);
+ assertEquals(i, message.getIntProperty("id").intValue());
+ message.acknowledge();
+ }
+
+ session.close();
+ }
+
+ @Test
+ public void testPageCounter() throws Throwable {
+ boolean persistentMessages = true;
+
+ Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
+
+ ActiveMQServer server = createServer(true, config, PAGE_SIZE, PAGE_MAX, new HashMap<String, AddressSettings>());
+
+ server.start();
+
+ final int messageSize = 1024;
+
+ final int numberOfMessages = 500;
+
+ ServerLocator locator = createInVMNonHALocator().setClientFailureCheckPeriod(1000).setConnectionTTL(2000).setReconnectAttempts(0).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setConsumerWindowSize(1024 * 1024);
+
+ ClientSessionFactory sf = createSessionFactory(locator);
+
+ ClientSession session = sf.createSession(false, false, false);
+
+ Queue q1 = server.createQueue(ADDRESS, ADDRESS, null, true, false);
+
+ Queue q2 = server.createQueue(ADDRESS, new SimpleString("inactive"), null, true, false);
+
+ ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ byte[] body = new byte[messageSize];
+
+ ByteBuffer bb = ByteBuffer.wrap(body);
+
+ for (int j = 1; j <= messageSize; j++) {
+ bb.put(getSamplebyte(j));
+ }
+
+ final AtomicInteger errors = new AtomicInteger(0);
+
+ Thread t1 = new Thread() {
+ @Override
+ public void run() {
+ try {
+ ServerLocator sl = createInVMNonHALocator();
+ ClientSessionFactory sf = sl.createSessionFactory();
+ ClientSession sess = sf.createSession(true, true, 0);
+ sess.start();
+ ClientConsumer cons = sess.createConsumer(ADDRESS);
+ for (int i = 0; i < numberOfMessages; i++) {
+ ClientMessage msg = cons.receive(5000);
+ assertNotNull(msg);
+ assertEquals(i, msg.getIntProperty("id").intValue());
+ msg.acknowledge();
+ }
+
+ assertNull(cons.receiveImmediate());
+ sess.close();
+ sl.close();
+ }
+ catch (Throwable e) {
+ e.printStackTrace();
+ errors.incrementAndGet();
+ }
+
+ }
+ };
+
+ t1.start();
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ ClientMessage message = session.createMessage(persistentMessages);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ message.putIntProperty(new SimpleString("id"), i);
+
+ producer.send(message);
+ if (i % 20 == 0) {
+ session.commit();
+ }
+ }
+
+ session.commit();
+
+ t1.join();
+
+ assertEquals(0, errors.get());
+
+ assertEquals(numberOfMessages, getMessageCount(q2));
+ assertEquals(numberOfMessages, getMessagesAdded(q2));
+ assertEquals(0, getMessageCount(q1));
+ assertEquals(numberOfMessages, getMessagesAdded(q1));
+
+ session.close();
+ sf.close();
+ locator.close();
+
+ server.stop();
+
+ server.start();
+
+ Bindings bindings = server.getPostOffice().getBindingsForAddress(ADDRESS);
+
+ q1 = null;
+ q2 = null;
+
+ for (Binding bind : bindings.getBindings()) {
+ if (bind instanceof LocalQueueBinding) {
+ LocalQueueBinding qb = (LocalQueueBinding) bind;
+ if (qb.getQueue().getName().equals(ADDRESS)) {
+ q1 = qb.getQueue();
+ }
+
+ if (qb.getQueue().getName().equals(new SimpleString("inactive"))) {
+ q2 = qb.getQueue();
+ }
+ }
+ }
+
+ assertNotNull(q1);
+
+ assertNotNull(q2);
+
+ assertEquals("q2 msg count", numberOfMessages, getMessageCount(q2));
+ assertEquals("q2 msgs added", numberOfMessages, getMessagesAdded(q2));
+ assertEquals("q1 msg count", 0, getMessageCount(q1));
+ // 0, since nothing was sent to the queue after the server was restarted
+ assertEquals("q1 msgs added", 0, getMessagesAdded(q1));
+
+ }
+
+ @Test
+ public void testPageCounter2() throws Throwable {
+ boolean persistentMessages = true;
+
+ Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
+
+ ActiveMQServer server = createServer(true, config, PAGE_SIZE, PAGE_MAX, new HashMap<String, AddressSettings>());
+
+ server.start();
+
+ final int messageSize = 1024;
+
+ final int numberOfMessages = 500;
+
+ ServerLocator locator = createInVMNonHALocator().setClientFailureCheckPeriod(1000).setConnectionTTL(2000).setReconnectAttempts(0).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setConsumerWindowSize(1024 * 1024);
+
+ ClientSessionFactory sf = createSessionFactory(locator);
+
+ ClientSession session = sf.createSession(false, false, false);
+
+ Queue q1 = server.createQueue(ADDRESS, ADDRESS, null, true, false);
+
+ Queue q2 = server.createQueue(ADDRESS, new SimpleString("inactive"), null, true, false);
+
+ ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ byte[] body = new byte[messageSize];
+
+ ByteBuffer bb = ByteBuffer.wrap(body);
+
+ for (int j = 1; j <= messageSize; j++) {
+ bb.put(getSamplebyte(j));
+ }
+
+ final AtomicInteger errors = new AtomicInteger(0);
+
+ Thread t1 = new Thread() {
+ @Override
+ public void run() {
+ try {
+ ServerLocator sl = createInVMNonHALocator();
+ ClientSessionFactory sf = sl.createSessionFactory();
+ ClientSession sess = sf.createSession(true, true, 0);
+ sess.start();
+ ClientConsumer cons = sess.createConsumer(ADDRESS);
+ for (int i = 0; i < 100; i++) {
+ ClientMessage msg = cons.receive(5000);
+ assertNotNull(msg);
+ assertEquals(i, msg.getIntProperty("id").intValue());
+ msg.acknowledge();
+ }
+ sess.close();
+ sl.close();
+ }
+ catch (Throwable e) {
+ e.printStackTrace();
+ errors.incrementAndGet();
+ }
+
+ }
+ };
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ ClientMessage message = session.createMessage(persistentMessages);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ message.putIntProperty(new SimpleString("id"), i);
+
+ producer.send(message);
+ if (i % 20 == 0) {
+ session.commit();
+ }
+ }
+
+ session.commit();
+
+ t1.start();
+ t1.join();
+
+ assertEquals(0, errors.get());
+ long timeout = System.currentTimeMillis() + 10000;
+ while (numberOfMessages - 100 != getMessageCount(q1) && System.currentTimeMillis() < timeout) {
+ Thread.sleep(500);
+
+ }
+
+ assertEquals(numberOfMessages, getMessageCount(q2));
+ assertEquals(numberOfMessages, getMessagesAdded(q2));
+ assertEquals(numberOfMessages - 100, getMessageCount(q1));
+ }
+
+ @Test
+ public void testOrderOverRollback() throws Throwable {
+ boolean persistentMessages = true;
+
+ Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
+
+ ActiveMQServer server = createServer(true, config, PAGE_SIZE, PAGE_MAX, new HashMap<String, AddressSettings>());
+
+ server.start();
+
+ final int messageSize = 1024;
+
+ final int numberOfMessages = 3000;
+
+ ServerLocator locator = createInVMNonHALocator().setClientFailureCheckPeriod(1000).setConnectionTTL(2000).setReconnectAttempts(0).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setConsumerWindowSize(1024 * 1024);
+
+ ClientSessionFactory sf = createSessionFactory(locator);
+
+ ClientSession session = sf.createSession(false, false, false);
+
+ server.createQueue(ADDRESS, ADDRESS, null, true, false);
+
+ ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ byte[] body = new byte[messageSize];
+
+ ByteBuffer bb = ByteBuffer.wrap(body);
+
+ for (int j = 1; j <= messageSize; j++) {
+ bb.put(getSamplebyte(j));
+ }
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ ClientMessage message = session.createMessage(persistentMessages);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ message.putIntProperty(new SimpleString("id"), i);
+
+ producer.send(message);
+ if (i % 1000 == 0) {
+ session.commit();
+ }
+ }
+
+ session.commit();
+
+ session.close();
+
+ session = sf.createSession(false, false, 0);
+
+ session.start();
+
+ ClientConsumer consumer = session.createConsumer(ADDRESS);
+
+ for (int i = 0; i < numberOfMessages / 2; i++) {
+ ClientMessage message = consumer.receive(5000);
+ assertNotNull(message);
+ assertEquals(i, message.getIntProperty("id").intValue());
+ message.acknowledge();
+ }
+
+ session.rollback();
+
+ session.close();
+
+ session = sf.createSession(false, false, 0);
+
+ session.start();
+
+ consumer = session.createConsumer(ADDRESS);
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ ClientMessage message = consumer.receive(5000);
+ assertNotNull(message);
+ assertEquals(i, message.getIntProperty("id").intValue());
+ message.acknowledge();
+ }
+
+ session.commit();
+ }
+
+ @Test
+ public void testOrderOverRollback2() throws Throwable {
+ boolean persistentMessages = true;
+
+ Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
+
+ ActiveMQServer server = createServer(true, config, PAGE_SIZE, PAGE_MAX, new HashMap<String, AddressSettings>());
+
+ server.start();
+
+ final int messageSize = 1024;
+
+ final int numberOfMessages = 200;
+
+ ServerLocator locator = createInVMNonHALocator().setClientFailureCheckPeriod(1000).setConnectionTTL(2000).setReconnectAttempts(0).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setConsumerWindowSize(0);
+
+ ClientSessionFactory sf = createSessionFactory(locator);
+
+ ClientSession session = sf.createSession(false, false, false);
+
+ QueueImpl queue = (QueueImpl) server.createQueue(ADDRESS, ADDRESS, null, true, false);
+
+ ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ byte[] body = new byte[messageSize];
+
+ ByteBuffer bb = ByteBuffer.wrap(body);
+
+ for (int j = 1; j <= messageSize; j++) {
+ bb.put(getSamplebyte(j));
+ }
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ ClientMessage message = session.createMessage(persistentMessages);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ message.putIntProperty(new SimpleString("id"), i);
+
+ producer.send(message);
+ if (i % 1000 == 0) {
+ session.commit();
+ }
+ }
+
+ session.commit();
+
+ session.close();
+
+ session = sf.createSession(false, false, 0);
+
+ session.start();
+
+ ClientConsumer consumer = session.createConsumer(ADDRESS);
+
+ // number of references without paging
+ int numberOfRefs = queue.getNumberOfReferences();
+
+ // consume all non-paged references
+ for (int ref = 0; ref < numberOfRefs; ref++) {
+ ClientMessage msg = consumer.receive(5000);
+ assertNotNull(msg);
+ msg.acknowledge();
+ }
+
+ session.commit();
+
+ session.close();
+
+ session = sf.createSession(false, false, 0);
+
+ session.start();
+
+ consumer = session.createConsumer(ADDRESS);
+
+ ClientMessage msg = consumer.receive(5000);
+ assertNotNull(msg);
+ int msgIDRolledBack = msg.getIntProperty("id").intValue();
+ msg.acknowledge();
+
+ session.rollback();
+
+ msg = consumer.receive(5000);
+
+ assertNotNull(msg);
+
+ assertEquals(msgIDRolledBack, msg.getIntProperty("id").intValue());
+
+ session.rollback();
+
+ session.close();
+
+ sf.close();
+ locator.close();
+
+ server.stop();
+
+ server.start();
+
+ locator = createInVMNonHALocator().setClientFailureCheckPeriod(1000).setConnectionTTL(2000).setReconnectAttempts(0).setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true).setConsumerWindowSize(0);
+
+ sf = createSessionFactory(locator);
+
+ session = sf.createSession(false, false, 0);
+
+ session.start();
+
+ consumer = session.createConsumer(ADDRESS);
+
+ for (int i = msgIDRolledBack; i < numberOfMessages; i++) {
+ ClientMessage message = consumer.receive(5000);
+ assertNotNull(message);
+ assertEquals(i, message.getIntProperty("id").intValue());
+ message.acknowledge();
+ }
+
+ session.commit();
+
+ session.close();
+ }
+
+ @Test
+ public void testPagingOverCreatedDestinationTopics() throws Exception {
+
+ Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
+
+ ActiveMQServer server = createServer(true, config, PAGE_SIZE, -1, new HashMap<String, AddressSettings>());
+
+ JMSServerManagerImpl jmsServer = new JMSServerManagerImpl(server);
+ InVMNamingContext context = new InVMNamingContext();
+ jmsServer.setRegistry(new JndiBindingRegistry(context));
+ jmsServer.start();
+
+ jmsServer.createTopic(true, "tt", "/topic/TT");
+
+ server.getActiveMQServerControl().addAddressSettings("jms.topic.TT", "DLQ", "DLQ", -1, false, 5, 1024 * 1024, 1024 * 10, 5, 5, 1, 1000, 0, false, "PAGE", -1, 10, "KILL", true, true, true, true);
+
+ ActiveMQJMSConnectionFactory cf = (ActiveMQJMSConnectionFactory) ActiveMQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, new TransportConfiguration(INVM_CONNECTOR_FACTORY));
+
+ Connection conn = cf.createConnection();
+ conn.setClientID("tst");
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Topic topic = (Topic) context.lookup("/topic/TT");
+ sess.createDurableSubscriber(topic, "t1");
+
+ MessageProducer prod = sess.createProducer(topic);
+ prod.setDeliveryMode(DeliveryMode.PERSISTENT);
+ TextMessage txt = sess.createTextMessage("TST");
+ prod.send(txt);
+
+ PagingStore store = server.getPagingManager().getPageStore(new SimpleString("jms.topic.TT"));
+
+ assertEquals(1024 * 1024, store.getMaxSize());
+ assertEquals(10 * 1024, store.getPageSizeBytes());
+
+ jmsServer.stop();
+
+ server = createServer(true, config, PAGE_SIZE, -1, new HashMap<String, AddressSettings>());
+
+ jmsServer = new JMSServerManagerImpl(server);
+ context = new InVMNamingContext();
+ jmsServer.setRegistry(new JndiBindingRegistry(context));
+ jmsServer.start();
+
+ AddressSettings settings = server.getAddressSettingsRepository().getMatch("jms.topic.TT");
+
+ assertEquals(1024 * 1024, settings.getMaxSizeBytes());
+ assertEquals(10 * 1024, settings.getPageSizeBytes());
+ assertEquals(AddressFullMessagePolicy.PAGE, settings.getAddressFullMessagePolicy());
+
+ store = server.getPagingManager().getPageStore(new SimpleString("TT"));
+
+ conn.close();
+
+ server.stop();
+
+ }
+
+ @Test
+ public void testPagingOverCreatedDestinationQueues() throws Exception {
+
+ Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
+
+ ActiveMQServer server = createServer(true, config, -1, -1, new HashMap<String, AddressSettings>());
+ server.getAddressSettingsRepository().getMatch("#").setAddressFullMessagePolicy(AddressFullMessagePolicy.BLOCK);
+
+ JMSServerManagerImpl jmsServer = new JMSServerManagerImpl(server);
+ InVMNamingContext context = new InVMNamingContext();
+ jmsServer.setRegistry(new JndiBindingRegistry(context));
+ jmsServer.start();
+
+ server.getActiveMQServerControl().addAddressSettings("jms.queue.Q1", "DLQ", "DLQ", -1, false, 5, 100 * 1024, 10 * 1024, 5, 5, 1, 1000, 0, false, "PAGE", -1, 10, "KILL", true, true, true, true);
+
+ jmsServer.createQueue(true, "Q1", null, true, "/queue/Q1");
+
+ ActiveMQJMSConnectionFactory cf = (ActiveMQJMSConnectionFactory) ActiveMQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, new TransportConfiguration(INVM_CONNECTOR_FACTORY));
+
+ conn = cf.createConnection();
+ conn.setClientID("tst");
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ javax.jms.Queue queue = (javax.jms.Queue) context.lookup("/queue/Q1");
+
+ MessageProducer prod = sess.createProducer(queue);
+ prod.setDeliveryMode(DeliveryMode.PERSISTENT);
+ BytesMessage bmt = sess.createBytesMessage();
+
+ bmt.writeBytes(new byte[1024]);
+
+ for (int i = 0; i < 500; i++) {
+ prod.send(bmt);
+ }
+
+ PagingStore store = server.getPagingManager().getPageStore(new SimpleString("jms.queue.Q1"));
+
+ assertEquals(100 * 1024, store.getMaxSize());
+ assertEquals(10 * 1024, store.getPageSizeBytes());
+ assertEquals(AddressFullMessagePolicy.PAGE, store.getAddressFullMessagePolicy());
+
+ jmsServer.stop();
+
+ server = createServer(true, config, -1, -1, new HashMap<String, AddressSettings>());
+ server.getAddressSettingsRepository().getMatch("#").setAddressFullMessagePolicy(AddressFullMessagePolicy.BLOCK);
+
+ jmsServer = new JMSServerManagerImpl(server);
+ context = new InVMNamingContext();
+ jmsServer.setRegistry(new JndiBindingRegistry(context));
+ jmsServer.start();
+
+ AddressSettings settings = server.getAddressSettingsRepository().getMatch("jms.queue.Q1");
+
+ assertEquals(100 * 1024, settings.getMaxSizeBytes());
+ assertEquals(10 * 1024, settings.getPageSizeBytes());
+ assertEquals(AddressFullMessagePolicy.PAGE, settings.getAddressFullMessagePolicy());
+
+ store = server.getPagingManager().getPageStore(new SimpleString("jms.queue.Q1"));
+ assertEquals(100 * 1024, store.getMaxSize());
+ assertEquals(10 * 1024, store.getPageSizeBytes());
+ assertEquals(AddressFullMessagePolicy.PAGE, store.getAddressFullMessagePolicy());
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/paging/PagingSyncTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/paging/PagingSyncTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/paging/PagingSyncTest.java
new file mode 100644
index 0000000..bb94634
--- /dev/null
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/paging/PagingSyncTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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.artemis.tests.integration.paging;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+
+import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
+import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.api.core.client.ClientMessage;
+import org.apache.activemq.artemis.api.core.client.ClientProducer;
+import org.apache.activemq.artemis.api.core.client.ClientSession;
+import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
+import org.apache.activemq.artemis.api.core.client.ServerLocator;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
+import org.apache.activemq.artemis.core.config.Configuration;
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
+import org.junit.Test;
+
+/**
+ * A PagingOrderTest.
+ * <br>
+ * PagingTest has a lot of tests already. I decided to create a newer one more specialized on Ordering and counters
+ */
+public class PagingSyncTest extends ActiveMQTestBase {
+
+ private static final int PAGE_MAX = 100 * 1024;
+
+ private static final int PAGE_SIZE = 10 * 1024;
+
+ // Attributes ----------------------------------------------------
+
+ // Static --------------------------------------------------------
+
+ static final SimpleString ADDRESS = new SimpleString("SimpleAddress");
+
+ @Test
+ public void testOrder1() throws Throwable {
+ boolean persistentMessages = true;
+
+ Configuration config = createDefaultInVMConfig().setJournalSyncNonTransactional(false);
+
+ ActiveMQServer server = createServer(true, config, PAGE_SIZE, PAGE_MAX, new HashMap<String, AddressSettings>());
+
+ server.start();
+
+ final int messageSize = 1024;
+
+ final int numberOfMessages = 500;
+
+ ServerLocator locator = createInVMNonHALocator().setClientFailureCheckPeriod(1000).setConnectionTTL(2000).setReconnectAttempts(0).setBlockOnNonDurableSend(false).setBlockOnDurableSend(false).setBlockOnAcknowledge(false).setConsumerWindowSize(1024 * 1024);
+
+ ClientSessionFactory sf = createSessionFactory(locator);
+
+ ClientSession session = sf.createSession(false, false, false);
+
+ server.createQueue(ADDRESS, ADDRESS, null, true, false);
+
+ ClientProducer producer = session.createProducer(PagingTest.ADDRESS);
+
+ byte[] body = new byte[messageSize];
+
+ ByteBuffer bb = ByteBuffer.wrap(body);
+
+ for (int j = 1; j <= messageSize; j++) {
+ bb.put(getSamplebyte(j));
+ }
+
+ for (int i = 0; i < numberOfMessages; i++) {
+ ClientMessage message = session.createMessage(persistentMessages);
+
+ ActiveMQBuffer bodyLocal = message.getBodyBuffer();
+
+ bodyLocal.writeBytes(body);
+
+ message.putIntProperty(new SimpleString("id"), i);
+
+ producer.send(message);
+ }
+
+ session.commit();
+
+ session.close();
+ }
+
+ // Package protected ---------------------------------------------
+
+ // Protected -----------------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ // Inner classes -------------------------------------------------
+
+}
[2/7] activemq-artemis git commit: ARTEMIS-581 Implement max disk
usage, and global-max-size
Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/AddressFullLoggingTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/AddressFullLoggingTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/AddressFullLoggingTest.java
deleted file mode 100644
index f315b89..0000000
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/AddressFullLoggingTest.java
+++ /dev/null
@@ -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.artemis.tests.integration.server;
-
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import org.apache.activemq.artemis.api.core.ActiveMQException;
-import org.apache.activemq.artemis.api.core.client.ClientConsumer;
-import org.apache.activemq.artemis.api.core.client.ClientMessage;
-import org.apache.activemq.artemis.api.core.client.ClientProducer;
-import org.apache.activemq.artemis.api.core.client.ClientSession;
-import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
-import org.apache.activemq.artemis.api.core.client.ServerLocator;
-import org.apache.activemq.artemis.core.server.ActiveMQServer;
-import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy;
-import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
-import org.apache.activemq.artemis.logs.AssertionLoggerHandler;
-import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
-import org.junit.AfterClass;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-public class AddressFullLoggingTest extends ActiveMQTestBase {
-
- @BeforeClass
- public static void prepareLogger() {
- AssertionLoggerHandler.startCapture();
- }
-
- @Test
- /**
- * When running this test from an IDE add this to the test command line so that the AssertionLoggerHandler works properly:
- *
- * -Djava.util.logging.manager=org.jboss.logmanager.LogManager -Dlogging.configuration=file:<path_to_source>/tests/config/logging.properties
- */ public void testBlockLogging() throws Exception {
- final int MAX_MESSAGES = 200;
- final String MY_ADDRESS = "myAddress";
- final String MY_QUEUE = "myQueue";
-
- ActiveMQServer server = createServer(false);
-
- AddressSettings defaultSetting = new AddressSettings().setPageSizeBytes(10 * 1024).setMaxSizeBytes(20 * 1024).setAddressFullMessagePolicy(AddressFullMessagePolicy.BLOCK);
- server.getAddressSettingsRepository().addMatch("#", defaultSetting);
- server.start();
-
- ServerLocator locator = createInVMNonHALocator().setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setBlockOnAcknowledge(true);
-
- ClientSessionFactory factory = createSessionFactory(locator);
- ClientSession session = factory.createSession(false, true, true);
-
- session.createQueue(MY_ADDRESS, MY_QUEUE, true);
-
- final ClientProducer producer = session.createProducer(MY_ADDRESS);
-
- final ClientMessage message = session.createMessage(false);
- message.getBodyBuffer().writeBytes(new byte[1024]);
-
- ExecutorService executor = Executors.newFixedThreadPool(1, ActiveMQThreadFactory.defaultThreadFactory());
- Callable<Object> sendMessageTask = new Callable<Object>() {
- @Override
- public Object call() throws ActiveMQException {
- producer.send(message);
- return null;
- }
- };
-
- int sendCount = 0;
-
- for (int i = 0; i < MAX_MESSAGES; i++) {
- Future<Object> future = executor.submit(sendMessageTask);
- try {
- future.get(3, TimeUnit.SECONDS);
- sendCount++;
- }
- catch (TimeoutException ex) {
- // message sending has been blocked
- break;
- }
- finally {
- future.cancel(true); // may or may not desire this
- }
- }
-
- executor.shutdown();
- session.close();
-
- session = factory.createSession(false, true, true);
- session.start();
- ClientConsumer consumer = session.createConsumer(MY_QUEUE);
- for (int i = 0; i < sendCount; i++) {
- ClientMessage msg = consumer.receive(250);
- if (msg == null)
- break;
- msg.acknowledge();
- }
-
- session.close();
- locator.close();
- server.stop();
-
- // Using the code only so the test doesn't fail just because someone edits the log text
- Assert.assertTrue("Expected to find AMQ222183", AssertionLoggerHandler.findText("AMQ222183", "myAddress"));
- Assert.assertTrue("Expected to find AMQ221046", AssertionLoggerHandler.findText("AMQ221046", "myAddress"));
- }
-
- @AfterClass
- public static void clearLogger() {
- AssertionLoggerHandler.stopCapture();
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/stomp/StompTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/stomp/StompTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/stomp/StompTest.java
index 1c4adc5..9e25c18 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/stomp/StompTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/stomp/StompTest.java
@@ -40,6 +40,8 @@ import org.apache.activemq.artemis.api.core.client.ServerLocator;
import org.apache.activemq.artemis.api.core.management.ResourceNames;
import org.apache.activemq.artemis.api.jms.ActiveMQJMSClient;
import org.apache.activemq.artemis.core.protocol.stomp.Stomp;
+import org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl;
+import org.apache.activemq.artemis.logs.AssertionLoggerHandler;
import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger;
import org.apache.activemq.artemis.tests.integration.mqtt.imported.FuseMQTTClientProvider;
import org.apache.activemq.artemis.tests.integration.mqtt.imported.MQTTClientProvider;
@@ -101,6 +103,46 @@ public class StompTest extends StompTestBase {
}
@Test
+ public void testSendOverDiskFull() throws Exception {
+ AssertionLoggerHandler.startCapture();
+ try {
+ MessageConsumer consumer = session.createConsumer(queue);
+
+ String frame = "CONNECT\n" + "login: brianm\n" + "passcode: wombats\n\n" + Stomp.NULL;
+ sendFrame(frame);
+ frame = receiveFrame(10000);
+
+ Assert.assertTrue(frame.startsWith("CONNECTED"));
+ int count = 1000;
+ final CountDownLatch latch = new CountDownLatch(count);
+ consumer.setMessageListener(new MessageListener() {
+
+ @Override
+ public void onMessage(Message arg0) {
+ latch.countDown();
+ }
+ });
+
+ ((ActiveMQServerImpl) server.getActiveMQServer()).getMonitor().setMaxUsage(0).tick();
+
+ frame = "SEND\n" + "destination:" + getQueuePrefix() + getQueueName() + "\n\n" + "Hello World" + Stomp.NULL;
+ for (int i = 1; i <= count; i++) {
+ // Thread.sleep(1);
+ // System.out.println(">>> " + i);
+ sendFrame(frame);
+ }
+
+ // It should encounter the exception on logs
+ AssertionLoggerHandler.findText("AMQ119119");
+ }
+ finally {
+ AssertionLoggerHandler.clear();
+ AssertionLoggerHandler.stopCapture();
+ }
+
+ }
+
+ @Test
public void testConnect() throws Exception {
String connect_frame = "CONNECT\n" + "login: brianm\n" +
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/stomp/StompTestBase.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/stomp/StompTestBase.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/stomp/StompTestBase.java
index 7f73e48..2e93b83 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/stomp/StompTestBase.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/stomp/StompTestBase.java
@@ -205,7 +205,7 @@ public abstract class StompTestBase extends ActiveMQTestBase {
TransportConfiguration stompTransport = new TransportConfiguration(NettyAcceptorFactory.class.getName(), params);
TransportConfiguration allTransport = new TransportConfiguration(NettyAcceptorFactory.class.getName());
- Configuration config = createBasicConfig().setSecurityEnabled(isSecurityEnabled()).setPersistenceEnabled(false).addAcceptorConfiguration(stompTransport).addAcceptorConfiguration(new TransportConfiguration(InVMAcceptorFactory.class.getName()));
+ Configuration config = createBasicConfig().setSecurityEnabled(isSecurityEnabled()).setPersistenceEnabled(true).addAcceptorConfiguration(stompTransport).addAcceptorConfiguration(new TransportConfiguration(InVMAcceptorFactory.class.getName()));
config.addAcceptorConfiguration(allTransport);
ActiveMQServer activeMQServer = addServer(ActiveMQServers.newActiveMQServer(config, defUser, defPass));
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/storage/PersistMultiThreadTest.java
----------------------------------------------------------------------
diff --git a/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/storage/PersistMultiThreadTest.java b/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/storage/PersistMultiThreadTest.java
index 6c42413..b70d432 100644
--- a/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/storage/PersistMultiThreadTest.java
+++ b/tests/performance-tests/src/test/java/org/apache/activemq/artemis/tests/performance/storage/PersistMultiThreadTest.java
@@ -448,5 +448,10 @@ public class PersistMultiThreadTest extends ActiveMQTestBase {
public boolean isStarted() {
return false;
}
+
+ @Override
+ public boolean checkReleasedMemory() {
+ return true;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PagingStoreImplTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PagingStoreImplTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PagingStoreImplTest.java
index 97520f3..9731277 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PagingStoreImplTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/paging/impl/PagingStoreImplTest.java
@@ -50,6 +50,7 @@ import org.apache.activemq.artemis.core.paging.impl.PagingStoreImpl;
import org.apache.activemq.artemis.core.persistence.StorageManager;
import org.apache.activemq.artemis.core.persistence.impl.nullpm.NullStorageManager;
import org.apache.activemq.artemis.core.server.ServerMessage;
+import org.apache.activemq.artemis.core.server.files.FileStoreMonitor;
import org.apache.activemq.artemis.core.server.impl.RoutingContextImpl;
import org.apache.activemq.artemis.core.server.impl.ServerMessageImpl;
import org.apache.activemq.artemis.core.settings.HierarchicalRepository;
@@ -826,6 +827,11 @@ public class PagingStoreImplTest extends ActiveMQTestBase {
public void stop() throws InterruptedException {
}
+ @Override
+ public void injectMonitor(FileStoreMonitor monitor) throws Exception {
+
+ }
+
public void beforePageRead() throws Exception {
}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/4472aa0e/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/util/FakePagingManager.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/util/FakePagingManager.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/util/FakePagingManager.java
index 9faf307..bbaa3a3 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/util/FakePagingManager.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/util/FakePagingManager.java
@@ -23,39 +23,25 @@ import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.core.paging.PageTransactionInfo;
import org.apache.activemq.artemis.core.paging.PagingManager;
import org.apache.activemq.artemis.core.paging.PagingStore;
-import org.apache.activemq.artemis.core.postoffice.PostOffice;
import org.apache.activemq.artemis.core.server.ServerMessage;
+import org.apache.activemq.artemis.core.server.files.FileStoreMonitor;
public final class FakePagingManager implements PagingManager {
- public void activate() {
- }
+ @Override
+ public void addBlockedStore(PagingStore store) {
- public long addSize(final long size) {
- return 0;
}
@Override
public void addTransaction(final PageTransactionInfo pageTransaction) {
}
- public PagingStore createPageStore(final SimpleString destination) throws Exception {
- return null;
- }
-
- public long getTotalMemory() {
- return 0;
- }
-
@Override
public SimpleString[] getStoreNames() {
return null;
}
- public long getMaxMemory() {
- return 0;
- }
-
@Override
public PagingStore getPageStore(final SimpleString address) throws Exception {
return null;
@@ -74,10 +60,6 @@ public final class FakePagingManager implements PagingManager {
return false;
}
- public boolean isGlobalPageMode() {
- return false;
- }
-
public boolean isPaging(final SimpleString destination) throws Exception {
return false;
}
@@ -93,21 +75,22 @@ public final class FakePagingManager implements PagingManager {
}
@Override
- public void reloadStores() throws Exception {
+ public FakePagingManager addSize(int size) {
+ return this;
}
@Override
- public void removeTransaction(final long transactionID) {
-
+ public void reloadStores() throws Exception {
}
- public void setGlobalPageMode(final boolean globalMode) {
- }
+ @Override
+ public void removeTransaction(final long transactionID) {
- public void setPostOffice(final PostOffice postOffice) {
}
- public void resumeDepages() {
+ @Override
+ public boolean isUsingGlobalSize() {
+ return false;
}
public void sync(final Collection<SimpleString> destinationsToSync) throws Exception {
@@ -126,10 +109,15 @@ public final class FakePagingManager implements PagingManager {
public void stop() throws Exception {
}
+ @Override
+ public boolean isDiskFull() {
+ return false;
+ }
+
/*
- * (non-Javadoc)
- * @see org.apache.activemq.artemis.core.paging.PagingManager#isGlobalFull()
- */
+ * (non-Javadoc)
+ * @see org.apache.activemq.artemis.core.paging.PagingManager#isGlobalFull()
+ */
public boolean isGlobalFull() {
return false;
}
@@ -177,4 +165,8 @@ public final class FakePagingManager implements PagingManager {
// no-op
}
+ @Override
+ public void injectMonitor(FileStoreMonitor monitor) throws Exception {
+
+ }
}