You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ha...@apache.org on 2014/12/25 05:02:23 UTC
[1/5] activemq git commit: Revert
"https://issues.apache.org/jira/browse/AMQ-3758"
Repository: activemq
Updated Branches:
refs/heads/activemq-5.10.x 76357bdb1 -> 3424e04fa
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/legacy/LegacyStoreReplayer.java
----------------------------------------------------------------------
diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/legacy/LegacyStoreReplayer.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/legacy/LegacyStoreReplayer.java
deleted file mode 100644
index 92563f4..0000000
--- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/legacy/LegacyStoreReplayer.java
+++ /dev/null
@@ -1,155 +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.store.kahadb.scheduler.legacy;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.activemq.store.kahadb.data.KahaAddScheduledJobCommand;
-import org.apache.activemq.store.kahadb.scheduler.JobSchedulerStoreImpl;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Used to upgrade a Legacy Job Scheduler store to the latest version this class
- * loads a found legacy scheduler store and generates new add commands for all
- * jobs currently in the store.
- */
-public class LegacyStoreReplayer {
-
- static final Logger LOG = LoggerFactory.getLogger(LegacyStoreReplayer.class);
-
- private LegacyJobSchedulerStoreImpl store;
- private final File legacyStoreDirectory;
-
- /**
- * Creates a new Legacy Store Replayer with the given target store
- * @param targetStore
- * @param directory
- */
- public LegacyStoreReplayer(File directory) {
- this.legacyStoreDirectory = directory;
- }
-
- /**
- * Loads the legacy store and prepares it for replay into a newer Store instance.
- *
- * @throws IOException if an error occurs while reading in the legacy store.
- */
- public void load() throws IOException {
-
- store = new LegacyJobSchedulerStoreImpl();
- store.setDirectory(legacyStoreDirectory);
- store.setFailIfDatabaseIsLocked(true);
-
- try {
- store.start();
- } catch (IOException ioe) {
- LOG.warn("Legacy store load failed: ", ioe);
- throw ioe;
- } catch (Exception e) {
- LOG.warn("Legacy store load failed: ", e);
- throw new IOException(e);
- }
- }
-
- /**
- * Unloads a previously loaded legacy store to release any resources associated with it.
- *
- * Once a store is unloaded it cannot be replayed again until it has been reloaded.
- * @throws IOException
- */
- public void unload() throws IOException {
-
- if (store != null) {
- try {
- store.stop();
- } catch (Exception e) {
- LOG.warn("Legacy store unload failed: ", e);
- throw new IOException(e);
- } finally {
- store = null;
- }
- }
- }
-
- /**
- * Performs a replay of scheduled jobs into the target JobSchedulerStore.
- *
- * @param targetStore
- * The JobSchedulerStore that will receive the replay events from the legacy store.
- *
- * @throws IOException if an error occurs during replay of the legacy store.
- */
- public void startReplay(JobSchedulerStoreImpl targetStore) throws IOException {
- checkLoaded();
-
- if (targetStore == null) {
- throw new IOException("Cannot replay to a null store");
- }
-
- try {
- Set<String> schedulers = store.getJobSchedulerNames();
- if (!schedulers.isEmpty()) {
-
- for (String name : schedulers) {
- LegacyJobSchedulerImpl scheduler = store.getJobScheduler(name);
- LOG.info("Replay of legacy store {} starting.", name);
- replayScheduler(scheduler, targetStore);
- }
- }
-
- LOG.info("Replay of legacy store complate.");
- } catch (IOException ioe) {
- LOG.warn("Failed during replay of legacy store: ", ioe);
- throw ioe;
- } catch (Exception e) {
- LOG.warn("Failed during replay of legacy store: ", e);
- throw new IOException(e);
- }
- }
-
- private final void replayScheduler(LegacyJobSchedulerImpl legacy, JobSchedulerStoreImpl target) throws Exception {
- List<LegacyJobImpl> jobs = legacy.getAllJobs();
-
- String schedulerName = legacy.getName();
-
- for (LegacyJobImpl job : jobs) {
- LOG.trace("Storing job from legacy store to new store: {}", job);
- KahaAddScheduledJobCommand newJob = new KahaAddScheduledJobCommand();
- newJob.setScheduler(schedulerName);
- newJob.setJobId(job.getJobId());
- newJob.setStartTime(job.getStartTime());
- newJob.setCronEntry(job.getCronEntry());
- newJob.setDelay(job.getDelay());
- newJob.setPeriod(job.getPeriod());
- newJob.setRepeat(job.getRepeat());
- newJob.setNextExecutionTime(job.getNextExecutionTime());
- newJob.setPayload(job.getPayload());
-
- target.store(newJob);
- }
- }
-
- private final void checkLoaded() throws IOException {
- if (this.store == null) {
- throw new IOException("Cannot replay until legacy store is loaded.");
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-kahadb-store/src/main/proto/journal-data.proto
----------------------------------------------------------------------
diff --git a/activemq-kahadb-store/src/main/proto/journal-data.proto b/activemq-kahadb-store/src/main/proto/journal-data.proto
index 01607a5..8290c4c 100644
--- a/activemq-kahadb-store/src/main/proto/journal-data.proto
+++ b/activemq-kahadb-store/src/main/proto/journal-data.proto
@@ -32,11 +32,6 @@ enum KahaEntryType {
KAHA_PRODUCER_AUDIT_COMMAND = 8;
KAHA_ACK_MESSAGE_FILE_MAP_COMMAND = 9;
KAHA_UPDATE_MESSAGE_COMMAND = 10;
- KAHA_ADD_SCHEDULED_JOB_COMMAND = 11;
- KAHA_RESCHEDULE_JOB_COMMAND = 12;
- KAHA_REMOVE_SCHEDULED_JOB_COMMAND = 13;
- KAHA_REMOVE_SCHEDULED_JOBS_COMMAND = 14;
- KAHA_DESTROY_SCHEDULER_COMMAND = 15;
}
message KahaTraceCommand {
@@ -184,62 +179,6 @@ message KahaLocation {
required int32 offset = 2;
}
-message KahaAddScheduledJobCommand {
- //| option java_implments = "org.apache.activemq.store.kahadb.JournalCommand<KahaAddScheduledJobCommand>";
- //| option java_visitor = "org.apache.activemq.store.kahadb.Visitor:void:java.io.IOException";
- //| option java_type_method = "KahaEntryType";
-
- required string scheduler=1;
- required string job_id=2;
- required int64 start_time=3;
- required string cron_entry=4;
- required int64 delay=5;
- required int64 period=6;
- required int32 repeat=7;
- required bytes payload=8;
- required int64 next_execution_time=9;
-}
-
-message KahaRescheduleJobCommand {
- //| option java_implments = "org.apache.activemq.store.kahadb.JournalCommand<KahaRescheduleJobCommand>";
- //| option java_visitor = "org.apache.activemq.store.kahadb.Visitor:void:java.io.IOException";
- //| option java_type_method = "KahaEntryType";
-
- required string scheduler=1;
- required string job_id=2;
- required int64 execution_time=3;
- required int64 next_execution_time=4;
- required int32 rescheduled_count=5;
-}
-
-message KahaRemoveScheduledJobCommand {
- //| option java_implments = "org.apache.activemq.store.kahadb.JournalCommand<KahaRemoveScheduledJobCommand>";
- //| option java_visitor = "org.apache.activemq.store.kahadb.Visitor:void:java.io.IOException";
- //| option java_type_method = "KahaEntryType";
-
- required string scheduler=1;
- required string job_id=2;
- required int64 next_execution_time=3;
-}
-
-message KahaRemoveScheduledJobsCommand {
- //| option java_implments = "org.apache.activemq.store.kahadb.JournalCommand<KahaRemoveScheduledJobsCommand>";
- //| option java_visitor = "org.apache.activemq.store.kahadb.Visitor:void:java.io.IOException";
- //| option java_type_method = "KahaEntryType";
-
- required string scheduler=1;
- required int64 start_time=2;
- required int64 end_time=3;
-}
-
-message KahaDestroySchedulerCommand {
- //| option java_implments = "org.apache.activemq.store.kahadb.JournalCommand<KahaDestroySchedulerCommand>";
- //| option java_visitor = "org.apache.activemq.store.kahadb.Visitor:void:java.io.IOException";
- //| option java_type_method = "KahaEntryType";
-
- required string scheduler=1;
-}
-
// TODO things to ponder
// should we move more message fields
// that are set by the sender (and rarely required by the broker
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-leveldb-store/src/main/scala/org/apache/activemq/leveldb/LevelDBStore.scala
----------------------------------------------------------------------
diff --git a/activemq-leveldb-store/src/main/scala/org/apache/activemq/leveldb/LevelDBStore.scala b/activemq-leveldb-store/src/main/scala/org/apache/activemq/leveldb/LevelDBStore.scala
index 01d5170..42b25c6 100644
--- a/activemq-leveldb-store/src/main/scala/org/apache/activemq/leveldb/LevelDBStore.scala
+++ b/activemq-leveldb-store/src/main/scala/org/apache/activemq/leveldb/LevelDBStore.scala
@@ -35,7 +35,6 @@ import org.apache.activemq.leveldb.util.Log
import org.apache.activemq.store.PList.PListIterator
import org.fusesource.hawtbuf.{UTF8Buffer, DataByteArrayOutputStream}
import org.fusesource.hawtdispatch;
-import org.apache.activemq.broker.scheduler.JobSchedulerStore;
object LevelDBStore extends Log {
val DEFAULT_DIRECTORY = new File("LevelDB");
@@ -605,10 +604,6 @@ class LevelDBStore extends LockableServiceSupport with BrokerServiceAware with P
rc
}
- def createJobSchedulerStore():JobSchedulerStore = {
- throw new UnsupportedOperationException();
- }
-
def removeTopicMessageStore(destination: ActiveMQTopic): Unit = {
topics.remove(destination).foreach { store=>
store.subscriptions.values.foreach { sub =>
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-leveldb-store/src/main/scala/org/apache/activemq/leveldb/replicated/ProxyLevelDBStore.scala
----------------------------------------------------------------------
diff --git a/activemq-leveldb-store/src/main/scala/org/apache/activemq/leveldb/replicated/ProxyLevelDBStore.scala b/activemq-leveldb-store/src/main/scala/org/apache/activemq/leveldb/replicated/ProxyLevelDBStore.scala
index efd55f3..bd3904f 100644
--- a/activemq-leveldb-store/src/main/scala/org/apache/activemq/leveldb/replicated/ProxyLevelDBStore.scala
+++ b/activemq-leveldb-store/src/main/scala/org/apache/activemq/leveldb/replicated/ProxyLevelDBStore.scala
@@ -25,7 +25,6 @@ import java.io.File
import java.io.IOException
import java.util.Set
import org.apache.activemq.util.{ServiceStopper, ServiceSupport}
-import org.apache.activemq.broker.scheduler.JobSchedulerStore
/**
*/
@@ -45,10 +44,6 @@ abstract class ProxyLevelDBStore extends LockableServiceSupport with BrokerServi
return proxy_target.createTopicMessageStore(destination)
}
- def createJobSchedulerStore():JobSchedulerStore = {
- return proxy_target.createJobSchedulerStore()
- }
-
def setDirectory(dir: File) {
proxy_target.setDirectory(dir)
}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerBrokerShutdownTest.java
----------------------------------------------------------------------
diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerBrokerShutdownTest.java b/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerBrokerShutdownTest.java
index 641ee97..04277bf 100644
--- a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerBrokerShutdownTest.java
+++ b/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerBrokerShutdownTest.java
@@ -39,7 +39,6 @@ public class JobSchedulerBrokerShutdownTest extends EmbeddedBrokerTestSupport {
BrokerService broker = super.createBroker();
broker.setSchedulerSupport(true);
- broker.setDataDirectory("target");
broker.setSchedulerDirectoryFile(schedulerDirectory);
broker.getSystemUsage().getStoreUsage().setLimit(1 * 512);
broker.deleteAllMessages();
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerJmxManagementTests.java
----------------------------------------------------------------------
diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerJmxManagementTests.java b/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerJmxManagementTests.java
deleted file mode 100644
index 8adb980..0000000
--- a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerJmxManagementTests.java
+++ /dev/null
@@ -1,155 +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.broker.scheduler;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.List;
-
-import javax.jms.Connection;
-import javax.jms.MessageProducer;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-import javax.management.openmbean.TabularData;
-
-import org.apache.activemq.ScheduledMessage;
-import org.apache.activemq.broker.jmx.JobSchedulerViewMBean;
-import org.apache.activemq.util.Wait;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Tests of the JMX JobSchedulerStore management MBean.
- */
-public class JobSchedulerJmxManagementTests extends JobSchedulerTestSupport {
-
- private static final Logger LOG = LoggerFactory.getLogger(JobSchedulerJmxManagementTests.class);
-
- @Test
- public void testJobSchedulerMBeanIsRegistered() throws Exception {
- JobSchedulerViewMBean view = getJobSchedulerMBean();
- assertNotNull(view);
- assertTrue(view.getAllJobs().isEmpty());
- }
-
- @Test
- public void testGetNumberOfJobs() throws Exception {
- JobSchedulerViewMBean view = getJobSchedulerMBean();
- assertNotNull(view);
- assertTrue(view.getAllJobs().isEmpty());
- scheduleMessage(60000, -1, -1);
- assertFalse(view.getAllJobs().isEmpty());
- assertEquals(1, view.getAllJobs().size());
- scheduleMessage(60000, -1, -1);
- assertEquals(2, view.getAllJobs().size());
- }
-
- @Test
- public void testRemvoeJob() throws Exception {
- JobSchedulerViewMBean view = getJobSchedulerMBean();
- assertNotNull(view);
- assertTrue(view.getAllJobs().isEmpty());
- scheduleMessage(60000, -1, -1);
- assertFalse(view.getAllJobs().isEmpty());
- TabularData jobs = view.getAllJobs();
- assertEquals(1, jobs.size());
- for (Object key : jobs.keySet()) {
- String jobId = ((List<?>)key).get(0).toString();
- LOG.info("Attempting to remove Job: {}", jobId);
- view.removeJob(jobId);
- }
- assertTrue(view.getAllJobs().isEmpty());
- }
-
- @Test
- public void testRemvoeJobInRange() throws Exception {
- JobSchedulerViewMBean view = getJobSchedulerMBean();
- assertNotNull(view);
- assertTrue(view.getAllJobs().isEmpty());
- scheduleMessage(60000, -1, -1);
- assertFalse(view.getAllJobs().isEmpty());
- String now = JobSupport.getDateTime(System.currentTimeMillis());
- String later = JobSupport.getDateTime(System.currentTimeMillis() + 120 * 1000);
- view.removeAllJobs(now, later);
- assertTrue(view.getAllJobs().isEmpty());
- }
-
- @Test
- public void testGetNextScheduledJob() throws Exception {
- JobSchedulerViewMBean view = getJobSchedulerMBean();
- assertNotNull(view);
- assertTrue(view.getAllJobs().isEmpty());
- scheduleMessage(60000, -1, -1);
- assertFalse(view.getAllJobs().isEmpty());
- long before = System.currentTimeMillis() + 57 * 1000;
- long toLate = System.currentTimeMillis() + 63 * 1000;
- String next = view.getNextScheduleTime();
- long nextTime = JobSupport.getDataTime(next);
- LOG.info("Next Scheduled Time: {}", next);
- assertTrue(nextTime > before);
- assertTrue(nextTime < toLate);
- }
-
- @Test
- public void testGetExecutionCount() throws Exception {
- final JobSchedulerViewMBean view = getJobSchedulerMBean();
- assertNotNull(view);
- assertTrue(view.getAllJobs().isEmpty());
- scheduleMessage(10000, 1000, 10);
- assertFalse(view.getAllJobs().isEmpty());
- TabularData jobs = view.getAllJobs();
- assertEquals(1, jobs.size());
- String jobId = null;
- for (Object key : jobs.keySet()) {
- jobId = ((List<?>)key).get(0).toString();
- }
-
- final String fixedJobId = jobId;
- LOG.info("Attempting to get execution count for Job: {}", jobId);
- assertEquals(0, view.getExecutionCount(jobId));
-
- assertTrue("Should execute again", Wait.waitFor(new Wait.Condition() {
-
- @Override
- public boolean isSatisified() throws Exception {
- return view.getExecutionCount(fixedJobId) > 0;
- }
- }));
- }
-
- @Override
- protected boolean isUseJmx() {
- return true;
- }
-
- protected void scheduleMessage(int time, int period, int repeat) throws Exception {
- Connection connection = createConnection();
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageProducer producer = session.createProducer(destination);
- TextMessage message = session.createTextMessage("test msg");
- message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, time);
- message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_PERIOD, period);
- message.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT, repeat);
- producer.send(message);
- connection.close();
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerManagementTest.java
----------------------------------------------------------------------
diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerManagementTest.java b/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerManagementTest.java
index c82f8ef..bc89d9e 100644
--- a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerManagementTest.java
+++ b/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerManagementTest.java
@@ -16,11 +16,7 @@
*/
package org.apache.activemq.broker.scheduler;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
-
+import java.io.File;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -33,17 +29,18 @@ import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
+import org.apache.activemq.EmbeddedBrokerTestSupport;
import org.apache.activemq.ScheduledMessage;
+import org.apache.activemq.broker.BrokerService;
+import org.apache.activemq.util.IOHelper;
import org.apache.activemq.util.IdGenerator;
-import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class JobSchedulerManagementTest extends JobSchedulerTestSupport {
+public class JobSchedulerManagementTest extends EmbeddedBrokerTestSupport {
private static final transient Logger LOG = LoggerFactory.getLogger(JobSchedulerManagementTest.class);
- @Test
public void testRemoveAllScheduled() throws Exception {
final int COUNT = 5;
Connection connection = createConnection();
@@ -80,7 +77,6 @@ public class JobSchedulerManagementTest extends JobSchedulerTestSupport {
assertEquals(latch.getCount(), COUNT);
}
- @Test
public void testRemoveAllScheduledAtTime() throws Exception {
final int COUNT = 3;
Connection connection = createConnection();
@@ -126,7 +122,8 @@ public class JobSchedulerManagementTest extends JobSchedulerTestSupport {
// Send the remove request
MessageProducer producer = session.createProducer(management);
Message request = session.createMessage();
- request.setStringProperty(ScheduledMessage.AMQ_SCHEDULER_ACTION, ScheduledMessage.AMQ_SCHEDULER_ACTION_REMOVEALL);
+ request.setStringProperty(ScheduledMessage.AMQ_SCHEDULER_ACTION,
+ ScheduledMessage.AMQ_SCHEDULER_ACTION_REMOVEALL);
request.setStringProperty(ScheduledMessage.AMQ_SCHEDULER_ACTION_START_TIME, Long.toString(start));
request.setStringProperty(ScheduledMessage.AMQ_SCHEDULER_ACTION_END_TIME, Long.toString(end));
producer.send(request);
@@ -146,7 +143,6 @@ public class JobSchedulerManagementTest extends JobSchedulerTestSupport {
assertEquals(2, latch.getCount());
}
- @Test
public void testBrowseAllScheduled() throws Exception {
final int COUNT = 10;
Connection connection = createConnection();
@@ -195,8 +191,7 @@ public class JobSchedulerManagementTest extends JobSchedulerTestSupport {
Thread.sleep(2000);
assertEquals(latch.getCount(), COUNT);
- // now see if we got all the scheduled messages on the browse
- // destination.
+ // now see if we got all the scheduled messages on the browse destination.
latch.await(10, TimeUnit.SECONDS);
assertEquals(browsedLatch.getCount(), 0);
@@ -205,7 +200,6 @@ public class JobSchedulerManagementTest extends JobSchedulerTestSupport {
assertEquals(latch.getCount(), 0);
}
- @Test
public void testBrowseWindowlScheduled() throws Exception {
final int COUNT = 10;
Connection connection = createConnection();
@@ -261,18 +255,15 @@ public class JobSchedulerManagementTest extends JobSchedulerTestSupport {
Thread.sleep(2000);
assertEquals(COUNT + 2, latch.getCount());
- // now see if we got all the scheduled messages on the browse
- // destination.
+ // now see if we got all the scheduled messages on the browse destination.
latch.await(15, TimeUnit.SECONDS);
assertEquals(0, browsedLatch.getCount());
- // now see if we got all the scheduled messages on the browse
- // destination.
+ // now see if we got all the scheduled messages on the browse destination.
latch.await(20, TimeUnit.SECONDS);
assertEquals(0, latch.getCount());
}
- @Test
public void testRemoveScheduled() throws Exception {
final int COUNT = 10;
Connection connection = createConnection();
@@ -306,7 +297,8 @@ public class JobSchedulerManagementTest extends JobSchedulerTestSupport {
// Send the browse request
Message request = session.createMessage();
- request.setStringProperty(ScheduledMessage.AMQ_SCHEDULER_ACTION, ScheduledMessage.AMQ_SCHEDULER_ACTION_BROWSE);
+ request.setStringProperty(ScheduledMessage.AMQ_SCHEDULER_ACTION,
+ ScheduledMessage.AMQ_SCHEDULER_ACTION_BROWSE);
request.setJMSReplyTo(browseDest);
producer.send(request);
@@ -315,12 +307,14 @@ public class JobSchedulerManagementTest extends JobSchedulerTestSupport {
Message message = browser.receive(2000);
assertNotNull(message);
- try {
+ try{
Message remove = session.createMessage();
- remove.setStringProperty(ScheduledMessage.AMQ_SCHEDULER_ACTION, ScheduledMessage.AMQ_SCHEDULER_ACTION_REMOVE);
- remove.setStringProperty(ScheduledMessage.AMQ_SCHEDULED_ID, message.getStringProperty(ScheduledMessage.AMQ_SCHEDULED_ID));
+ remove.setStringProperty(ScheduledMessage.AMQ_SCHEDULER_ACTION,
+ ScheduledMessage.AMQ_SCHEDULER_ACTION_REMOVE);
+ remove.setStringProperty(ScheduledMessage.AMQ_SCHEDULED_ID,
+ message.getStringProperty(ScheduledMessage.AMQ_SCHEDULED_ID));
producer.send(remove);
- } catch (Exception e) {
+ } catch(Exception e) {
}
}
@@ -329,7 +323,6 @@ public class JobSchedulerManagementTest extends JobSchedulerTestSupport {
assertEquals(COUNT, latch.getCount());
}
- @Test
public void testRemoveNotScheduled() throws Exception {
Connection connection = createConnection();
@@ -340,19 +333,19 @@ public class JobSchedulerManagementTest extends JobSchedulerTestSupport {
MessageProducer producer = session.createProducer(management);
- try {
+ try{
// Send the remove request
Message remove = session.createMessage();
- remove.setStringProperty(ScheduledMessage.AMQ_SCHEDULER_ACTION, ScheduledMessage.AMQ_SCHEDULER_ACTION_REMOVEALL);
+ remove.setStringProperty(ScheduledMessage.AMQ_SCHEDULER_ACTION,
+ ScheduledMessage.AMQ_SCHEDULER_ACTION_REMOVEALL);
remove.setStringProperty(ScheduledMessage.AMQ_SCHEDULED_ID, new IdGenerator().generateId());
producer.send(remove);
- } catch (Exception e) {
+ } catch(Exception e) {
fail("Caught unexpected exception during remove of unscheduled message.");
}
}
- @Test
public void testBrowseWithSelector() throws Exception {
Connection connection = createConnection();
@@ -369,7 +362,7 @@ public class JobSchedulerManagementTest extends JobSchedulerTestSupport {
Destination browseDest = session.createTemporaryTopic();
// Create the "Browser"
- MessageConsumer browser = session.createConsumer(browseDest, ScheduledMessage.AMQ_SCHEDULED_DELAY + " = 45000");
+ MessageConsumer browser = session.createConsumer(browseDest, ScheduledMessage.AMQ_SCHEDULED_DELAY + " = 45000" );
connection.start();
@@ -390,6 +383,7 @@ public class JobSchedulerManagementTest extends JobSchedulerTestSupport {
assertNull(message);
}
+
protected void scheduleMessage(Connection connection, long delay) throws Exception {
scheduleMessage(connection, delay, 1);
}
@@ -400,10 +394,38 @@ public class JobSchedulerManagementTest extends JobSchedulerTestSupport {
TextMessage message = session.createTextMessage("test msg");
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, delay);
- for (int i = 0; i < count; ++i) {
+ for(int i = 0; i < count; ++i ) {
producer.send(message);
}
producer.close();
}
+
+ @Override
+ protected void setUp() throws Exception {
+ bindAddress = "vm://localhost";
+ super.setUp();
+ }
+
+ @Override
+ protected BrokerService createBroker() throws Exception {
+ return createBroker(true);
+ }
+
+ protected BrokerService createBroker(boolean delete) throws Exception {
+ File schedulerDirectory = new File("target/scheduler");
+ if (delete) {
+ IOHelper.mkdirs(schedulerDirectory);
+ IOHelper.deleteChildren(schedulerDirectory);
+ }
+ BrokerService answer = new BrokerService();
+ answer.setPersistent(true);
+ answer.setDeleteAllMessagesOnStartup(true);
+ answer.setDataDirectory("target");
+ answer.setSchedulerDirectoryFile(schedulerDirectory);
+ answer.setSchedulerSupport(true);
+ answer.setUseJmx(false);
+ answer.addConnector(bindAddress);
+ return answer;
+ }
}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerStoreCheckpointTest.java
----------------------------------------------------------------------
diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerStoreCheckpointTest.java b/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerStoreCheckpointTest.java
deleted file mode 100644
index c013a4c..0000000
--- a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerStoreCheckpointTest.java
+++ /dev/null
@@ -1,125 +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.broker.scheduler;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.activemq.store.kahadb.scheduler.JobSchedulerStoreImpl;
-import org.apache.activemq.util.ByteSequence;
-import org.apache.activemq.util.IOHelper;
-import org.apache.activemq.util.Wait;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class JobSchedulerStoreCheckpointTest {
-
- static final Logger LOG = LoggerFactory.getLogger(JobSchedulerStoreCheckpointTest.class);
-
- private JobSchedulerStoreImpl store;
- private JobScheduler scheduler;
- private ByteSequence payload;
-
- @Before
- public void setUp() throws Exception {
- File directory = new File("target/test/ScheduledJobsDB");
- IOHelper.mkdirs(directory);
- IOHelper.deleteChildren(directory);
- startStore(directory);
-
- byte[] data = new byte[8192];
- for (int i = 0; i < data.length; ++i) {
- data[i] = (byte) (i % 256);
- }
-
- payload = new ByteSequence(data);
- }
-
- protected void startStore(File directory) throws Exception {
- store = new JobSchedulerStoreImpl();
- store.setDirectory(directory);
- store.setCheckpointInterval(5000);
- store.setCleanupInterval(10000);
- store.setJournalMaxFileLength(10 * 1024);
- store.start();
- scheduler = store.getJobScheduler("test");
- scheduler.startDispatching();
- }
-
- private int getNumJournalFiles() throws IOException {
- return store.getJournal().getFileMap().size();
- }
-
- @After
- public void tearDown() throws Exception {
- scheduler.stopDispatching();
- store.stop();
- }
-
- @Test
- public void test() throws Exception {
- final int COUNT = 10;
- final CountDownLatch latch = new CountDownLatch(COUNT);
- scheduler.addListener(new JobListener() {
- @Override
- public void scheduledJob(String id, ByteSequence job) {
- latch.countDown();
- }
- });
-
- long time = TimeUnit.SECONDS.toMillis(30);
- for (int i = 0; i < COUNT; i++) {
- scheduler.schedule("id" + i, payload, "", time, 0, 0);
- }
-
- int size = scheduler.getAllJobs().size();
- assertEquals(size, COUNT);
-
- LOG.info("Number of journal log files: {}", getNumJournalFiles());
- // need a little slack so go over 60 seconds
- assertTrue(latch.await(70, TimeUnit.SECONDS));
- assertEquals(0, latch.getCount());
-
- for (int i = 0; i < COUNT; i++) {
- scheduler.schedule("id" + i, payload, "", time, 0, 0);
- }
-
- LOG.info("Number of journal log files: {}", getNumJournalFiles());
- // need a little slack so go over 60 seconds
- assertTrue(latch.await(70, TimeUnit.SECONDS));
- assertEquals(0, latch.getCount());
-
- assertTrue("Should be only one log left: " + getNumJournalFiles(), Wait.waitFor(new Wait.Condition() {
-
- @Override
- public boolean isSatisified() throws Exception {
- return getNumJournalFiles() == 1;
- }
- }, TimeUnit.MINUTES.toMillis(2)));
-
- LOG.info("Number of journal log files: {}", getNumJournalFiles());
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerStoreTest.java
----------------------------------------------------------------------
diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerStoreTest.java b/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerStoreTest.java
index df1e7ff..0e0c1d7 100644
--- a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerStoreTest.java
+++ b/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerStoreTest.java
@@ -16,62 +16,50 @@
*/
package org.apache.activemq.broker.scheduler;
-import static org.junit.Assert.assertEquals;
-
import java.io.File;
import java.util.ArrayList;
import java.util.List;
+import junit.framework.TestCase;
+
import org.apache.activemq.store.kahadb.scheduler.JobSchedulerStoreImpl;
import org.apache.activemq.util.ByteSequence;
import org.apache.activemq.util.IOHelper;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class JobSchedulerStoreTest {
- private static final Logger LOG = LoggerFactory.getLogger(JobSchedulerStoreTest.class);
+public class JobSchedulerStoreTest extends TestCase {
- @Test(timeout = 120 * 1000)
public void testRestart() throws Exception {
JobSchedulerStore store = new JobSchedulerStoreImpl();
File directory = new File("target/test/ScheduledDB");
- IOHelper.mkdirs(directory);
- IOHelper.deleteChildren(directory);
- store.setDirectory(directory);
+ IOHelper.mkdirs(directory);
+ IOHelper.deleteChildren(directory);
+ store.setDirectory(directory);
final int NUMBER = 1000;
store.start();
- List<ByteSequence> list = new ArrayList<ByteSequence>();
- for (int i = 0; i < NUMBER; i++) {
- ByteSequence buff = new ByteSequence(new String("testjob" + i).getBytes());
+ List<ByteSequence>list = new ArrayList<ByteSequence>();
+ for (int i = 0; i < NUMBER;i++ ) {
+ ByteSequence buff = new ByteSequence(new String("testjob"+i).getBytes());
list.add(buff);
}
-
JobScheduler js = store.getJobScheduler("test");
js.startDispatching();
int count = 0;
- long startTime = 10 * 60 * 1000;
- long period = startTime;
- for (ByteSequence job : list) {
- js.schedule("id:" + (count++), job, "", startTime, period, -1);
+ long startTime = 10 * 60 * 1000; long period = startTime;
+ for (ByteSequence job:list) {
+ js.schedule("id:"+(count++), job, "", startTime, period, -1);
}
-
- List<Job> test = js.getAllJobs();
- LOG.debug("Found {} jobs in the store before restart", test.size());
- assertEquals(list.size(), test.size());
+ List<Job>test = js.getAllJobs();
+ assertEquals(list.size(),test.size());
store.stop();
store.start();
js = store.getJobScheduler("test");
test = js.getAllJobs();
- LOG.debug("Found {} jobs in the store after restart", test.size());
- assertEquals(list.size(), test.size());
-
- for (int i = 0; i < list.size(); i++) {
+ assertEquals(list.size(),test.size());
+ for (int i = 0; i < list.size();i++) {
String orig = new String(list.get(i).getData());
String payload = new String(test.get(i).getPayload());
- assertEquals(orig, payload);
+ assertEquals(orig,payload);
}
}
}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerTest.java
----------------------------------------------------------------------
diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerTest.java b/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerTest.java
index 2210eba..5126970 100644
--- a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerTest.java
+++ b/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerTest.java
@@ -31,13 +31,8 @@ import org.apache.activemq.util.IOHelper;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
public class JobSchedulerTest {
-
- private static final Logger LOG = LoggerFactory.getLogger(JobSchedulerTest.class);
-
private JobSchedulerStore store;
private JobScheduler scheduler;
@@ -178,37 +173,6 @@ public class JobSchedulerTest {
}
@Test
- public void testGetExecutionCount() throws Exception {
- final String jobId = "Job-1";
- long time = 10000;
- final CountDownLatch done = new CountDownLatch(10);
-
- String str = new String("test");
- scheduler.schedule(jobId, new ByteSequence(str.getBytes()), "", time, 1000, 10);
-
- int size = scheduler.getAllJobs().size();
- assertEquals(size, 1);
-
- scheduler.addListener(new JobListener() {
- @Override
- public void scheduledJob(String id, ByteSequence job) {
- LOG.info("Job exectued: {}", 11 - done.getCount());
- done.countDown();
- }
- });
-
- List<Job> jobs = scheduler.getNextScheduleJobs();
- assertEquals(1, jobs.size());
- Job job = jobs.get(0);
- assertEquals(jobId, job.getJobId());
- assertEquals(0, job.getExecutionCount());
- assertTrue("Should have fired ten times.", done.await(60, TimeUnit.SECONDS));
- // The job is not updated on the last firing as it is removed from the store following
- // it's last execution so the count will always be one less than the max firings.
- assertTrue(job.getExecutionCount() >= 9);
- }
-
- @Test
public void testgetAllJobs() throws Exception {
final int COUNT = 10;
final String ID = "id:";
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerTestSupport.java
----------------------------------------------------------------------
diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerTestSupport.java b/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerTestSupport.java
deleted file mode 100644
index 2b25797..0000000
--- a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/JobSchedulerTestSupport.java
+++ /dev/null
@@ -1,112 +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.broker.scheduler;
-
-import java.io.File;
-
-import javax.jms.Connection;
-import javax.jms.ConnectionFactory;
-import javax.jms.Queue;
-import javax.management.ObjectName;
-
-import org.apache.activemq.ActiveMQConnectionFactory;
-import org.apache.activemq.broker.BrokerService;
-import org.apache.activemq.broker.jmx.JobSchedulerViewMBean;
-import org.apache.activemq.command.ActiveMQQueue;
-import org.apache.activemq.util.IOHelper;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.rules.TestName;
-
-/**
- * Base class for tests of the Broker's JobSchedulerStore.
- */
-public class JobSchedulerTestSupport {
-
- @Rule public TestName name = new TestName();
-
- protected String connectionUri;
- protected BrokerService broker;
- protected JobScheduler jobScheduler;
- protected Queue destination;
-
- @Before
- public void setUp() throws Exception {
- connectionUri = "vm://localhost";
- destination = new ActiveMQQueue(name.getMethodName());
-
- broker = createBroker();
- broker.start();
- broker.waitUntilStarted();
-
- jobScheduler = broker.getJobSchedulerStore().getJobScheduler("JMS");
- }
-
- @After
- public void tearDown() throws Exception {
- if (broker != null) {
- broker.stop();
- broker.waitUntilStopped();
- }
- }
-
- protected Connection createConnection() throws Exception {
- return createConnectionFactory().createConnection();
- }
-
- protected ConnectionFactory createConnectionFactory() throws Exception {
- return new ActiveMQConnectionFactory(connectionUri);
- }
-
- protected BrokerService createBroker() throws Exception {
- return createBroker(true);
- }
-
- protected boolean isUseJmx() {
- return false;
- }
-
- protected JobSchedulerViewMBean getJobSchedulerMBean() throws Exception {
- ObjectName objectName = broker.getAdminView().getJMSJobScheduler();
- JobSchedulerViewMBean scheduler = null;
- if (objectName != null) {
- scheduler = (JobSchedulerViewMBean) broker.getManagementContext()
- .newProxyInstance(objectName, JobSchedulerViewMBean.class, true);
- }
-
- return scheduler;
- }
-
- protected BrokerService createBroker(boolean delete) throws Exception {
- File schedulerDirectory = new File("target/scheduler");
- if (delete) {
- IOHelper.mkdirs(schedulerDirectory);
- IOHelper.deleteChildren(schedulerDirectory);
- }
-
- BrokerService answer = new BrokerService();
- answer.setPersistent(true);
- answer.setDeleteAllMessagesOnStartup(true);
- answer.setDataDirectory("target");
- answer.setSchedulerDirectoryFile(schedulerDirectory);
- answer.setSchedulerSupport(true);
- answer.setUseJmx(isUseJmx());
- return answer;
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/KahaDBSchedulerIndexRebuildTest.java
----------------------------------------------------------------------
diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/KahaDBSchedulerIndexRebuildTest.java b/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/KahaDBSchedulerIndexRebuildTest.java
deleted file mode 100644
index 9d0fef2..0000000
--- a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/KahaDBSchedulerIndexRebuildTest.java
+++ /dev/null
@@ -1,179 +0,0 @@
-package org.apache.activemq.broker.scheduler;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-import java.io.IOException;
-import java.security.ProtectionDomain;
-import java.util.concurrent.TimeUnit;
-
-import javax.jms.Connection;
-import javax.jms.MessageProducer;
-import javax.jms.Queue;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-
-import org.apache.activemq.ActiveMQConnectionFactory;
-import org.apache.activemq.ScheduledMessage;
-import org.apache.activemq.broker.BrokerService;
-import org.apache.activemq.store.kahadb.scheduler.JobSchedulerStoreImpl;
-import org.apache.activemq.util.IOHelper;
-import org.apache.activemq.util.Wait;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class KahaDBSchedulerIndexRebuildTest {
-
- static final Logger LOG = LoggerFactory.getLogger(KahaDBSchedulerIndexRebuildTest.class);
-
- private BrokerService broker = null;
- private final int NUM_JOBS = 50;
-
- static String basedir;
- static {
- try {
- ProtectionDomain protectionDomain = SchedulerDBVersionTest.class.getProtectionDomain();
- basedir = new File(new File(protectionDomain.getCodeSource().getLocation().getPath()), "../.").getCanonicalPath();
- } catch (IOException e) {
- basedir = ".";
- }
- }
-
- private final File schedulerStoreDir = new File(basedir, "activemq-data/store/scheduler");
- private final File storeDir = new File(basedir, "activemq-data/store/");
-
- @Before
- public void setUp() throws Exception {
- LOG.info("Test Dir = {}", schedulerStoreDir);
- }
-
- @After
- public void tearDown() throws Exception {
- if (broker != null) {
- broker.stop();
- }
- }
-
- @Test
- public void testIndexRebuilds() throws Exception {
- IOHelper.deleteFile(schedulerStoreDir);
-
- JobSchedulerStoreImpl schedulerStore = createScheduler();
- broker = createBroker(schedulerStore);
- broker.start();
- ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("vm://localhost");
- Connection connection = cf.createConnection();
- connection.start();
- for (int i = 0; i < NUM_JOBS; ++i) {
- scheduleRepeating(connection);
- }
- connection.close();
-
- JobScheduler scheduler = schedulerStore.getJobScheduler("JMS");
- assertNotNull(scheduler);
- assertEquals(NUM_JOBS, scheduler.getAllJobs().size());
-
- broker.stop();
-
- IOHelper.delete(new File(schedulerStoreDir, "scheduleDB.data"));
-
- schedulerStore = createScheduler();
- broker = createBroker(schedulerStore);
- broker.start();
-
- scheduler = schedulerStore.getJobScheduler("JMS");
- assertNotNull(scheduler);
- assertEquals(NUM_JOBS, scheduler.getAllJobs().size());
- }
-
- @Test
- public void testIndexRebuildsAfterSomeJobsExpire() throws Exception {
- IOHelper.deleteFile(schedulerStoreDir);
-
- JobSchedulerStoreImpl schedulerStore = createScheduler();
- broker = createBroker(schedulerStore);
- broker.start();
- ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("vm://localhost");
- Connection connection = cf.createConnection();
- connection.start();
- for (int i = 0; i < NUM_JOBS; ++i) {
- scheduleRepeating(connection);
- scheduleOneShot(connection);
- }
- connection.close();
-
- JobScheduler scheduler = schedulerStore.getJobScheduler("JMS");
- assertNotNull(scheduler);
- assertEquals(NUM_JOBS * 2, scheduler.getAllJobs().size());
-
- final JobScheduler awaitingOneShotTimeout = scheduler;
- assertTrue("One shot jobs should time out", Wait.waitFor(new Wait.Condition() {
-
- @Override
- public boolean isSatisified() throws Exception {
- return awaitingOneShotTimeout.getAllJobs().size() == NUM_JOBS;
- }
- }, TimeUnit.MINUTES.toMillis(2)));
-
- broker.stop();
-
- IOHelper.delete(new File(schedulerStoreDir, "scheduleDB.data"));
-
- schedulerStore = createScheduler();
- broker = createBroker(schedulerStore);
- broker.start();
-
- scheduler = schedulerStore.getJobScheduler("JMS");
- assertNotNull(scheduler);
- assertEquals(NUM_JOBS, scheduler.getAllJobs().size());
- }
-
- private void scheduleRepeating(Connection connection) throws Exception {
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Queue queue = session.createQueue("test.queue");
- MessageProducer producer = session.createProducer(queue);
-
- TextMessage message = session.createTextMessage("test msg");
- long time = 360 * 1000;
- message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, time);
- message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_PERIOD, 500);
- message.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT, -1);
- producer.send(message);
- producer.close();
- }
-
- private void scheduleOneShot(Connection connection) throws Exception {
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Queue queue = session.createQueue("test.queue");
- MessageProducer producer = session.createProducer(queue);
-
- TextMessage message = session.createTextMessage("test msg");
- long time = TimeUnit.SECONDS.toMillis(30);
- message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, time);
- message.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT, 0);
- producer.send(message);
- producer.close();
- }
-
- protected JobSchedulerStoreImpl createScheduler() {
- JobSchedulerStoreImpl scheduler = new JobSchedulerStoreImpl();
- scheduler.setDirectory(schedulerStoreDir);
- scheduler.setJournalMaxFileLength(10 * 1024);
- return scheduler;
- }
-
- protected BrokerService createBroker(JobSchedulerStoreImpl scheduler) throws Exception {
- BrokerService answer = new BrokerService();
- answer.setJobSchedulerStore(scheduler);
- answer.setPersistent(true);
- answer.setDataDirectory(storeDir.getAbsolutePath());
- answer.setSchedulerSupport(true);
- answer.setUseJmx(false);
- return answer;
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/KahaDBSchedulerMissingJournalLogsTest.java
----------------------------------------------------------------------
diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/KahaDBSchedulerMissingJournalLogsTest.java b/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/KahaDBSchedulerMissingJournalLogsTest.java
deleted file mode 100644
index 30da10d..0000000
--- a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/KahaDBSchedulerMissingJournalLogsTest.java
+++ /dev/null
@@ -1,204 +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.broker.scheduler;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.File;
-import java.io.IOException;
-import java.security.ProtectionDomain;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import javax.jms.Connection;
-import javax.jms.MessageProducer;
-import javax.jms.Queue;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-
-import org.apache.activemq.ActiveMQConnectionFactory;
-import org.apache.activemq.ScheduledMessage;
-import org.apache.activemq.broker.BrokerService;
-import org.apache.activemq.store.kahadb.disk.journal.DataFile;
-import org.apache.activemq.store.kahadb.scheduler.JobSchedulerStoreImpl;
-import org.apache.activemq.util.IOHelper;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- *Test that the store recovers even if some log files are missing.
- */
-public class KahaDBSchedulerMissingJournalLogsTest {
-
- static final Logger LOG = LoggerFactory.getLogger(KahaDBSchedulerIndexRebuildTest.class);
-
- private BrokerService broker = null;
- private JobSchedulerStoreImpl schedulerStore = null;
-
- private final int NUM_LOGS = 6;
-
- static String basedir;
- static {
- try {
- ProtectionDomain protectionDomain = SchedulerDBVersionTest.class.getProtectionDomain();
- basedir = new File(new File(protectionDomain.getCodeSource().getLocation().getPath()), "../.").getCanonicalPath();
- } catch (IOException e) {
- basedir = ".";
- }
- }
-
- private final File schedulerStoreDir = new File(basedir, "activemq-data/store/scheduler");
- private final File storeDir = new File(basedir, "activemq-data/store/");
-
- /**
- * @throws java.lang.Exception
- */
- @Before
- public void setUp() throws Exception {
- IOHelper.deleteFile(schedulerStoreDir);
- LOG.info("Test Dir = {}", schedulerStoreDir);
-
- createBroker();
- broker.start();
- broker.waitUntilStarted();
-
- schedulerStore = (JobSchedulerStoreImpl) broker.getJobSchedulerStore();
- }
-
- /**
- * @throws java.lang.Exception
- */
- @After
- public void tearDown() throws Exception {
- if (broker != null) {
- broker.stop();
- broker.waitUntilStopped();
- }
- }
-
- @Test(timeout=120 * 1000)
- public void testMissingLogsCausesBrokerToFail() throws Exception {
- fillUpSomeLogFiles();
-
- int jobCount = schedulerStore.getJobScheduler("JMS").getAllJobs().size();
- LOG.info("There are {} jobs in the store.", jobCount);
-
- List<File> toDelete = new ArrayList<File>();
- Map<Integer, DataFile> files = schedulerStore.getJournal().getFileMap();
- for (int i = files.size(); i > files.size() / 2; i--) {
- toDelete.add(files.get(i).getFile());
- }
-
- broker.stop();
- broker.waitUntilStopped();
-
- for (File file : toDelete) {
- LOG.info("File to delete: {}", file);
- IOHelper.delete(file);
- }
-
- try {
- createBroker();
- fail("Should not start when logs are missing.");
- } catch (Exception e) {
- }
- }
-
- @Test(timeout=120 * 1000)
- public void testRecoverWhenSomeLogsAreMissing() throws Exception {
- fillUpSomeLogFiles();
-
- int jobCount = schedulerStore.getJobScheduler("JMS").getAllJobs().size();
- LOG.info("There are {} jobs in the store.", jobCount);
-
- List<File> toDelete = new ArrayList<File>();
- Map<Integer, DataFile> files = schedulerStore.getJournal().getFileMap();
- for (int i = files.size() - 1; i > files.size() / 2; i--) {
- toDelete.add(files.get(i).getFile());
- }
-
- broker.stop();
- broker.waitUntilStopped();
-
- for (File file : toDelete) {
- LOG.info("File to delete: {}", file);
- IOHelper.delete(file);
- }
-
- schedulerStore = createScheduler();
- schedulerStore.setIgnoreMissingJournalfiles(true);
-
- createBroker(schedulerStore);
- broker.start();
- broker.waitUntilStarted();
-
- int postRecoverJobCount = schedulerStore.getJobScheduler("JMS").getAllJobs().size();
- assertTrue(postRecoverJobCount > 0);
- assertTrue(postRecoverJobCount < jobCount);
- }
-
- private void fillUpSomeLogFiles() throws Exception {
- ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("vm://localhost");
- Connection connection = cf.createConnection();
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Queue queue = session.createQueue("test.queue");
- MessageProducer producer = session.createProducer(queue);
- connection.start();
- while (true) {
- scheduleRepeating(session, producer);
- if (schedulerStore.getJournal().getFileMap().size() == NUM_LOGS) {
- break;
- }
- }
- connection.close();
- }
-
- private void scheduleRepeating(Session session, MessageProducer producer) throws Exception {
- TextMessage message = session.createTextMessage("test msg");
- long time = 360 * 1000;
- message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, time);
- message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_PERIOD, 500);
- message.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT, -1);
- producer.send(message);
- }
-
- protected JobSchedulerStoreImpl createScheduler() {
- JobSchedulerStoreImpl scheduler = new JobSchedulerStoreImpl();
- scheduler.setDirectory(schedulerStoreDir);
- scheduler.setJournalMaxFileLength(10 * 1024);
- return scheduler;
- }
-
- protected void createBroker() throws Exception {
- createBroker(createScheduler());
- }
-
- protected void createBroker(JobSchedulerStoreImpl scheduler) throws Exception {
- broker = new BrokerService();
- broker.setJobSchedulerStore(scheduler);
- broker.setPersistent(true);
- broker.setDataDirectory(storeDir.getAbsolutePath());
- broker.setSchedulerSupport(true);
- broker.setUseJmx(false);
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/SchedulerDBVersionTest.java
----------------------------------------------------------------------
diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/SchedulerDBVersionTest.java b/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/SchedulerDBVersionTest.java
deleted file mode 100644
index 721f417..0000000
--- a/activemq-unit-tests/src/test/java/org/apache/activemq/broker/scheduler/SchedulerDBVersionTest.java
+++ /dev/null
@@ -1,164 +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.broker.scheduler;
-
-import static org.junit.Assert.assertEquals;
-
-import java.io.File;
-import java.io.IOException;
-import java.security.ProtectionDomain;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.jms.Connection;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageListener;
-import javax.jms.MessageProducer;
-import javax.jms.Queue;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-
-import org.apache.activemq.ActiveMQConnectionFactory;
-import org.apache.activemq.ScheduledMessage;
-import org.apache.activemq.broker.BrokerService;
-import org.apache.activemq.store.kahadb.scheduler.JobSchedulerStoreImpl;
-import org.apache.activemq.util.IOHelper;
-import org.junit.After;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class SchedulerDBVersionTest {
- static String basedir;
- static {
- try {
- ProtectionDomain protectionDomain = SchedulerDBVersionTest.class.getProtectionDomain();
- basedir = new File(new File(protectionDomain.getCodeSource().getLocation().getPath()), "../..").getCanonicalPath();
- } catch (IOException e) {
- basedir = ".";
- }
- }
-
- static final Logger LOG = LoggerFactory.getLogger(SchedulerDBVersionTest.class);
- final static File VERSION_LEGACY_JMS =
- new File(basedir + "/src/test/resources/org/apache/activemq/store/schedulerDB/legacy");
-
- BrokerService broker = null;
-
- protected BrokerService createBroker(JobSchedulerStoreImpl scheduler) throws Exception {
- BrokerService answer = new BrokerService();
- answer.setJobSchedulerStore(scheduler);
- answer.setPersistent(true);
- answer.setDataDirectory("target");
- answer.setSchedulerSupport(true);
- answer.setUseJmx(false);
- return answer;
- }
-
- @After
- public void tearDown() throws Exception {
- if (broker != null) {
- broker.stop();
- }
- }
-
- @Ignore("Used only when a new version of the store needs to archive it's test data.")
- @Test
- public void testCreateStore() throws Exception {
- JobSchedulerStoreImpl scheduler = new JobSchedulerStoreImpl();
- File dir = new File("src/test/resources/org/apache/activemq/store/schedulerDB/legacy");
- IOHelper.deleteFile(dir);
- scheduler.setDirectory(dir);
- scheduler.setJournalMaxFileLength(1024 * 1024);
- broker = createBroker(scheduler);
- broker.start();
- ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("vm://localhost");
- Connection connection = cf.createConnection();
- connection.start();
- scheduleRepeating(connection);
- connection.close();
- broker.stop();
- }
-
- private void scheduleRepeating(Connection connection) throws Exception {
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Queue queue = session.createQueue("test.queue");
- MessageProducer producer = session.createProducer(queue);
-
- TextMessage message = session.createTextMessage("test msg");
- long time = 1000;
- message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, time);
- message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_PERIOD, 500);
- message.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT, -1);
- producer.send(message);
- producer.close();
- }
-
- @Test
- public void testLegacyStoreConversion() throws Exception {
- doTestScheduleRepeated(VERSION_LEGACY_JMS);
- }
-
- public void doTestScheduleRepeated(File existingStore) throws Exception {
- File testDir = new File("target/activemq-data/store/scheduler/versionDB");
- IOHelper.deleteFile(testDir);
- IOHelper.copyFile(existingStore, testDir);
-
- final int NUMBER = 10;
- ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("vm://localhost");
-
- for (int i = 0; i < 3; ++i) {
- JobSchedulerStoreImpl scheduler = new JobSchedulerStoreImpl();
- scheduler.setDirectory(testDir);
- scheduler.setJournalMaxFileLength(1024 * 1024);
- BrokerService broker = createBroker(scheduler);
- broker.start();
- broker.waitUntilStarted();
-
- final AtomicInteger count = new AtomicInteger();
- Connection connection = cf.createConnection();
-
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Queue queue = session.createQueue("test.queue");
-
- MessageConsumer consumer = session.createConsumer(queue);
-
- final CountDownLatch latch = new CountDownLatch(NUMBER);
- consumer.setMessageListener(new MessageListener() {
- @Override
- public void onMessage(Message message) {
- LOG.info("Received scheduled message: {}", message);
- latch.countDown();
- count.incrementAndGet();
- }
- });
-
- connection.start();
- assertEquals(latch.getCount(), NUMBER);
- latch.await(30, TimeUnit.SECONDS);
-
- connection.close();
- broker.stop();
- broker.waitUntilStopped();
-
- assertEquals(0, latch.getCount());
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-unit-tests/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/activemq-unit-tests/src/test/resources/log4j.properties b/activemq-unit-tests/src/test/resources/log4j.properties
index 85516aa..564ed9e 100755
--- a/activemq-unit-tests/src/test/resources/log4j.properties
+++ b/activemq-unit-tests/src/test/resources/log4j.properties
@@ -21,7 +21,6 @@
log4j.rootLogger=INFO, out, stdout
#log4j.logger.org.apache.activemq.broker.scheduler=DEBUG
-#log4j.logger.org.apache.activemq.store.kahadb.scheduler=DEBUG
#log4j.logger.org.apache.activemq.network.DemandForwardingBridgeSupport=DEBUG
#log4j.logger.org.apache.activemq.transport.failover=TRACE
#log4j.logger.org.apache.activemq.store.jdbc=TRACE
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-unit-tests/src/test/resources/org/apache/activemq/store/schedulerDB/legacy/db-1.log
----------------------------------------------------------------------
diff --git a/activemq-unit-tests/src/test/resources/org/apache/activemq/store/schedulerDB/legacy/db-1.log b/activemq-unit-tests/src/test/resources/org/apache/activemq/store/schedulerDB/legacy/db-1.log
deleted file mode 100644
index 342f8c7..0000000
Binary files a/activemq-unit-tests/src/test/resources/org/apache/activemq/store/schedulerDB/legacy/db-1.log and /dev/null differ
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-unit-tests/src/test/resources/org/apache/activemq/store/schedulerDB/legacy/scheduleDB.data
----------------------------------------------------------------------
diff --git a/activemq-unit-tests/src/test/resources/org/apache/activemq/store/schedulerDB/legacy/scheduleDB.data b/activemq-unit-tests/src/test/resources/org/apache/activemq/store/schedulerDB/legacy/scheduleDB.data
deleted file mode 100644
index 30c937d..0000000
Binary files a/activemq-unit-tests/src/test/resources/org/apache/activemq/store/schedulerDB/legacy/scheduleDB.data and /dev/null differ
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-unit-tests/src/test/resources/org/apache/activemq/store/schedulerDB/legacy/scheduleDB.redo
----------------------------------------------------------------------
diff --git a/activemq-unit-tests/src/test/resources/org/apache/activemq/store/schedulerDB/legacy/scheduleDB.redo b/activemq-unit-tests/src/test/resources/org/apache/activemq/store/schedulerDB/legacy/scheduleDB.redo
deleted file mode 100644
index b06e549..0000000
Binary files a/activemq-unit-tests/src/test/resources/org/apache/activemq/store/schedulerDB/legacy/scheduleDB.redo and /dev/null differ
[3/5] activemq git commit: Revert
"https://issues.apache.org/jira/browse/AMQ-3758"
Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobLocationsMarshaller.java
----------------------------------------------------------------------
diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobLocationsMarshaller.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobLocationsMarshaller.java
deleted file mode 100644
index e22e4df..0000000
--- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobLocationsMarshaller.java
+++ /dev/null
@@ -1,53 +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.store.kahadb.scheduler;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.activemq.store.kahadb.disk.util.VariableMarshaller;
-
-/**
- * A VariableMarshaller instance that performs the read and write of a list of
- * JobLocation objects using the JobLocation's built in read and write methods.
- */
-class JobLocationsMarshaller extends VariableMarshaller<List<JobLocation>> {
- static JobLocationsMarshaller INSTANCE = new JobLocationsMarshaller();
-
- @Override
- public List<JobLocation> readPayload(DataInput dataIn) throws IOException {
- List<JobLocation> result = new ArrayList<JobLocation>();
- int size = dataIn.readInt();
- for (int i = 0; i < size; i++) {
- JobLocation jobLocation = new JobLocation();
- jobLocation.readExternal(dataIn);
- result.add(jobLocation);
- }
- return result;
- }
-
- @Override
- public void writePayload(List<JobLocation> value, DataOutput dataOut) throws IOException {
- dataOut.writeInt(value.size());
- for (JobLocation jobLocation : value) {
- jobLocation.writeExternal(dataOut);
- }
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobSchedulerImpl.java
----------------------------------------------------------------------
diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobSchedulerImpl.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobSchedulerImpl.java
index bcb819c..455801a 100644
--- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobSchedulerImpl.java
+++ b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobSchedulerImpl.java
@@ -32,15 +32,11 @@ import org.apache.activemq.broker.scheduler.CronParser;
import org.apache.activemq.broker.scheduler.Job;
import org.apache.activemq.broker.scheduler.JobListener;
import org.apache.activemq.broker.scheduler.JobScheduler;
-import org.apache.activemq.protobuf.Buffer;
-import org.apache.activemq.store.kahadb.data.KahaAddScheduledJobCommand;
-import org.apache.activemq.store.kahadb.data.KahaRemoveScheduledJobCommand;
-import org.apache.activemq.store.kahadb.data.KahaRemoveScheduledJobsCommand;
-import org.apache.activemq.store.kahadb.data.KahaRescheduleJobCommand;
import org.apache.activemq.store.kahadb.disk.index.BTreeIndex;
import org.apache.activemq.store.kahadb.disk.journal.Location;
import org.apache.activemq.store.kahadb.disk.page.Transaction;
import org.apache.activemq.store.kahadb.disk.util.LongMarshaller;
+import org.apache.activemq.store.kahadb.disk.util.VariableMarshaller;
import org.apache.activemq.util.ByteSequence;
import org.apache.activemq.util.IdGenerator;
import org.apache.activemq.util.ServiceStopper;
@@ -48,13 +44,12 @@ import org.apache.activemq.util.ServiceSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class JobSchedulerImpl extends ServiceSupport implements Runnable, JobScheduler {
-
+class JobSchedulerImpl extends ServiceSupport implements Runnable, JobScheduler {
private static final Logger LOG = LoggerFactory.getLogger(JobSchedulerImpl.class);
- private final JobSchedulerStoreImpl store;
+ final JobSchedulerStoreImpl store;
private final AtomicBoolean running = new AtomicBoolean();
private String name;
- private BTreeIndex<Long, List<JobLocation>> index;
+ BTreeIndex<Long, List<JobLocation>> index;
private Thread thread;
private final AtomicBoolean started = new AtomicBoolean(false);
private final List<JobListener> jobListeners = new CopyOnWriteArrayList<JobListener>();
@@ -69,163 +64,233 @@ public class JobSchedulerImpl extends ServiceSupport implements Runnable, JobSch
this.name = name;
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.activemq.beanstalk.JobScheduler#getName()
+ */
@Override
public String getName() {
return this.name;
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.activemq.beanstalk.JobScheduler#addListener(org.apache.activemq .beanstalk.JobListener)
+ */
@Override
public void addListener(JobListener l) {
this.jobListeners.add(l);
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.activemq.beanstalk.JobScheduler#removeListener(org.apache. activemq.beanstalk.JobListener)
+ */
@Override
public void removeListener(JobListener l) {
this.jobListeners.remove(l);
}
@Override
- public void schedule(final String jobId, final ByteSequence payload, final long delay) throws IOException {
- doSchedule(jobId, payload, "", 0, delay, 0);
+ public synchronized void schedule(final String jobId, final ByteSequence payload, final long delay) throws IOException {
+ this.store.getPageFile().tx().execute(new Transaction.Closure<IOException>() {
+ @Override
+ public void execute(Transaction tx) throws IOException {
+ schedule(tx, jobId, payload, "", 0, delay, 0);
+ }
+ });
}
@Override
- public void schedule(final String jobId, final ByteSequence payload, final String cronEntry) throws Exception {
- doSchedule(jobId, payload, cronEntry, 0, 0, 0);
+ public synchronized void schedule(final String jobId, final ByteSequence payload, final String cronEntry) throws Exception {
+ this.store.getPageFile().tx().execute(new Transaction.Closure<IOException>() {
+ @Override
+ public void execute(Transaction tx) throws IOException {
+ schedule(tx, jobId, payload, cronEntry, 0, 0, 0);
+ }
+ });
}
@Override
- public void schedule(final String jobId, final ByteSequence payload, final String cronEntry, final long delay, final long period, final int repeat) throws IOException {
- doSchedule(jobId, payload, cronEntry, delay, period, repeat);
+ public synchronized void schedule(final String jobId, final ByteSequence payload, final String cronEntry, final long delay, final long period,
+ final int repeat) throws IOException {
+ this.store.getPageFile().tx().execute(new Transaction.Closure<IOException>() {
+ @Override
+ public void execute(Transaction tx) throws IOException {
+ schedule(tx, jobId, payload, cronEntry, delay, period, repeat);
+ }
+ });
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.activemq.beanstalk.JobScheduler#remove(long)
+ */
@Override
- public void remove(final long time) throws IOException {
- doRemoveRange(time, time);
+ public synchronized void remove(final long time) throws IOException {
+ this.store.getPageFile().tx().execute(new Transaction.Closure<IOException>() {
+ @Override
+ public void execute(Transaction tx) throws IOException {
+ remove(tx, time);
+ }
+ });
}
- @Override
- public void remove(final String jobId) throws IOException {
- doRemove(-1, jobId);
+ synchronized void removeFromIndex(final long time, final String jobId) throws IOException {
+ this.store.getPageFile().tx().execute(new Transaction.Closure<IOException>() {
+ @Override
+ public void execute(Transaction tx) throws IOException {
+ removeFromIndex(tx, time, jobId);
+ }
+ });
}
- @Override
- public void removeAllJobs() throws IOException {
- doRemoveRange(0, Long.MAX_VALUE);
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.activemq.beanstalk.JobScheduler#remove(long, java.lang.String)
+ */
+ public synchronized void remove(final long time, final String jobId) throws IOException {
+ this.store.getPageFile().tx().execute(new Transaction.Closure<IOException>() {
+ @Override
+ public void execute(Transaction tx) throws IOException {
+ remove(tx, time, jobId);
+ }
+ });
+ }
+
+ synchronized void remove(final long time, final List<JobLocation> jobIds) throws IOException {
+ this.store.getPageFile().tx().execute(new Transaction.Closure<IOException>() {
+ @Override
+ public void execute(Transaction tx) throws IOException {
+ remove(tx, time, jobIds);
+ }
+ });
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.activemq.beanstalk.JobScheduler#remove(java.lang.String)
+ */
@Override
- public void removeAllJobs(final long start, final long finish) throws IOException {
- doRemoveRange(start, finish);
+ public synchronized void remove(final String jobId) throws IOException {
+ this.store.getPageFile().tx().execute(new Transaction.Closure<IOException>() {
+ @Override
+ public void execute(Transaction tx) throws IOException {
+ remove(tx, jobId);
+ }
+ });
}
@Override
- public long getNextScheduleTime() throws IOException {
- this.store.readLockIndex();
- try {
- Map.Entry<Long, List<JobLocation>> first = this.index.getFirst(this.store.getPageFile().tx());
- return first != null ? first.getKey() : -1l;
- } finally {
- this.store.readUnlockIndex();
- }
+ public synchronized long getNextScheduleTime() throws IOException {
+ Map.Entry<Long, List<JobLocation>> first = this.index.getFirst(this.store.getPageFile().tx());
+ return first != null ? first.getKey() : -1l;
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.activemq.beanstalk.JobScheduler#getNextScheduleJobs()
+ */
@Override
- public List<Job> getNextScheduleJobs() throws IOException {
+ public synchronized List<Job> getNextScheduleJobs() throws IOException {
final List<Job> result = new ArrayList<Job>();
- this.store.readLockIndex();
- try {
- this.store.getPageFile().tx().execute(new Transaction.Closure<IOException>() {
- @Override
- public void execute(Transaction tx) throws IOException {
- Map.Entry<Long, List<JobLocation>> first = index.getFirst(tx);
- if (first != null) {
- for (JobLocation jl : first.getValue()) {
- ByteSequence bs = getPayload(jl.getLocation());
- Job job = new JobImpl(jl, bs);
- result.add(job);
- }
+
+ this.store.getPageFile().tx().execute(new Transaction.Closure<IOException>() {
+ @Override
+ public void execute(Transaction tx) throws IOException {
+ Map.Entry<Long, List<JobLocation>> first = index.getFirst(store.getPageFile().tx());
+ if (first != null) {
+ for (JobLocation jl : first.getValue()) {
+ ByteSequence bs = getPayload(jl.getLocation());
+ Job job = new JobImpl(jl, bs);
+ result.add(job);
}
}
- });
- } finally {
- this.store.readUnlockIndex();
- }
- return result;
- }
-
- private Map.Entry<Long, List<JobLocation>> getNextToSchedule() throws IOException {
- this.store.readLockIndex();
- try {
- if (!this.store.isStopped() && !this.store.isStopping()) {
- Map.Entry<Long, List<JobLocation>> first = this.index.getFirst(this.store.getPageFile().tx());
- return first;
}
- } finally {
- this.store.readUnlockIndex();
- }
- return null;
+ });
+ return result;
}
@Override
- public List<Job> getAllJobs() throws IOException {
+ public synchronized List<Job> getAllJobs() throws IOException {
final List<Job> result = new ArrayList<Job>();
- this.store.readLockIndex();
- try {
- this.store.getPageFile().tx().execute(new Transaction.Closure<IOException>() {
- @Override
- public void execute(Transaction tx) throws IOException {
- Iterator<Map.Entry<Long, List<JobLocation>>> iter = index.iterator(store.getPageFile().tx());
- while (iter.hasNext()) {
- Map.Entry<Long, List<JobLocation>> next = iter.next();
- if (next != null) {
- for (JobLocation jl : next.getValue()) {
- ByteSequence bs = getPayload(jl.getLocation());
- Job job = new JobImpl(jl, bs);
- result.add(job);
- }
- } else {
- break;
+ this.store.getPageFile().tx().execute(new Transaction.Closure<IOException>() {
+ @Override
+ public void execute(Transaction tx) throws IOException {
+ Iterator<Map.Entry<Long, List<JobLocation>>> iter = index.iterator(store.getPageFile().tx());
+ while (iter.hasNext()) {
+ Map.Entry<Long, List<JobLocation>> next = iter.next();
+ if (next != null) {
+ for (JobLocation jl : next.getValue()) {
+ ByteSequence bs = getPayload(jl.getLocation());
+ Job job = new JobImpl(jl, bs);
+ result.add(job);
}
+ } else {
+ break;
}
}
- });
- } finally {
- this.store.readUnlockIndex();
- }
+ }
+ });
return result;
}
@Override
- public List<Job> getAllJobs(final long start, final long finish) throws IOException {
+ public synchronized List<Job> getAllJobs(final long start, final long finish) throws IOException {
final List<Job> result = new ArrayList<Job>();
- this.store.readLockIndex();
- try {
- this.store.getPageFile().tx().execute(new Transaction.Closure<IOException>() {
- @Override
- public void execute(Transaction tx) throws IOException {
- Iterator<Map.Entry<Long, List<JobLocation>>> iter = index.iterator(tx, start);
- while (iter.hasNext()) {
- Map.Entry<Long, List<JobLocation>> next = iter.next();
- if (next != null && next.getKey().longValue() <= finish) {
- for (JobLocation jl : next.getValue()) {
- ByteSequence bs = getPayload(jl.getLocation());
- Job job = new JobImpl(jl, bs);
- result.add(job);
- }
- } else {
- break;
+ this.store.getPageFile().tx().execute(new Transaction.Closure<IOException>() {
+ @Override
+ public void execute(Transaction tx) throws IOException {
+ Iterator<Map.Entry<Long, List<JobLocation>>> iter = index.iterator(store.getPageFile().tx(), start);
+ while (iter.hasNext()) {
+ Map.Entry<Long, List<JobLocation>> next = iter.next();
+ if (next != null && next.getKey().longValue() <= finish) {
+ for (JobLocation jl : next.getValue()) {
+ ByteSequence bs = getPayload(jl.getLocation());
+ Job job = new JobImpl(jl, bs);
+ result.add(job);
}
+ } else {
+ break;
}
}
- });
- } finally {
- this.store.readUnlockIndex();
- }
+ }
+ });
return result;
}
- private void doSchedule(final String jobId, final ByteSequence payload, final String cronEntry, long delay, long period, int repeat) throws IOException {
+ @Override
+ public synchronized void removeAllJobs() throws IOException {
+ this.store.getPageFile().tx().execute(new Transaction.Closure<IOException>() {
+ @Override
+ public void execute(Transaction tx) throws IOException {
+ destroy(tx);
+ }
+ });
+ }
+
+ @Override
+ public synchronized void removeAllJobs(final long start, final long finish) throws IOException {
+ this.store.getPageFile().tx().execute(new Transaction.Closure<IOException>() {
+ @Override
+ public void execute(Transaction tx) throws IOException {
+ destroy(tx, start, finish);
+ }
+ });
+ }
+
+ ByteSequence getPayload(Location location) throws IllegalStateException, IOException {
+ return this.store.getPayload(location);
+ }
+
+ void schedule(Transaction tx, String jobId, ByteSequence payload, String cronEntry, long delay, long period, int repeat) throws IOException {
long startTime = System.currentTimeMillis();
// round startTime - so we can schedule more jobs
// at the same time
@@ -243,86 +308,38 @@ public class JobSchedulerImpl extends ServiceSupport implements Runnable, JobSch
// start time not set by CRON - so it it to the current time
time = startTime;
}
-
if (delay > 0) {
time += delay;
} else {
time += period;
}
- KahaAddScheduledJobCommand newJob = new KahaAddScheduledJobCommand();
- newJob.setScheduler(name);
- newJob.setJobId(jobId);
- newJob.setStartTime(startTime);
- newJob.setCronEntry(cronEntry);
- newJob.setDelay(delay);
- newJob.setPeriod(period);
- newJob.setRepeat(repeat);
- newJob.setNextExecutionTime(time);
- newJob.setPayload(new Buffer(payload.getData(), payload.getOffset(), payload.getLength()));
-
- this.store.store(newJob);
- }
-
- private void doReschedule(final String jobId, long executionTime, long nextExecutionTime, int rescheduledCount) throws IOException {
- KahaRescheduleJobCommand update = new KahaRescheduleJobCommand();
- update.setScheduler(name);
- update.setJobId(jobId);
- update.setExecutionTime(executionTime);
- update.setNextExecutionTime(nextExecutionTime);
- update.setRescheduledCount(rescheduledCount);
- this.store.store(update);
- }
-
- private void doRemove(final long executionTime, final List<JobLocation> jobs) throws IOException {
- for (JobLocation job : jobs) {
- doRemove(executionTime, job.getJobId());
- }
- }
-
- private void doRemove(long executionTime, final String jobId) throws IOException {
- KahaRemoveScheduledJobCommand remove = new KahaRemoveScheduledJobCommand();
- remove.setScheduler(name);
- remove.setJobId(jobId);
- remove.setNextExecutionTime(executionTime);
- this.store.store(remove);
- }
-
- private void doRemoveRange(long start, long end) throws IOException {
- KahaRemoveScheduledJobsCommand destroy = new KahaRemoveScheduledJobsCommand();
- destroy.setScheduler(name);
- destroy.setStartTime(start);
- destroy.setEndTime(end);
- this.store.store(destroy);
- }
-
- /**
- * Adds a new Scheduled job to the index. Must be called under index lock.
- *
- * This method must ensure that a duplicate add is not processed into the scheduler. On index
- * recover some adds may be replayed and we don't allow more than one instance of a JobId to
- * exist at any given scheduled time, so filter these out to ensure idempotence.
- *
- * @param tx
- * Transaction in which the update is performed.
- * @param command
- * The new scheduled job command to process.
- * @param location
- * The location where the add command is stored in the journal.
- *
- * @throws IOException if an error occurs updating the index.
- */
- protected void process(final Transaction tx, final KahaAddScheduledJobCommand command, Location location) throws IOException {
+ Location location = this.store.write(payload, false);
JobLocation jobLocation = new JobLocation(location);
- jobLocation.setJobId(command.getJobId());
- jobLocation.setStartTime(command.getStartTime());
- jobLocation.setCronEntry(command.getCronEntry());
- jobLocation.setDelay(command.getDelay());
- jobLocation.setPeriod(command.getPeriod());
- jobLocation.setRepeat(command.getRepeat());
-
- long nextExecutionTime = command.getNextExecutionTime();
+ this.store.incrementJournalCount(tx, location);
+ jobLocation.setJobId(jobId);
+ jobLocation.setStartTime(startTime);
+ jobLocation.setCronEntry(cronEntry);
+ jobLocation.setDelay(delay);
+ jobLocation.setPeriod(period);
+ jobLocation.setRepeat(repeat);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Scheduling " + jobLocation);
+ }
+ storeJob(tx, jobLocation, time);
+ this.scheduleTime.newJob();
+ }
+
+ synchronized void storeJob(final JobLocation jobLocation, final long nextExecutionTime) throws IOException {
+ this.store.getPageFile().tx().execute(new Transaction.Closure<IOException>() {
+ @Override
+ public void execute(Transaction tx) throws IOException {
+ storeJob(tx, jobLocation, nextExecutionTime);
+ }
+ });
+ }
+ void storeJob(final Transaction tx, final JobLocation jobLocation, final long nextExecutionTime) throws IOException {
List<JobLocation> values = null;
jobLocation.setNextTime(nextExecutionTime);
if (this.index.containsKey(tx, nextExecutionTime)) {
@@ -331,239 +348,106 @@ public class JobSchedulerImpl extends ServiceSupport implements Runnable, JobSch
if (values == null) {
values = new ArrayList<JobLocation>();
}
+ values.add(jobLocation);
+ this.index.put(tx, nextExecutionTime, values);
+ }
- // There can never be more than one instance of the same JobId scheduled at any
- // given time, when it happens its probably the result of index recovery and this
- // method must be idempotent so check for it first.
- if (!values.contains(jobLocation)) {
- values.add(jobLocation);
-
- // Reference the log file where the add command is stored to prevent GC.
- this.store.incrementJournalCount(tx, location);
- this.index.put(tx, nextExecutionTime, values);
- this.scheduleTime.newJob();
- } else {
- this.index.put(tx, nextExecutionTime, values);
- LOG.trace("Job {} already in scheduler at this time {}",
- jobLocation.getJobId(), jobLocation.getNextTime());
+ void remove(Transaction tx, long time, String jobId) throws IOException {
+ JobLocation result = removeFromIndex(tx, time, jobId);
+ if (result != null) {
+ this.store.decrementJournalCount(tx, result.getLocation());
}
}
- /**
- * Reschedules a Job after it has be fired.
- *
- * For jobs that are repeating this method updates the job in the index by adding it to the
- * jobs list for the new execution time. If the job is not a cron type job then this method
- * will reduce the repeat counter if the job has a fixed number of repeats set. The Job will
- * be removed from the jobs list it just executed on.
- *
- * This method must also update the value of the last update location in the JobLocation
- * instance so that the checkpoint worker doesn't drop the log file in which that command lives.
- *
- * This method must ensure that an reschedule command that references a job that doesn't exist
- * does not cause an error since it's possible that on recover the original add might be gone
- * and so the job should not reappear in the scheduler.
- *
- * @param tx
- * The TX under which the index is updated.
- * @param command
- * The reschedule command to process.
- * @param location
- * The location in the index where the reschedule command was stored.
- *
- * @throws IOException if an error occurs during the reschedule.
- */
- protected void process(final Transaction tx, final KahaRescheduleJobCommand command, Location location) throws IOException {
+ JobLocation removeFromIndex(Transaction tx, long time, String jobId) throws IOException {
JobLocation result = null;
- final List<JobLocation> current = this.index.remove(tx, command.getExecutionTime());
- if (current != null) {
- for (int i = 0; i < current.size(); i++) {
- JobLocation jl = current.get(i);
- if (jl.getJobId().equals(command.getJobId())) {
- current.remove(i);
- if (!current.isEmpty()) {
- this.index.put(tx, command.getExecutionTime(), current);
+ List<JobLocation> values = this.index.remove(tx, time);
+ if (values != null) {
+ for (int i = 0; i < values.size(); i++) {
+ JobLocation jl = values.get(i);
+ if (jl.getJobId().equals(jobId)) {
+ values.remove(i);
+ if (!values.isEmpty()) {
+ this.index.put(tx, time, values);
}
result = jl;
break;
}
}
- } else {
- LOG.debug("Process reschedule command for job {} non-existent executime time {}.",
- command.getJobId(), command.getExecutionTime());
}
+ return result;
+ }
+ private void remove(Transaction tx, long time, List<JobLocation> jobIds) throws IOException {
+ List<JobLocation> result = removeFromIndex(tx, time, jobIds);
if (result != null) {
- Location previousUpdate = result.getLastUpdate();
-
- List<JobLocation> target = null;
- result.setNextTime(command.getNextExecutionTime());
- result.setLastUpdate(location);
- result.setRescheduledCount(command.getRescheduledCount());
- if (!result.isCron() && result.getRepeat() > 0) {
- result.setRepeat(result.getRepeat() - 1);
+ for (JobLocation jl : result) {
+ this.store.decrementJournalCount(tx, jl.getLocation());
}
- if (this.index.containsKey(tx, command.getNextExecutionTime())) {
- target = this.index.remove(tx, command.getNextExecutionTime());
- }
- if (target == null) {
- target = new ArrayList<JobLocation>();
- }
- target.add(result);
-
- // Track the location of the last reschedule command and release the log file
- // reference for the previous one if there was one.
- this.store.incrementJournalCount(tx, location);
- if (previousUpdate != null) {
- this.store.decrementJournalCount(tx, previousUpdate);
- }
-
- this.index.put(tx, command.getNextExecutionTime(), target);
- this.scheduleTime.newJob();
- } else {
- LOG.debug("Process reschedule command for non-scheduled job {} at executime time {}.",
- command.getJobId(), command.getExecutionTime());
}
}
- /**
- * Removes a scheduled job from the scheduler.
- *
- * The remove operation can be of two forms. The first is that there is a job Id but no set time
- * (-1) in which case the jobs index is searched until the target job Id is located. The alternate
- * form is that a job Id and execution time are both set in which case the given time is checked
- * for a job matching that Id. In either case once an execution time is identified the job is
- * removed and the index updated.
- *
- * This method should ensure that if the matching job is not found that no error results as it
- * is possible that on a recover the initial add command could be lost so the job may not be
- * rescheduled.
- *
- * @param tx
- * The transaction under which the index is updated.
- * @param command
- * The remove command to process.
- * @param location
- * The location of the remove command in the Journal.
- *
- * @throws IOException if an error occurs while updating the scheduler index.
- */
- void process(final Transaction tx, final KahaRemoveScheduledJobCommand command, Location location) throws IOException {
-
- // Case 1: JobId and no time value means find the job and remove it.
- // Case 2: JobId and a time value means find exactly this scheduled job.
-
- Long executionTime = command.getNextExecutionTime();
-
- List<JobLocation> values = null;
-
- if (executionTime == -1) {
- for (Iterator<Map.Entry<Long, List<JobLocation>>> i = this.index.iterator(tx); i.hasNext();) {
- Map.Entry<Long, List<JobLocation>> entry = i.next();
- List<JobLocation> candidates = entry.getValue();
- if (candidates != null) {
- for (JobLocation jl : candidates) {
- if (jl.getJobId().equals(command.getJobId())) {
- LOG.trace("Entry {} contains the remove target: {}", entry.getKey(), command.getJobId());
- executionTime = entry.getKey();
- values = this.index.remove(tx, executionTime);
- break;
- }
- }
- }
- }
- } else {
- values = this.index.remove(tx, executionTime);
- }
-
- JobLocation removed = null;
-
- // Remove the job and update the index if there are any other jobs scheduled at this time.
+ private List<JobLocation> removeFromIndex(Transaction tx, long time, List<JobLocation> Jobs) throws IOException {
+ List<JobLocation> result = null;
+ List<JobLocation> values = this.index.remove(tx, time);
if (values != null) {
- for (JobLocation job : values) {
- if (job.getJobId().equals(command.getJobId())) {
- removed = job;
- values.remove(removed);
- break;
+ result = new ArrayList<JobLocation>(values.size());
+
+ for (JobLocation job : Jobs) {
+ if (values.remove(job)) {
+ result.add(job);
}
}
if (!values.isEmpty()) {
- this.index.put(tx, executionTime, values);
+ this.index.put(tx, time, values);
}
}
+ return result;
+ }
- if (removed != null) {
- LOG.trace("{} removed from scheduler {}", removed, this);
-
- // Remove the references for add and reschedule commands for this job
- // so that those logs can be GC'd when free.
- this.store.decrementJournalCount(tx, removed.getLocation());
- if (removed.getLastUpdate() != null) {
- this.store.decrementJournalCount(tx, removed.getLastUpdate());
+ void remove(Transaction tx, long time) throws IOException {
+ List<JobLocation> values = this.index.remove(tx, time);
+ if (values != null) {
+ for (JobLocation jl : values) {
+ this.store.decrementJournalCount(tx, jl.getLocation());
}
-
- // now that the job is removed from the index we can store the remove info and
- // then dereference the log files that hold the initial add command and the most
- // recent update command.
- this.store.referenceRemovedLocation(tx, location, removed);
}
}
- /**
- * Removes all scheduled jobs within a given time range.
- *
- * The method can be used to clear the entire scheduler index by specifying a range that
- * encompasses all time [0...Long.MAX_VALUE] or a single execution time can be removed by
- * setting start and end time to the same value.
- *
- * @param tx
- * The transaction under which the index is updated.
- * @param command
- * The remove command to process.
- * @param location
- * The location of the remove command in the Journal.
- *
- * @throws IOException if an error occurs while updating the scheduler index.
- */
- protected void process(final Transaction tx, final KahaRemoveScheduledJobsCommand command, Location location) throws IOException {
- removeInRange(tx, command.getStartTime(), command.getEndTime(), location);
+ void remove(Transaction tx, String id) throws IOException {
+ for (Iterator<Map.Entry<Long, List<JobLocation>>> i = this.index.iterator(tx); i.hasNext();) {
+ Map.Entry<Long, List<JobLocation>> entry = i.next();
+ List<JobLocation> values = entry.getValue();
+ if (values != null) {
+ for (JobLocation jl : values) {
+ if (jl.getJobId().equals(id)) {
+ remove(tx, entry.getKey(), id);
+ return;
+ }
+ }
+ }
+ }
}
- /**
- * Removes all jobs from the schedulers index. Must be called with the index locked.
- *
- * @param tx
- * The transaction under which the index entries for this scheduler are removed.
- *
- * @throws IOException if an error occurs removing the jobs from the scheduler index.
- */
- protected void removeAll(Transaction tx) throws IOException {
- this.removeInRange(tx, 0, Long.MAX_VALUE, null);
+ synchronized void destroy(Transaction tx) throws IOException {
+ List<Long> keys = new ArrayList<Long>();
+ for (Iterator<Map.Entry<Long, List<JobLocation>>> i = this.index.iterator(tx); i.hasNext();) {
+ Map.Entry<Long, List<JobLocation>> entry = i.next();
+ keys.add(entry.getKey());
+ }
+
+ for (Long l : keys) {
+ List<JobLocation> values = this.index.remove(tx, l);
+ if (values != null) {
+ for (JobLocation jl : values) {
+ this.store.decrementJournalCount(tx, jl.getLocation());
+ }
+ }
+ }
}
- /**
- * Removes all scheduled jobs within the target range.
- *
- * This method can be used to remove all the stored jobs by passing a range of [0...Long.MAX_VALUE]
- * or it can be used to remove all jobs at a given scheduled time by passing the same time value
- * for both start and end. If the optional location parameter is set then this method will update
- * the store's remove location tracker with the location value and the Jobs that are being removed.
- *
- * This method must be called with the store index locked for writes.
- *
- * @param tx
- * The transaction under which the index is to be updated.
- * @param start
- * The start time for the remove operation.
- * @param finish
- * The end time for the remove operation.
- * @param location (optional)
- * The location of the remove command that triggered this remove.
- *
- * @throws IOException if an error occurs during the remove operation.
- */
- protected void removeInRange(Transaction tx, long start, long finish, Location location) throws IOException {
+ synchronized void destroy(Transaction tx, long start, long finish) throws IOException {
List<Long> keys = new ArrayList<Long>();
for (Iterator<Map.Entry<Long, List<JobLocation>>> i = this.index.iterator(tx, start); i.hasNext();) {
Map.Entry<Long, List<JobLocation>> entry = i.next();
@@ -574,97 +458,32 @@ public class JobSchedulerImpl extends ServiceSupport implements Runnable, JobSch
}
}
- for (Long executionTime : keys) {
- List<JobLocation> values = this.index.remove(tx, executionTime);
- if (location != null) {
- for (JobLocation job : values) {
- LOG.trace("Removing {} scheduled at: {}", job, executionTime);
-
- // Remove the references for add and reschedule commands for this job
- // so that those logs can be GC'd when free.
- this.store.decrementJournalCount(tx, job.getLocation());
- if (job.getLastUpdate() != null) {
- this.store.decrementJournalCount(tx, job.getLastUpdate());
- }
-
- // now that the job is removed from the index we can store the remove info and
- // then dereference the log files that hold the initial add command and the most
- // recent update command.
- this.store.referenceRemovedLocation(tx, location, job);
+ for (Long l : keys) {
+ List<JobLocation> values = this.index.remove(tx, l);
+ if (values != null) {
+ for (JobLocation jl : values) {
+ this.store.decrementJournalCount(tx, jl.getLocation());
}
}
}
}
- /**
- * Removes a Job from the index using it's Id value and the time it is currently set to
- * be executed. This method will only remove the Job if it is found at the given execution
- * time.
- *
- * This method must be called under index lock.
- *
- * @param tx
- * the transaction under which this method is being executed.
- * @param jobId
- * the target Job Id to remove.
- * @param executionTime
- * the scheduled time that for the Job Id that is being removed.
- *
- * @returns true if the Job was removed or false if not found at the given time.
- *
- * @throws IOException if an error occurs while removing the Job.
- */
- protected boolean removeJobAtTime(Transaction tx, String jobId, long executionTime) throws IOException {
- boolean result = false;
-
- List<JobLocation> jobs = this.index.remove(tx, executionTime);
- Iterator<JobLocation> jobsIter = jobs.iterator();
- while (jobsIter.hasNext()) {
- JobLocation job = jobsIter.next();
- if (job.getJobId().equals(jobId)) {
- jobsIter.remove();
- // Remove the references for add and reschedule commands for this job
- // so that those logs can be GC'd when free.
- this.store.decrementJournalCount(tx, job.getLocation());
- if (job.getLastUpdate() != null) {
- this.store.decrementJournalCount(tx, job.getLastUpdate());
- }
- result = true;
- break;
- }
+ private synchronized Map.Entry<Long, List<JobLocation>> getNextToSchedule() throws IOException {
+ if (!this.store.isStopped() && !this.store.isStopping()) {
+ Map.Entry<Long, List<JobLocation>> first = this.index.getFirst(this.store.getPageFile().tx());
+ return first;
}
-
- // Return the list to the index modified or unmodified.
- this.index.put(tx, executionTime, jobs);
-
- return result;
+ return null;
}
- /**
- * Walks the Scheduled Job Tree and collects the add location and last update location
- * for all scheduled jobs.
- *
- * This method must be called with the index locked.
- *
- * @param tx
- * the transaction under which this operation was invoked.
- *
- * @return a list of all referenced Location values for this JobSchedulerImpl
- *
- * @throws IOException if an error occurs walking the scheduler tree.
- */
- protected List<JobLocation> getAllScheduledJobs(Transaction tx) throws IOException {
- List<JobLocation> references = new ArrayList<JobLocation>();
-
- for (Iterator<Map.Entry<Long, List<JobLocation>>> i = this.index.iterator(tx); i.hasNext();) {
- Map.Entry<Long, List<JobLocation>> entry = i.next();
- List<JobLocation> scheduled = entry.getValue();
- for (JobLocation job : scheduled) {
- references.add(job);
- }
+ void fireJob(JobLocation job) throws IllegalStateException, IOException {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Firing " + job);
+ }
+ ByteSequence bs = this.store.getPayload(job.getLocation());
+ for (JobListener l : jobListeners) {
+ l.scheduledJob(job.getJobId(), bs);
}
-
- return references;
}
@Override
@@ -673,14 +492,14 @@ public class JobSchedulerImpl extends ServiceSupport implements Runnable, JobSch
mainLoop();
} catch (Throwable e) {
if (this.running.get() && isStarted()) {
- LOG.error("{} Caught exception in mainloop", this, e);
+ LOG.error(this + " Caught exception in mainloop", e);
}
} finally {
if (running.get()) {
try {
stop();
} catch (Exception e) {
- LOG.error("Failed to stop {}", this);
+ LOG.error("Failed to stop " + this);
}
}
}
@@ -688,55 +507,56 @@ public class JobSchedulerImpl extends ServiceSupport implements Runnable, JobSch
@Override
public String toString() {
- return "JobScheduler: " + this.name;
+ return "JobScheduler:" + this.name;
}
protected void mainLoop() {
while (this.running.get()) {
this.scheduleTime.clearNewJob();
try {
+ // peek the next job
long currentTime = System.currentTimeMillis();
- // Read the list of scheduled events and fire the jobs, reschedule repeating jobs as
- // needed before firing the job event.
+ // Read the list of scheduled events and fire the jobs. Once done with the batch
+ // remove all that were fired, and reschedule as needed.
Map.Entry<Long, List<JobLocation>> first = getNextToSchedule();
if (first != null) {
List<JobLocation> list = new ArrayList<JobLocation>(first.getValue());
- List<JobLocation> toRemove = new ArrayList<JobLocation>(list.size());
+ List<JobLocation> fired = new ArrayList<JobLocation>(list.size());
final long executionTime = first.getKey();
long nextExecutionTime = 0;
if (executionTime <= currentTime) {
for (final JobLocation job : list) {
-
- if (!running.get()) {
- break;
- }
-
int repeat = job.getRepeat();
nextExecutionTime = calculateNextExecutionTime(job, currentTime, repeat);
long waitTime = nextExecutionTime - currentTime;
this.scheduleTime.setWaitTime(waitTime);
- if (!job.isCron()) {
+ if (job.isCron() == false) {
fireJob(job);
if (repeat != 0) {
- // Reschedule for the next time, the scheduler will take care of
- // updating the repeat counter on the update.
- doReschedule(job.getJobId(), executionTime, nextExecutionTime, job.getRescheduledCount() + 1);
+ repeat--;
+ job.setRepeat(repeat);
+ // remove this job from the index so it doesn't get destroyed
+ removeFromIndex(executionTime, job.getJobId());
+ // and re-store it
+ storeJob(job, nextExecutionTime);
} else {
- toRemove.add(job);
+ fired.add(job);
}
} else {
+ // cron job will have a repeat time.
if (repeat == 0) {
- // This is a non-repeating Cron entry so we can fire and forget it.
+ // we haven't got a separate scheduler to execute at
+ // this time - just a cron job - so fire it
fireJob(job);
}
if (nextExecutionTime > currentTime) {
- // Reschedule the cron job as a new event, if the cron entry signals
- // a repeat then it will be stored separately and fired as a normal
- // event with decrementing repeat.
- doReschedule(job.getJobId(), executionTime, nextExecutionTime, job.getRescheduledCount() + 1);
-
+ // we will run again ...
+ // remove this job from the index - so it doesn't get destroyed
+ removeFromIndex(executionTime, job.getJobId());
+ // and re-store it
+ storeJob(job, nextExecutionTime);
if (repeat != 0) {
// we have a separate schedule to run at this time
// so the cron job is used to set of a separate schedule
@@ -749,14 +569,14 @@ public class JobSchedulerImpl extends ServiceSupport implements Runnable, JobSch
this.scheduleTime.setWaitTime(waitTime);
}
} else {
- toRemove.add(job);
+ fired.add(job);
}
}
}
// now remove all jobs that have not been rescheduled from this execution
// time, if there are no more entries in that time it will be removed.
- doRemove(executionTime, toRemove);
+ remove(executionTime, fired);
// If there is a job that should fire before the currently set wait time
// we need to reset wait time otherwise we'll miss it.
@@ -768,30 +588,25 @@ public class JobSchedulerImpl extends ServiceSupport implements Runnable, JobSch
}
}
} else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Not yet time to execute the job, waiting " + (executionTime - currentTime) + " ms");
+ }
this.scheduleTime.setWaitTime(executionTime - currentTime);
}
}
this.scheduleTime.pause();
} catch (Exception ioe) {
- LOG.error("{} Failed to schedule job", this.name, ioe);
+ LOG.error(this.name + " Failed to schedule job", ioe);
try {
this.store.stop();
} catch (Exception e) {
- LOG.error("{} Failed to shutdown JobSchedulerStore", this.name, e);
+ LOG.error(this.name + " Failed to shutdown JobSchedulerStore", e);
}
}
}
}
- void fireJob(JobLocation job) throws IllegalStateException, IOException {
- LOG.debug("Firing: {}", job);
- ByteSequence bs = this.store.getPayload(job.getLocation());
- for (JobListener l : jobListeners) {
- l.scheduledJob(job.getJobId(), bs);
- }
- }
-
@Override
public void startDispatching() throws Exception {
if (!this.running.get()) {
@@ -812,7 +627,7 @@ public class JobSchedulerImpl extends ServiceSupport implements Runnable, JobSch
Thread t = this.thread;
this.thread = null;
if (t != null) {
- t.join(3000);
+ t.join(1000);
}
}
}
@@ -828,10 +643,6 @@ public class JobSchedulerImpl extends ServiceSupport implements Runnable, JobSch
stopDispatching();
}
- private ByteSequence getPayload(Location location) throws IllegalStateException, IOException {
- return this.store.getPayload(location);
- }
-
long calculateNextExecutionTime(final JobLocation job, long currentTime, int repeat) throws MessageFormatException {
long result = currentTime;
String cron = job.getCronEntry();
@@ -849,7 +660,7 @@ public class JobSchedulerImpl extends ServiceSupport implements Runnable, JobSch
void load(Transaction tx) throws IOException {
this.index.setKeyMarshaller(LongMarshaller.INSTANCE);
- this.index.setValueMarshaller(JobLocationsMarshaller.INSTANCE);
+ this.index.setValueMarshaller(ValueMarshaller.INSTANCE);
this.index.load(tx);
}
@@ -857,7 +668,7 @@ public class JobSchedulerImpl extends ServiceSupport implements Runnable, JobSch
this.name = in.readUTF();
this.index = new BTreeIndex<Long, List<JobLocation>>(this.store.getPageFile(), in.readLong());
this.index.setKeyMarshaller(LongMarshaller.INSTANCE);
- this.index.setValueMarshaller(JobLocationsMarshaller.INSTANCE);
+ this.index.setValueMarshaller(ValueMarshaller.INSTANCE);
}
public void write(DataOutput out) throws IOException {
@@ -865,6 +676,30 @@ public class JobSchedulerImpl extends ServiceSupport implements Runnable, JobSch
out.writeLong(this.index.getPageId());
}
+ static class ValueMarshaller extends VariableMarshaller<List<JobLocation>> {
+ static ValueMarshaller INSTANCE = new ValueMarshaller();
+
+ @Override
+ public List<JobLocation> readPayload(DataInput dataIn) throws IOException {
+ List<JobLocation> result = new ArrayList<JobLocation>();
+ int size = dataIn.readInt();
+ for (int i = 0; i < size; i++) {
+ JobLocation jobLocation = new JobLocation();
+ jobLocation.readExternal(dataIn);
+ result.add(jobLocation);
+ }
+ return result;
+ }
+
+ @Override
+ public void writePayload(List<JobLocation> value, DataOutput dataOut) throws IOException {
+ dataOut.writeInt(value.size());
+ for (JobLocation jobLocation : value) {
+ jobLocation.writeExternal(dataOut);
+ }
+ }
+ }
+
static class ScheduleTime {
private final int DEFAULT_WAIT = 500;
private final int DEFAULT_NEW_JOB_WAIT = 100;
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobSchedulerKahaDBMetaData.java
----------------------------------------------------------------------
diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobSchedulerKahaDBMetaData.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobSchedulerKahaDBMetaData.java
deleted file mode 100644
index c92dc7b..0000000
--- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobSchedulerKahaDBMetaData.java
+++ /dev/null
@@ -1,246 +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.store.kahadb.scheduler;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.UUID;
-
-import org.apache.activemq.store.kahadb.AbstractKahaDBMetaData;
-import org.apache.activemq.store.kahadb.disk.index.BTreeIndex;
-import org.apache.activemq.store.kahadb.disk.page.Transaction;
-import org.apache.activemq.store.kahadb.disk.util.IntegerMarshaller;
-import org.apache.activemq.store.kahadb.disk.util.LocationMarshaller;
-import org.apache.activemq.store.kahadb.disk.util.StringMarshaller;
-import org.apache.activemq.store.kahadb.disk.util.VariableMarshaller;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The KahaDB MetaData used to house the Index data for the KahaDB implementation
- * of a JobSchedulerStore.
- */
-public class JobSchedulerKahaDBMetaData extends AbstractKahaDBMetaData<JobSchedulerKahaDBMetaData> {
-
- static final Logger LOG = LoggerFactory.getLogger(JobSchedulerKahaDBMetaData.class);
-
- private final JobSchedulerStoreImpl store;
-
- private UUID token = JobSchedulerStoreImpl.SCHEDULER_STORE_TOKEN;
- private int version = JobSchedulerStoreImpl.CURRENT_VERSION;
-
- private BTreeIndex<Integer, List<Integer>> removeLocationTracker;
- private BTreeIndex<Integer, Integer> journalRC;
- private BTreeIndex<String, JobSchedulerImpl> storedSchedulers;
-
- /**
- * Creates a new instance of this meta data object with the assigned
- * parent JobSchedulerStore instance.
- *
- * @param store
- * the store instance that owns this meta data.
- */
- public JobSchedulerKahaDBMetaData(JobSchedulerStoreImpl store) {
- this.store = store;
- }
-
- /**
- * @return the current value of the Scheduler store identification token.
- */
- public UUID getToken() {
- return this.token;
- }
-
- /**
- * @return the current value of the version tag for this meta data instance.
- */
- public int getVersion() {
- return this.version;
- }
-
- /**
- * Gets the index that contains the location tracking information for Jobs
- * that have been removed from the index but whose add operation has yet
- * to be removed from the Journal.
- *
- * The Journal log file where a remove command is written cannot be released
- * until the log file with the original add command has also been released,
- * otherwise on a log replay the scheduled job could reappear in the scheduler
- * since its corresponding remove might no longer be present.
- *
- * @return the remove command location tracker index.
- */
- public BTreeIndex<Integer, List<Integer>> getRemoveLocationTracker() {
- return this.removeLocationTracker;
- }
-
- /**
- * Gets the index used to track the number of reference to a Journal log file.
- *
- * A log file in the Journal can only be considered for removal after all the
- * references to it have been released.
- *
- * @return the journal log file reference counter index.
- */
- public BTreeIndex<Integer, Integer> getJournalRC() {
- return this.journalRC;
- }
-
- /**
- * Gets the index of JobScheduler instances that have been created and stored
- * in the JobSchedulerStore instance.
- *
- * @return the index of stored JobScheduler instances.
- */
- public BTreeIndex<String, JobSchedulerImpl> getJobSchedulers() {
- return this.storedSchedulers;
- }
-
- @Override
- public void initialize(Transaction tx) throws IOException {
- this.storedSchedulers = new BTreeIndex<String, JobSchedulerImpl>(store.getPageFile(), tx.allocate().getPageId());
- this.journalRC = new BTreeIndex<Integer, Integer>(store.getPageFile(), tx.allocate().getPageId());
- this.removeLocationTracker = new BTreeIndex<Integer, List<Integer>>(store.getPageFile(), tx.allocate().getPageId());
- }
-
- @Override
- public void load(Transaction tx) throws IOException {
- this.storedSchedulers.setKeyMarshaller(StringMarshaller.INSTANCE);
- this.storedSchedulers.setValueMarshaller(new JobSchedulerMarshaller(this.store));
- this.storedSchedulers.load(tx);
- this.journalRC.setKeyMarshaller(IntegerMarshaller.INSTANCE);
- this.journalRC.setValueMarshaller(IntegerMarshaller.INSTANCE);
- this.journalRC.load(tx);
- this.removeLocationTracker.setKeyMarshaller(IntegerMarshaller.INSTANCE);
- this.removeLocationTracker.setValueMarshaller(new IntegerListMarshaller());
- this.removeLocationTracker.load(tx);
- }
-
- /**
- * Loads all the stored JobScheduler instances into the provided map.
- *
- * @param tx
- * the Transaction under which the load operation should be executed.
- * @param schedulers
- * a Map<String, JobSchedulerImpl> into which the loaded schedulers are stored.
- *
- * @throws IOException if an error occurs while performing the load operation.
- */
- public void loadScheduler(Transaction tx, Map<String, JobSchedulerImpl> schedulers) throws IOException {
- for (Iterator<Entry<String, JobSchedulerImpl>> i = this.storedSchedulers.iterator(tx); i.hasNext();) {
- Entry<String, JobSchedulerImpl> entry = i.next();
- entry.getValue().load(tx);
- schedulers.put(entry.getKey(), entry.getValue());
- }
- }
-
- @Override
- public void read(DataInput in) throws IOException {
- try {
- long msb = in.readLong();
- long lsb = in.readLong();
- this.token = new UUID(msb, lsb);
- } catch (Exception e) {
- throw new UnknownStoreVersionException(e);
- }
-
- if (!token.equals(JobSchedulerStoreImpl.SCHEDULER_STORE_TOKEN)) {
- throw new UnknownStoreVersionException(token.toString());
- }
- this.version = in.readInt();
- if (in.readBoolean()) {
- setLastUpdateLocation(LocationMarshaller.INSTANCE.readPayload(in));
- } else {
- setLastUpdateLocation(null);
- }
- this.storedSchedulers = new BTreeIndex<String, JobSchedulerImpl>(store.getPageFile(), in.readLong());
- this.storedSchedulers.setKeyMarshaller(StringMarshaller.INSTANCE);
- this.storedSchedulers.setValueMarshaller(new JobSchedulerMarshaller(this.store));
- this.journalRC = new BTreeIndex<Integer, Integer>(store.getPageFile(), in.readLong());
- this.journalRC.setKeyMarshaller(IntegerMarshaller.INSTANCE);
- this.journalRC.setValueMarshaller(IntegerMarshaller.INSTANCE);
- this.removeLocationTracker = new BTreeIndex<Integer, List<Integer>>(store.getPageFile(), in.readLong());
- this.removeLocationTracker.setKeyMarshaller(IntegerMarshaller.INSTANCE);
- this.removeLocationTracker.setValueMarshaller(new IntegerListMarshaller());
-
- LOG.info("Scheduler Store version {} loaded", this.version);
- }
-
- @Override
- public void write(DataOutput out) throws IOException {
- out.writeLong(this.token.getMostSignificantBits());
- out.writeLong(this.token.getLeastSignificantBits());
- out.writeInt(this.version);
- if (getLastUpdateLocation() != null) {
- out.writeBoolean(true);
- LocationMarshaller.INSTANCE.writePayload(getLastUpdateLocation(), out);
- } else {
- out.writeBoolean(false);
- }
- out.writeLong(this.storedSchedulers.getPageId());
- out.writeLong(this.journalRC.getPageId());
- out.writeLong(this.removeLocationTracker.getPageId());
- }
-
- private class JobSchedulerMarshaller extends VariableMarshaller<JobSchedulerImpl> {
- private final JobSchedulerStoreImpl store;
-
- JobSchedulerMarshaller(JobSchedulerStoreImpl store) {
- this.store = store;
- }
-
- @Override
- public JobSchedulerImpl readPayload(DataInput dataIn) throws IOException {
- JobSchedulerImpl result = new JobSchedulerImpl(this.store);
- result.read(dataIn);
- return result;
- }
-
- @Override
- public void writePayload(JobSchedulerImpl js, DataOutput dataOut) throws IOException {
- js.write(dataOut);
- }
- }
-
- private class IntegerListMarshaller extends VariableMarshaller<List<Integer>> {
-
- @Override
- public List<Integer> readPayload(DataInput dataIn) throws IOException {
- List<Integer> result = new ArrayList<Integer>();
- int size = dataIn.readInt();
- for (int i = 0; i < size; i++) {
- result.add(IntegerMarshaller.INSTANCE.readPayload(dataIn));
- }
- return result;
- }
-
- @Override
- public void writePayload(List<Integer> value, DataOutput dataOut) throws IOException {
- dataOut.writeInt(value.size());
- for (Integer integer : value) {
- IntegerMarshaller.INSTANCE.writePayload(integer, dataOut);
- }
- }
- }
-}
[2/5] activemq git commit: Revert
"https://issues.apache.org/jira/browse/AMQ-3758"
Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobSchedulerStoreImpl.java
----------------------------------------------------------------------
diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobSchedulerStoreImpl.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobSchedulerStoreImpl.java
index 1a08931..5934914 100644
--- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobSchedulerStoreImpl.java
+++ b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobSchedulerStoreImpl.java
@@ -19,10 +19,8 @@ package org.apache.activemq.store.kahadb.scheduler;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.File;
-import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -30,917 +28,363 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-import java.util.TreeSet;
-import java.util.UUID;
+import java.util.concurrent.atomic.AtomicLong;
+import org.apache.activemq.broker.LockableServiceSupport;
+import org.apache.activemq.broker.Locker;
import org.apache.activemq.broker.scheduler.JobScheduler;
import org.apache.activemq.broker.scheduler.JobSchedulerStore;
-import org.apache.activemq.protobuf.Buffer;
-import org.apache.activemq.store.kahadb.AbstractKahaDBStore;
-import org.apache.activemq.store.kahadb.JournalCommand;
-import org.apache.activemq.store.kahadb.KahaDBMetaData;
-import org.apache.activemq.store.kahadb.Visitor;
-import org.apache.activemq.store.kahadb.data.KahaAddScheduledJobCommand;
-import org.apache.activemq.store.kahadb.data.KahaDestroySchedulerCommand;
-import org.apache.activemq.store.kahadb.data.KahaRemoveScheduledJobCommand;
-import org.apache.activemq.store.kahadb.data.KahaRemoveScheduledJobsCommand;
-import org.apache.activemq.store.kahadb.data.KahaRescheduleJobCommand;
-import org.apache.activemq.store.kahadb.data.KahaTraceCommand;
-import org.apache.activemq.store.kahadb.disk.index.BTreeVisitor;
-import org.apache.activemq.store.kahadb.disk.journal.DataFile;
+import org.apache.activemq.store.SharedFileLocker;
+import org.apache.activemq.store.kahadb.disk.index.BTreeIndex;
+import org.apache.activemq.store.kahadb.disk.journal.Journal;
import org.apache.activemq.store.kahadb.disk.journal.Location;
import org.apache.activemq.store.kahadb.disk.page.Page;
import org.apache.activemq.store.kahadb.disk.page.PageFile;
import org.apache.activemq.store.kahadb.disk.page.Transaction;
+import org.apache.activemq.store.kahadb.disk.util.IntegerMarshaller;
+import org.apache.activemq.store.kahadb.disk.util.StringMarshaller;
import org.apache.activemq.store.kahadb.disk.util.VariableMarshaller;
-import org.apache.activemq.store.kahadb.scheduler.legacy.LegacyStoreReplayer;
import org.apache.activemq.util.ByteSequence;
import org.apache.activemq.util.IOHelper;
+import org.apache.activemq.util.ServiceStopper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class JobSchedulerStoreImpl extends AbstractKahaDBStore implements JobSchedulerStore {
-
- private static final Logger LOG = LoggerFactory.getLogger(JobSchedulerStoreImpl.class);
-
- private JobSchedulerKahaDBMetaData metaData = new JobSchedulerKahaDBMetaData(this);
- private final MetaDataMarshaller metaDataMarshaller = new MetaDataMarshaller(this);
- private final Map<String, JobSchedulerImpl> schedulers = new HashMap<String, JobSchedulerImpl>();
- private File legacyStoreArchiveDirectory;
-
- /**
- * The Scheduler Token is used to identify base revisions of the Scheduler store. A store
- * based on the initial scheduler design will not have this tag in it's meta-data and will
- * indicate an update is needed. Later versions of the scheduler can also change this value
- * to indicate incompatible store bases which require complete meta-data and journal rewrites
- * instead of simpler meta-data updates.
- */
- static final UUID SCHEDULER_STORE_TOKEN = UUID.fromString("57ed642b-1ee3-47b3-be6d-b7297d500409");
-
- /**
- * The default scheduler store version. All new store instance will be given this version and
- * earlier versions will be updated to this version.
- */
- static final int CURRENT_VERSION = 1;
-
- @Override
- public JobScheduler getJobScheduler(final String name) throws Exception {
- this.indexLock.writeLock().lock();
- try {
- JobSchedulerImpl result = this.schedulers.get(name);
- if (result == null) {
- final JobSchedulerImpl js = new JobSchedulerImpl(this);
- js.setName(name);
- getPageFile().tx().execute(new Transaction.Closure<IOException>() {
- @Override
- public void execute(Transaction tx) throws IOException {
- js.createIndexes(tx);
- js.load(tx);
- metaData.getJobSchedulers().put(tx, name, js);
- }
- });
- result = js;
- this.schedulers.put(name, js);
- if (isStarted()) {
- result.start();
- }
- this.pageFile.flush();
- }
- return result;
- } finally {
- this.indexLock.writeLock().unlock();
+public class JobSchedulerStoreImpl extends LockableServiceSupport implements JobSchedulerStore {
+ static final Logger LOG = LoggerFactory.getLogger(JobSchedulerStoreImpl.class);
+ private static final int DATABASE_LOCKED_WAIT_DELAY = 10 * 1000;
+
+ public static final int CLOSED_STATE = 1;
+ public static final int OPEN_STATE = 2;
+
+ private File directory;
+ PageFile pageFile;
+ private Journal journal;
+ protected AtomicLong journalSize = new AtomicLong(0);
+ private boolean failIfDatabaseIsLocked;
+ private int journalMaxFileLength = Journal.DEFAULT_MAX_FILE_LENGTH;
+ private int journalMaxWriteBatchSize = Journal.DEFAULT_MAX_WRITE_BATCH_SIZE;
+ private boolean enableIndexWriteAsync = false;
+ MetaData metaData = new MetaData(this);
+ final MetaDataMarshaller metaDataMarshaller = new MetaDataMarshaller(this);
+ Map<String, JobSchedulerImpl> schedulers = new HashMap<String, JobSchedulerImpl>();
+
+ protected class MetaData {
+ protected MetaData(JobSchedulerStoreImpl store) {
+ this.store = store;
}
- }
- @Override
- public boolean removeJobScheduler(final String name) throws Exception {
- boolean result = false;
+ private final JobSchedulerStoreImpl store;
+ Page<MetaData> page;
+ BTreeIndex<Integer, Integer> journalRC;
+ BTreeIndex<String, JobSchedulerImpl> storedSchedulers;
- this.indexLock.writeLock().lock();
- try {
- final JobSchedulerImpl js = this.schedulers.remove(name);
- result = js != null;
- if (result) {
- js.stop();
- getPageFile().tx().execute(new Transaction.Closure<IOException>() {
- @Override
- public void execute(Transaction tx) throws IOException {
- metaData.getJobSchedulers().remove(tx, name);
- js.removeAll(tx);
- }
- });
- }
- } finally {
- this.indexLock.writeLock().unlock();
+ void createIndexes(Transaction tx) throws IOException {
+ this.storedSchedulers = new BTreeIndex<String, JobSchedulerImpl>(pageFile, tx.allocate().getPageId());
+ this.journalRC = new BTreeIndex<Integer, Integer>(pageFile, tx.allocate().getPageId());
}
- return result;
- }
-
- /**
- * Sets the directory where the legacy scheduler store files are archived before an
- * update attempt is made. Both the legacy index files and the journal files are moved
- * to this folder prior to an upgrade attempt.
- *
- * @param directory
- * The directory to move the legacy Scheduler Store files to.
- */
- public void setLegacyStoreArchiveDirectory(File directory) {
- this.legacyStoreArchiveDirectory = directory;
- }
- /**
- * Gets the directory where the legacy Scheduler Store files will be archived if the
- * broker is started and an existing Job Scheduler Store from an old version is detected.
- *
- * @return the directory where scheduler store legacy files are archived on upgrade.
- */
- public File getLegacyStoreArchiveDirectory() {
- if (this.legacyStoreArchiveDirectory == null) {
- this.legacyStoreArchiveDirectory = new File(getDirectory(), "legacySchedulerStore");
+ void load(Transaction tx) throws IOException {
+ this.storedSchedulers.setKeyMarshaller(StringMarshaller.INSTANCE);
+ this.storedSchedulers.setValueMarshaller(new JobSchedulerMarshaller(this.store));
+ this.storedSchedulers.load(tx);
+ this.journalRC.setKeyMarshaller(IntegerMarshaller.INSTANCE);
+ this.journalRC.setValueMarshaller(IntegerMarshaller.INSTANCE);
+ this.journalRC.load(tx);
}
- return this.legacyStoreArchiveDirectory.getAbsoluteFile();
- }
-
- @Override
- public void load() throws IOException {
- if (opened.compareAndSet(false, true)) {
- getJournal().start();
- try {
- loadPageFile();
- } catch (UnknownStoreVersionException ex) {
- LOG.info("Can't start until store update is performed.");
- upgradeFromLegacy();
- // Restart with the updated store
- getJournal().start();
- loadPageFile();
- LOG.info("Update from legacy Scheduler store completed successfully.");
- } catch (Throwable t) {
- LOG.warn("Index corrupted. Recovering the index through journal replay. Cause: {}", t.toString());
- LOG.debug("Index load failure", t);
-
- // try to recover index
- try {
- pageFile.unload();
- } catch (Exception ignore) {
- }
- if (isArchiveCorruptedIndex()) {
- pageFile.archive();
- } else {
- pageFile.delete();
- }
- metaData = new JobSchedulerKahaDBMetaData(this);
- pageFile = null;
- loadPageFile();
+ void loadScheduler(Transaction tx, Map<String, JobSchedulerImpl> schedulers) throws IOException {
+ for (Iterator<Entry<String, JobSchedulerImpl>> i = this.storedSchedulers.iterator(tx); i.hasNext();) {
+ Entry<String, JobSchedulerImpl> entry = i.next();
+ entry.getValue().load(tx);
+ schedulers.put(entry.getKey(), entry.getValue());
}
- startCheckpoint();
- recover();
}
- LOG.info("{} started.", this);
- }
-
- @Override
- public void unload() throws IOException {
- if (opened.compareAndSet(true, false)) {
- for (JobSchedulerImpl js : this.schedulers.values()) {
- try {
- js.stop();
- } catch (Exception e) {
- throw new IOException(e);
- }
- }
- this.indexLock.writeLock().lock();
- try {
- if (pageFile != null && pageFile.isLoaded()) {
- metaData.setState(KahaDBMetaData.CLOSED_STATE);
-
- if (metaData.getPage() != null) {
- pageFile.tx().execute(new Transaction.Closure<IOException>() {
- @Override
- public void execute(Transaction tx) throws IOException {
- tx.store(metaData.getPage(), metaDataMarshaller, true);
- }
- });
- }
- }
- } finally {
- this.indexLock.writeLock().unlock();
- }
- checkpointLock.writeLock().lock();
- try {
- if (metaData.getPage() != null) {
- checkpointUpdate(true);
- }
- } finally {
- checkpointLock.writeLock().unlock();
- }
- synchronized (checkpointThreadLock) {
- if (checkpointThread != null) {
- try {
- checkpointThread.join();
- checkpointThread = null;
- } catch (InterruptedException e) {
- }
- }
- }
-
- if (pageFile != null) {
- pageFile.unload();
- pageFile = null;
- }
- if (this.journal != null) {
- journal.close();
- journal = null;
- }
-
- metaData = new JobSchedulerKahaDBMetaData(this);
+ public void read(DataInput is) throws IOException {
+ this.storedSchedulers = new BTreeIndex<String, JobSchedulerImpl>(pageFile, is.readLong());
+ this.storedSchedulers.setKeyMarshaller(StringMarshaller.INSTANCE);
+ this.storedSchedulers.setValueMarshaller(new JobSchedulerMarshaller(this.store));
+ this.journalRC = new BTreeIndex<Integer, Integer>(pageFile, is.readLong());
+ this.journalRC.setKeyMarshaller(IntegerMarshaller.INSTANCE);
+ this.journalRC.setValueMarshaller(IntegerMarshaller.INSTANCE);
}
- LOG.info("{} stopped.", this);
- }
- private void loadPageFile() throws IOException {
- this.indexLock.writeLock().lock();
- try {
- final PageFile pageFile = getPageFile();
- pageFile.load();
- pageFile.tx().execute(new Transaction.Closure<IOException>() {
- @Override
- public void execute(Transaction tx) throws IOException {
- if (pageFile.getPageCount() == 0) {
- Page<JobSchedulerKahaDBMetaData> page = tx.allocate();
- assert page.getPageId() == 0;
- page.set(metaData);
- metaData.setPage(page);
- metaData.setState(KahaDBMetaData.CLOSED_STATE);
- metaData.initialize(tx);
- tx.store(metaData.getPage(), metaDataMarshaller, true);
- } else {
- Page<JobSchedulerKahaDBMetaData> page = null;
- page = tx.load(0, metaDataMarshaller);
- metaData = page.get();
- metaData.setPage(page);
- }
- metaData.load(tx);
- metaData.loadScheduler(tx, schedulers);
- for (JobSchedulerImpl js : schedulers.values()) {
- try {
- js.start();
- } catch (Exception e) {
- JobSchedulerStoreImpl.LOG.error("Failed to load " + js.getName(), e);
- }
- }
- }
- });
-
- pageFile.flush();
- } finally {
- this.indexLock.writeLock().unlock();
+ public void write(DataOutput os) throws IOException {
+ os.writeLong(this.storedSchedulers.getPageId());
+ os.writeLong(this.journalRC.getPageId());
}
}
- private void upgradeFromLegacy() throws IOException {
-
- journal.close();
- journal = null;
- try {
- pageFile.unload();
- pageFile = null;
- } catch (Exception ignore) {}
-
- File storeDir = getDirectory().getAbsoluteFile();
- File storeArchiveDir = getLegacyStoreArchiveDirectory();
-
- LOG.info("Attempting to move old store files from {} to {}", storeDir, storeArchiveDir);
-
- // Move only the known store files, locks and other items left in place.
- IOHelper.moveFiles(storeDir, storeArchiveDir, new FilenameFilter() {
-
- @Override
- public boolean accept(File dir, String name) {
- if (name.endsWith(".data") || name.endsWith(".redo") || name.endsWith(".log")) {
- return true;
- }
- return false;
- }
- });
-
- // We reset everything to clean state, then we can read from the old
- // scheduler store and replay the scheduled jobs into this one as adds.
- getJournal().start();
- metaData = new JobSchedulerKahaDBMetaData(this);
- pageFile = null;
- loadPageFile();
-
- LegacyStoreReplayer replayer = new LegacyStoreReplayer(getLegacyStoreArchiveDirectory());
- replayer.load();
- replayer.startReplay(this);
-
- // Cleanup after replay and store what we've done.
- pageFile.tx().execute(new Transaction.Closure<IOException>() {
- @Override
- public void execute(Transaction tx) throws IOException {
- tx.store(metaData.getPage(), metaDataMarshaller, true);
- }
- });
-
- checkpointUpdate(true);
- getJournal().close();
- getPageFile().unload();
- }
-
- @Override
- protected void checkpointUpdate(Transaction tx, boolean cleanup) throws IOException {
- LOG.debug("Job Scheduler Store Checkpoint started.");
-
- // reflect last update exclusive of current checkpoint
- Location lastUpdate = metaData.getLastUpdateLocation();
- metaData.setState(KahaDBMetaData.OPEN_STATE);
- tx.store(metaData.getPage(), metaDataMarshaller, true);
- pageFile.flush();
-
- if (cleanup) {
- final TreeSet<Integer> completeFileSet = new TreeSet<Integer>(journal.getFileMap().keySet());
- final TreeSet<Integer> gcCandidateSet = new TreeSet<Integer>(completeFileSet);
-
- LOG.trace("Last update: {}, full gc candidates set: {}", lastUpdate, gcCandidateSet);
-
- if (lastUpdate != null) {
- gcCandidateSet.remove(lastUpdate.getDataFileId());
- }
-
- this.metaData.getJournalRC().visit(tx, new BTreeVisitor<Integer, Integer>() {
-
- @Override
- public void visit(List<Integer> keys, List<Integer> values) {
- for (Integer key : keys) {
- if (gcCandidateSet.remove(key)) {
- LOG.trace("Removed referenced file: {} from GC set", key);
- }
- }
- }
-
- @Override
- public boolean isInterestedInKeysBetween(Integer first, Integer second) {
- return true;
- }
- });
-
- LOG.trace("gc candidates after reference check: {}", gcCandidateSet);
-
- // If there are GC candidates then check the remove command location to see
- // if any of them can go or if they must stay in order to ensure proper recover.
- //
- // A log containing any remove commands must be kept until all the logs with the
- // add commands for all the removed jobs have been dropped.
- if (!gcCandidateSet.isEmpty()) {
- Iterator<Entry<Integer, List<Integer>>> removals = metaData.getRemoveLocationTracker().iterator(tx);
- List<Integer> orphans = new ArrayList<Integer>();
- while (removals.hasNext()) {
- boolean orphanedRemve = true;
- Entry<Integer, List<Integer>> entry = removals.next();
-
- // If this log is not a GC candidate then there's no need to do a check to rule it out
- if (gcCandidateSet.contains(entry.getKey())) {
- for (Integer addLocation : entry.getValue()) {
- if (completeFileSet.contains(addLocation)) {
- orphanedRemve = false;
- break;
- }
- }
-
- // If it's not orphaned than we can't remove it, otherwise we
- // stop tracking it it's log will get deleted on the next check.
- if (!orphanedRemve) {
- LOG.trace("A remove in log {} has an add still in existance.", entry.getKey());
- gcCandidateSet.remove(entry.getKey());
- } else {
- LOG.trace("All removes in log {} are orphaned, file can be GC'd", entry.getKey());
- orphans.add(entry.getKey());
- }
- }
- }
-
- // Drop all orphaned removes from the tracker.
- for (Integer orphan : orphans) {
- metaData.getRemoveLocationTracker().remove(tx, orphan);
- }
- }
+ class MetaDataMarshaller extends VariableMarshaller<MetaData> {
+ private final JobSchedulerStoreImpl store;
- LOG.trace("gc candidates after removals check: {}", gcCandidateSet);
- if (!gcCandidateSet.isEmpty()) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Cleanup removing the data files: " + gcCandidateSet);
- }
- journal.removeDataFiles(gcCandidateSet);
- }
+ MetaDataMarshaller(JobSchedulerStoreImpl store) {
+ this.store = store;
}
- LOG.debug("Job Scheduler Store Checkpoint complete.");
- }
+ @Override
+ public MetaData readPayload(DataInput dataIn) throws IOException {
+ MetaData rc = new MetaData(this.store);
+ rc.read(dataIn);
+ return rc;
+ }
- /**
- * Adds a reference for the journal log file pointed to by the given Location value.
- *
- * To prevent log files in the journal that still contain valid data that needs to be
- * kept in order to allow for recovery the logs must have active references. Each Job
- * scheduler should ensure that the logs are accurately referenced.
- *
- * @param tx
- * The TX under which the update is to be performed.
- * @param location
- * The location value to update the reference count of.
- *
- * @throws IOException if an error occurs while updating the journal references table.
- */
- protected void incrementJournalCount(Transaction tx, Location location) throws IOException {
- int logId = location.getDataFileId();
- Integer val = metaData.getJournalRC().get(tx, logId);
- int refCount = val != null ? val.intValue() + 1 : 1;
- metaData.getJournalRC().put(tx, logId, refCount);
+ @Override
+ public void writePayload(MetaData object, DataOutput dataOut) throws IOException {
+ object.write(dataOut);
+ }
}
- /**
- * Removes one reference for the Journal log file indicated in the given Location value.
- *
- * The references are used to track which log files cannot be GC'd. When the reference count
- * on a log file reaches zero the file id is removed from the tracker and the log will be
- * removed on the next check point update.
- *
- * @param tx
- * The TX under which the update is to be performed.
- * @param location
- * The location value to update the reference count of.
- *
- * @throws IOException if an error occurs while updating the journal references table.
- */
- protected void decrementJournalCount(Transaction tx, Location location) throws IOException {
- int logId = location.getDataFileId();
- Integer refCount = metaData.getJournalRC().get(tx, logId);
- if (refCount != null) {
- int refCountValue = refCount;
- refCountValue--;
- if (refCountValue <= 0) {
- metaData.getJournalRC().remove(tx, logId);
- } else {
- metaData.getJournalRC().put(tx, logId, refCountValue);
+ class ValueMarshaller extends VariableMarshaller<List<JobLocation>> {
+ @Override
+ public List<JobLocation> readPayload(DataInput dataIn) throws IOException {
+ List<JobLocation> result = new ArrayList<JobLocation>();
+ int size = dataIn.readInt();
+ for (int i = 0; i < size; i++) {
+ JobLocation jobLocation = new JobLocation();
+ jobLocation.readExternal(dataIn);
+ result.add(jobLocation);
}
+ return result;
}
- }
- /**
- * Updates the Job removal tracking index with the location of a remove command and the
- * original JobLocation entry.
- *
- * The JobLocation holds the locations in the logs where the add and update commands for
- * a job stored. The log file containing the remove command can only be discarded after
- * both the add and latest update log files have also been discarded.
- *
- * @param tx
- * The TX under which the update is to be performed.
- * @param location
- * The location value to reference a remove command.
- * @param removedJob
- * The original JobLocation instance that holds the add and update locations
- *
- * @throws IOException if an error occurs while updating the remove location tracker.
- */
- protected void referenceRemovedLocation(Transaction tx, Location location, JobLocation removedJob) throws IOException {
- int logId = location.getDataFileId();
- List<Integer> removed = this.metaData.getRemoveLocationTracker().get(tx, logId);
- if (removed == null) {
- removed = new ArrayList<Integer>();
+ @Override
+ public void writePayload(List<JobLocation> value, DataOutput dataOut) throws IOException {
+ dataOut.writeInt(value.size());
+ for (JobLocation jobLocation : value) {
+ jobLocation.writeExternal(dataOut);
+ }
}
- removed.add(removedJob.getLocation().getDataFileId());
- this.metaData.getRemoveLocationTracker().put(tx, logId, removed);
- }
-
- /**
- * Retrieve the scheduled Job's byte blob from the journal.
- *
- * @param location
- * The location of the KahaAddScheduledJobCommand that originated the Job.
- *
- * @return a ByteSequence containing the payload of the scheduled Job.
- *
- * @throws IOException if an error occurs while reading the payload value.
- */
- protected ByteSequence getPayload(Location location) throws IOException {
- KahaAddScheduledJobCommand job = (KahaAddScheduledJobCommand) this.load(location);
- Buffer payload = job.getPayload();
- return new ByteSequence(payload.getData(), payload.getOffset(), payload.getLength());
- }
-
- public void readLockIndex() {
- this.indexLock.readLock().lock();
- }
-
- public void readUnlockIndex() {
- this.indexLock.readLock().unlock();
- }
-
- public void writeLockIndex() {
- this.indexLock.writeLock().lock();
- }
-
- public void writeUnlockIndex() {
- this.indexLock.writeLock().unlock();
- }
-
- @Override
- public String toString() {
- return "JobSchedulerStore: " + getDirectory();
- }
-
- @Override
- protected String getPageFileName() {
- return "scheduleDB";
- }
-
- @Override
- protected File getDefaultDataDirectory() {
- return new File(IOHelper.getDefaultDataDirectory(), "delayedDB");
}
- private class MetaDataMarshaller extends VariableMarshaller<JobSchedulerKahaDBMetaData> {
-
+ class JobSchedulerMarshaller extends VariableMarshaller<JobSchedulerImpl> {
private final JobSchedulerStoreImpl store;
- MetaDataMarshaller(JobSchedulerStoreImpl store) {
+ JobSchedulerMarshaller(JobSchedulerStoreImpl store) {
this.store = store;
}
@Override
- public JobSchedulerKahaDBMetaData readPayload(DataInput dataIn) throws IOException {
- JobSchedulerKahaDBMetaData rc = new JobSchedulerKahaDBMetaData(store);
- rc.read(dataIn);
- return rc;
+ public JobSchedulerImpl readPayload(DataInput dataIn) throws IOException {
+ JobSchedulerImpl result = new JobSchedulerImpl(this.store);
+ result.read(dataIn);
+ return result;
}
@Override
- public void writePayload(JobSchedulerKahaDBMetaData object, DataOutput dataOut) throws IOException {
- object.write(dataOut);
+ public void writePayload(JobSchedulerImpl js, DataOutput dataOut) throws IOException {
+ js.write(dataOut);
}
}
- /**
- * Called during index recovery to rebuild the index from the last known good location. For
- * entries that occur before the last known good position we just ignore then and move on.
- *
- * @param command
- * the command read from the Journal which should be used to update the index.
- * @param location
- * the location in the index where the command was read.
- * @param inDoubtlocation
- * the location in the index known to be the last time the index was valid.
- *
- * @throws IOException if an error occurs while recovering the index.
- */
- protected void doRecover(JournalCommand<?> data, final Location location, final Location inDoubtlocation) throws IOException {
- if (inDoubtlocation != null && location.compareTo(inDoubtlocation) >= 0) {
- process(data, location);
- }
+ @Override
+ public File getDirectory() {
+ return directory;
}
- /**
- * Called during recovery to allow the store to rebuild from scratch.
- *
- * @param data
- * The command to process, which was read from the Journal.
- * @param location
- * The location of the command in the Journal.
- *
- * @throws IOException if an error occurs during command processing.
- */
@Override
- protected void process(JournalCommand<?> data, final Location location) throws IOException {
- data.visit(new Visitor() {
- @Override
- public void visit(final KahaAddScheduledJobCommand command) throws IOException {
- final JobSchedulerImpl scheduler;
-
- indexLock.writeLock().lock();
- try {
- try {
- scheduler = (JobSchedulerImpl) getJobScheduler(command.getScheduler());
- } catch (Exception e) {
- throw new IOException(e);
- }
- getPageFile().tx().execute(new Transaction.Closure<IOException>() {
- @Override
- public void execute(Transaction tx) throws IOException {
- scheduler.process(tx, command, location);
- }
- });
-
- processLocation(location);
- } finally {
- indexLock.writeLock().unlock();
- }
- }
-
- @Override
- public void visit(final KahaRemoveScheduledJobCommand command) throws IOException {
- final JobSchedulerImpl scheduler;
-
- indexLock.writeLock().lock();
- try {
- try {
- scheduler = (JobSchedulerImpl) getJobScheduler(command.getScheduler());
- } catch (Exception e) {
- throw new IOException(e);
- }
- getPageFile().tx().execute(new Transaction.Closure<IOException>() {
- @Override
- public void execute(Transaction tx) throws IOException {
- scheduler.process(tx, command, location);
- }
- });
-
- processLocation(location);
- } finally {
- indexLock.writeLock().unlock();
- }
- }
-
- @Override
- public void visit(final KahaRemoveScheduledJobsCommand command) throws IOException {
- final JobSchedulerImpl scheduler;
-
- indexLock.writeLock().lock();
- try {
- try {
- scheduler = (JobSchedulerImpl) getJobScheduler(command.getScheduler());
- } catch (Exception e) {
- throw new IOException(e);
- }
- getPageFile().tx().execute(new Transaction.Closure<IOException>() {
- @Override
- public void execute(Transaction tx) throws IOException {
- scheduler.process(tx, command, location);
- }
- });
-
- processLocation(location);
- } finally {
- indexLock.writeLock().unlock();
- }
- }
-
- @Override
- public void visit(final KahaRescheduleJobCommand command) throws IOException {
- final JobSchedulerImpl scheduler;
-
- indexLock.writeLock().lock();
- try {
- try {
- scheduler = (JobSchedulerImpl) getJobScheduler(command.getScheduler());
- } catch (Exception e) {
- throw new IOException(e);
- }
- getPageFile().tx().execute(new Transaction.Closure<IOException>() {
- @Override
- public void execute(Transaction tx) throws IOException {
- scheduler.process(tx, command, location);
- }
- });
-
- processLocation(location);
- } finally {
- indexLock.writeLock().unlock();
- }
- }
-
- @Override
- public void visit(final KahaDestroySchedulerCommand command) {
- try {
- removeJobScheduler(command.getScheduler());
- } catch (Exception e) {
- LOG.warn("Failed to remove scheduler: {}", command.getScheduler());
- }
-
- processLocation(location);
- }
-
- @Override
- public void visit(KahaTraceCommand command) {
- processLocation(location);
- }
- });
+ public void setDirectory(File directory) {
+ this.directory = directory;
}
- protected void processLocation(final Location location) {
- indexLock.writeLock().lock();
+ @Override
+ public long size() {
+ if (!isStarted()) {
+ return 0;
+ }
try {
- this.metaData.setLastUpdateLocation(location);
- } finally {
- indexLock.writeLock().unlock();
+ return journalSize.get() + pageFile.getDiskSize();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
}
}
- /**
- * We recover from the Journal logs as needed to restore the index.
- *
- * @throws IllegalStateException
- * @throws IOException
- */
- private void recover() throws IllegalStateException, IOException {
- this.indexLock.writeLock().lock();
- try {
- long start = System.currentTimeMillis();
- Location lastIndoubtPosition = getRecoveryPosition();
- Location recoveryPosition = lastIndoubtPosition;
-
- if (recoveryPosition != null) {
- int redoCounter = 0;
- LOG.info("Recovering from the journal ...");
- while (recoveryPosition != null) {
- JournalCommand<?> message = load(recoveryPosition);
- metaData.setLastUpdateLocation(recoveryPosition);
- doRecover(message, recoveryPosition, lastIndoubtPosition);
- redoCounter++;
- recoveryPosition = journal.getNextLocation(recoveryPosition);
- if (LOG.isInfoEnabled() && redoCounter % 100000 == 0) {
- LOG.info("@ {}, {} entries recovered ..", recoveryPosition, redoCounter);
- }
+ @Override
+ public JobScheduler getJobScheduler(final String name) throws Exception {
+ JobSchedulerImpl result = this.schedulers.get(name);
+ if (result == null) {
+ final JobSchedulerImpl js = new JobSchedulerImpl(this);
+ js.setName(name);
+ getPageFile().tx().execute(new Transaction.Closure<IOException>() {
+ @Override
+ public void execute(Transaction tx) throws IOException {
+ js.createIndexes(tx);
+ js.load(tx);
+ metaData.storedSchedulers.put(tx, name, js);
}
- long end = System.currentTimeMillis();
- LOG.info("Recovery replayed {} operations from the journal in {} seconds.",
- redoCounter, ((end - start) / 1000.0f));
+ });
+ result = js;
+ this.schedulers.put(name, js);
+ if (isStarted()) {
+ result.start();
}
+ this.pageFile.flush();
+ }
+ return result;
+ }
- // We may have to undo some index updates.
- pageFile.tx().execute(new Transaction.Closure<IOException>() {
+ @Override
+ synchronized public boolean removeJobScheduler(final String name) throws Exception {
+ boolean result = false;
+ final JobSchedulerImpl js = this.schedulers.remove(name);
+ result = js != null;
+ if (result) {
+ js.stop();
+ getPageFile().tx().execute(new Transaction.Closure<IOException>() {
@Override
public void execute(Transaction tx) throws IOException {
- recoverIndex(tx);
+ metaData.storedSchedulers.remove(tx, name);
+ js.destroy(tx);
}
});
-
- } finally {
- this.indexLock.writeLock().unlock();
}
+ return result;
}
- private Location getRecoveryPosition() throws IOException {
- // This loads the first position and we completely rebuild the index if we
- // do not override it with some known recovery start location.
- Location result = null;
-
- if (!isForceRecoverIndex()) {
- if (metaData.getLastUpdateLocation() != null) {
- result = metaData.getLastUpdateLocation();
- }
+ @Override
+ protected synchronized void doStart() throws Exception {
+ if (this.directory == null) {
+ this.directory = new File(IOHelper.getDefaultDataDirectory() + File.pathSeparator + "delayedDB");
}
+ IOHelper.mkdirs(this.directory);
+ this.journal = new Journal();
+ this.journal.setDirectory(directory);
+ this.journal.setMaxFileLength(getJournalMaxFileLength());
+ this.journal.setWriteBatchSize(getJournalMaxWriteBatchSize());
+ this.journal.setSizeAccumulator(this.journalSize);
+ this.journal.start();
+ this.pageFile = new PageFile(directory, "scheduleDB");
+ this.pageFile.setWriteBatchSize(1);
+ this.pageFile.load();
+
+ this.pageFile.tx().execute(new Transaction.Closure<IOException>() {
+ @Override
+ public void execute(Transaction tx) throws IOException {
+ if (pageFile.getPageCount() == 0) {
+ Page<MetaData> page = tx.allocate();
+ assert page.getPageId() == 0;
+ page.set(metaData);
+ metaData.page = page;
+ metaData.createIndexes(tx);
+ tx.store(metaData.page, metaDataMarshaller, true);
- return journal.getNextLocation(result);
- }
-
- private void recoverIndex(Transaction tx) throws IOException {
- long start = System.currentTimeMillis();
-
- // It is possible index updates got applied before the journal updates..
- // in that case we need to removed references to Jobs that are not in the journal
- final Location lastAppendLocation = journal.getLastAppendLocation();
- long undoCounter = 0;
-
- // Go through all the jobs in each scheduler and check if any are added after
- // the last appended location and remove those. For now we ignore the update
- // location since the scheduled job will update itself after the next fire and
- // a new update will replace any existing update.
- for (Iterator<Map.Entry<String, JobSchedulerImpl>> i = metaData.getJobSchedulers().iterator(tx); i.hasNext();) {
- Map.Entry<String, JobSchedulerImpl> entry = i.next();
- JobSchedulerImpl scheduler = entry.getValue();
-
- List<JobLocation> jobs = scheduler.getAllScheduledJobs(tx);
- for (JobLocation job : jobs) {
- if (job.getLocation().compareTo(lastAppendLocation) >= 0) {
- if (scheduler.removeJobAtTime(tx, job.getJobId(), job.getNextTime())) {
- LOG.trace("Removed Job past last appened in the journal: {}", job.getJobId());
- undoCounter++;
+ } else {
+ Page<MetaData> page = tx.load(0, metaDataMarshaller);
+ metaData = page.get();
+ metaData.page = page;
+ }
+ metaData.load(tx);
+ metaData.loadScheduler(tx, schedulers);
+ for (JobSchedulerImpl js : schedulers.values()) {
+ try {
+ js.start();
+ } catch (Exception e) {
+ JobSchedulerStoreImpl.LOG.error("Failed to load " + js.getName(), e);
}
}
}
- }
-
- if (undoCounter > 0) {
- // The rolled back operations are basically in flight journal writes. To avoid getting
- // these the end user should do sync writes to the journal.
- long end = System.currentTimeMillis();
- LOG.info("Rolled back {} messages from the index in {} seconds.", undoCounter, ((end - start) / 1000.0f));
- undoCounter = 0;
- }
-
- // Now we check for missing and corrupt journal files.
+ });
- // 1. Collect the set of all referenced journal files based on the Location of the
- // the scheduled jobs and the marked last update field.
- HashSet<Integer> missingJournalFiles = new HashSet<Integer>();
- for (Iterator<Map.Entry<String, JobSchedulerImpl>> i = metaData.getJobSchedulers().iterator(tx); i.hasNext();) {
- Map.Entry<String, JobSchedulerImpl> entry = i.next();
- JobSchedulerImpl scheduler = entry.getValue();
+ this.pageFile.flush();
+ LOG.info(this + " started");
+ }
- List<JobLocation> jobs = scheduler.getAllScheduledJobs(tx);
- for (JobLocation job : jobs) {
- missingJournalFiles.add(job.getLocation().getDataFileId());
- if (job.getLastUpdate() != null) {
- missingJournalFiles.add(job.getLastUpdate().getDataFileId());
- }
- }
+ @Override
+ protected synchronized void doStop(ServiceStopper stopper) throws Exception {
+ for (JobSchedulerImpl js : this.schedulers.values()) {
+ js.stop();
}
-
- // 2. Remove from that set all known data file Id's in the journal and what's left
- // is the missing set which will soon also contain the corrupted set.
- missingJournalFiles.removeAll(journal.getFileMap().keySet());
- if (!missingJournalFiles.isEmpty()) {
- LOG.info("Some journal files are missing: {}", missingJournalFiles);
+ if (this.pageFile != null) {
+ this.pageFile.unload();
}
+ if (this.journal != null) {
+ journal.close();
+ }
+ LOG.info(this + " stopped");
+ }
- // 3. Now check all references in the journal logs for corruption and add any
- // corrupt journal files to the missing set.
- HashSet<Location> corruptedLocations = new HashSet<Location>();
-
- if (isCheckForCorruptJournalFiles()) {
- Collection<DataFile> dataFiles = journal.getFileMap().values();
- for (DataFile dataFile : dataFiles) {
- int id = dataFile.getDataFileId();
- for (long offset : dataFile.getCorruptedBlocks()) {
- corruptedLocations.add(new Location(id, (int) offset));
- }
- }
+ synchronized void incrementJournalCount(Transaction tx, Location location) throws IOException {
+ int logId = location.getDataFileId();
+ Integer val = this.metaData.journalRC.get(tx, logId);
+ int refCount = val != null ? val.intValue() + 1 : 1;
+ this.metaData.journalRC.put(tx, logId, refCount);
+ }
- if (!corruptedLocations.isEmpty()) {
- LOG.debug("Found some corrupted data blocks in the journal: {}", corruptedLocations.size());
- }
+ synchronized void decrementJournalCount(Transaction tx, Location location) throws IOException {
+ int logId = location.getDataFileId();
+ int refCount = this.metaData.journalRC.get(tx, logId);
+ refCount--;
+ if (refCount <= 0) {
+ this.metaData.journalRC.remove(tx, logId);
+ Set<Integer> set = new HashSet<Integer>();
+ set.add(logId);
+ this.journal.removeDataFiles(set);
+ } else {
+ this.metaData.journalRC.put(tx, logId, refCount);
}
+ }
- // 4. Now we either fail or we remove all references to missing or corrupt journal
- // files from the various JobSchedulerImpl instances. We only remove the Job if
- // the initial Add operation is missing when the ignore option is set, the updates
- // could be lost but that's price you pay when ignoring the missing logs.
- if (!missingJournalFiles.isEmpty() || !corruptedLocations.isEmpty()) {
- if (!isIgnoreMissingJournalfiles()) {
- throw new IOException("Detected missing/corrupt journal files.");
- }
+ synchronized ByteSequence getPayload(Location location) throws IllegalStateException, IOException {
+ ByteSequence result = null;
+ result = this.journal.read(location);
+ return result;
+ }
- // Remove all Jobs that reference an Location that is either missing or corrupt.
- undoCounter = removeJobsInMissingOrCorruptJounralFiles(tx, missingJournalFiles, corruptedLocations);
+ synchronized Location write(ByteSequence payload, boolean sync) throws IllegalStateException, IOException {
+ return this.journal.write(payload, sync);
+ }
- // Clean up the Journal Reference count Map.
- removeJournalRCForMissingFiles(tx, missingJournalFiles);
- }
+ PageFile getPageFile() {
+ this.pageFile.isLoaded();
+ return this.pageFile;
+ }
- if (undoCounter > 0) {
- long end = System.currentTimeMillis();
- LOG.info("Detected missing/corrupt journal files. Dropped {} jobs from the " +
- "index in {} seconds.", undoCounter, ((end - start) / 1000.0f));
- }
+ public boolean isFailIfDatabaseIsLocked() {
+ return failIfDatabaseIsLocked;
}
- private void removeJournalRCForMissingFiles(Transaction tx, Set<Integer> missing) throws IOException {
- List<Integer> matches = new ArrayList<Integer>();
+ public void setFailIfDatabaseIsLocked(boolean failIfDatabaseIsLocked) {
+ this.failIfDatabaseIsLocked = failIfDatabaseIsLocked;
+ }
- Iterator<Entry<Integer, Integer>> references = metaData.getJournalRC().iterator(tx);
- while (references.hasNext()) {
- int dataFileId = references.next().getKey();
- if (missing.contains(dataFileId)) {
- matches.add(dataFileId);
- }
- }
+ public int getJournalMaxFileLength() {
+ return journalMaxFileLength;
+ }
- for (Integer match : matches) {
- metaData.getJournalRC().remove(tx, match);
- }
+ public void setJournalMaxFileLength(int journalMaxFileLength) {
+ this.journalMaxFileLength = journalMaxFileLength;
}
- private int removeJobsInMissingOrCorruptJounralFiles(Transaction tx, Set<Integer> missing, Set<Location> corrupted) throws IOException {
- int removed = 0;
+ public int getJournalMaxWriteBatchSize() {
+ return journalMaxWriteBatchSize;
+ }
- // Remove Jobs that reference missing or corrupt files.
- // Remove Reference counts to missing or corrupt files.
- // Remove and remove command markers to missing or corrupt files.
- for (Iterator<Map.Entry<String, JobSchedulerImpl>> i = metaData.getJobSchedulers().iterator(tx); i.hasNext();) {
- Map.Entry<String, JobSchedulerImpl> entry = i.next();
- JobSchedulerImpl scheduler = entry.getValue();
+ public void setJournalMaxWriteBatchSize(int journalMaxWriteBatchSize) {
+ this.journalMaxWriteBatchSize = journalMaxWriteBatchSize;
+ }
- List<JobLocation> jobs = scheduler.getAllScheduledJobs(tx);
- for (JobLocation job : jobs) {
+ public boolean isEnableIndexWriteAsync() {
+ return enableIndexWriteAsync;
+ }
- // Remove all jobs in missing log files.
- if (missing.contains(job.getLocation().getDataFileId())) {
- scheduler.removeJobAtTime(tx, job.getJobId(), job.getNextTime());
- removed++;
- continue;
- }
+ public void setEnableIndexWriteAsync(boolean enableIndexWriteAsync) {
+ this.enableIndexWriteAsync = enableIndexWriteAsync;
+ }
- // Remove all jobs in corrupted parts of log files.
- if (corrupted.contains(job.getLocation())) {
- scheduler.removeJobAtTime(tx, job.getJobId(), job.getNextTime());
- removed++;
- }
- }
- }
+ @Override
+ public String toString() {
+ return "JobSchedulerStore:" + this.directory;
+ }
- return removed;
+ @Override
+ public Locker createDefaultLocker() throws IOException {
+ SharedFileLocker locker = new SharedFileLocker();
+ locker.setDirectory(this.getDirectory());
+ return locker;
+ }
+
+ @Override
+ public void init() throws Exception {
}
}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/UnknownStoreVersionException.java
----------------------------------------------------------------------
diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/UnknownStoreVersionException.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/UnknownStoreVersionException.java
deleted file mode 100644
index 5146d84..0000000
--- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/UnknownStoreVersionException.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.apache.activemq.store.kahadb.scheduler;
-
-import java.io.IOException;
-
-public class UnknownStoreVersionException extends IOException {
-
- private static final long serialVersionUID = -8544753506151157145L;
-
- private final String token;
-
- public UnknownStoreVersionException(Throwable cause) {
- super(cause);
- this.token = "";
- }
-
- public UnknownStoreVersionException(String token) {
- super("Failed to load Store, found unknown store token: " + token);
- this.token = token;
- }
-
- public String getToken() {
- return this.token;
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/legacy/LegacyJobImpl.java
----------------------------------------------------------------------
diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/legacy/LegacyJobImpl.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/legacy/LegacyJobImpl.java
deleted file mode 100644
index 2562f50..0000000
--- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/legacy/LegacyJobImpl.java
+++ /dev/null
@@ -1,72 +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.store.kahadb.scheduler.legacy;
-
-import org.apache.activemq.protobuf.Buffer;
-import org.apache.activemq.util.ByteSequence;
-
-/**
- * Legacy version Job and Job payload wrapper. Allows for easy replay of stored
- * legacy jobs into a new JobSchedulerStoreImpl intsance.
- */
-final class LegacyJobImpl {
-
- private final LegacyJobLocation jobLocation;
- private final Buffer payload;
-
- protected LegacyJobImpl(LegacyJobLocation location, ByteSequence payload) {
- this.jobLocation = location;
- this.payload = new Buffer(payload.data, payload.offset, payload.length);
- }
-
- public String getJobId() {
- return this.jobLocation.getJobId();
- }
-
- public Buffer getPayload() {
- return this.payload;
- }
-
- public long getPeriod() {
- return this.jobLocation.getPeriod();
- }
-
- public int getRepeat() {
- return this.jobLocation.getRepeat();
- }
-
- public long getDelay() {
- return this.jobLocation.getDelay();
- }
-
- public String getCronEntry() {
- return this.jobLocation.getCronEntry();
- }
-
- public long getNextExecutionTime() {
- return this.jobLocation.getNextTime();
- }
-
- public long getStartTime() {
- return this.jobLocation.getStartTime();
- }
-
- @Override
- public String toString() {
- return this.jobLocation.toString();
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/legacy/LegacyJobLocation.java
----------------------------------------------------------------------
diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/legacy/LegacyJobLocation.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/legacy/LegacyJobLocation.java
deleted file mode 100644
index 8437064..0000000
--- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/legacy/LegacyJobLocation.java
+++ /dev/null
@@ -1,296 +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.store.kahadb.scheduler.legacy;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import org.apache.activemq.store.kahadb.disk.journal.Location;
-import org.apache.activemq.store.kahadb.disk.util.VariableMarshaller;
-
-final class LegacyJobLocation {
-
- private String jobId;
- private int repeat;
- private long startTime;
- private long delay;
- private long nextTime;
- private long period;
- private String cronEntry;
- private final Location location;
-
- public LegacyJobLocation(Location location) {
- this.location = location;
- }
-
- public LegacyJobLocation() {
- this(new Location());
- }
-
- public void readExternal(DataInput in) throws IOException {
- this.jobId = in.readUTF();
- this.repeat = in.readInt();
- this.startTime = in.readLong();
- this.delay = in.readLong();
- this.nextTime = in.readLong();
- this.period = in.readLong();
- this.cronEntry = in.readUTF();
- this.location.readExternal(in);
- }
-
- public void writeExternal(DataOutput out) throws IOException {
- out.writeUTF(this.jobId);
- out.writeInt(this.repeat);
- out.writeLong(this.startTime);
- out.writeLong(this.delay);
- out.writeLong(this.nextTime);
- out.writeLong(this.period);
- if (this.cronEntry == null) {
- this.cronEntry = "";
- }
- out.writeUTF(this.cronEntry);
- this.location.writeExternal(out);
- }
-
- /**
- * @return the jobId
- */
- public String getJobId() {
- return this.jobId;
- }
-
- /**
- * @param jobId
- * the jobId to set
- */
- public void setJobId(String jobId) {
- this.jobId = jobId;
- }
-
- /**
- * @return the repeat
- */
- public int getRepeat() {
- return this.repeat;
- }
-
- /**
- * @param repeat
- * the repeat to set
- */
- public void setRepeat(int repeat) {
- this.repeat = repeat;
- }
-
- /**
- * @return the start
- */
- public long getStartTime() {
- return this.startTime;
- }
-
- /**
- * @param start
- * the start to set
- */
- public void setStartTime(long start) {
- this.startTime = start;
- }
-
- /**
- * @return the nextTime
- */
- public synchronized long getNextTime() {
- return this.nextTime;
- }
-
- /**
- * @param nextTime
- * the nextTime to set
- */
- public synchronized void setNextTime(long nextTime) {
- this.nextTime = nextTime;
- }
-
- /**
- * @return the period
- */
- public long getPeriod() {
- return this.period;
- }
-
- /**
- * @param period
- * the period to set
- */
- public void setPeriod(long period) {
- this.period = period;
- }
-
- /**
- * @return the cronEntry
- */
- public synchronized String getCronEntry() {
- return this.cronEntry;
- }
-
- /**
- * @param cronEntry
- * the cronEntry to set
- */
- public synchronized void setCronEntry(String cronEntry) {
- this.cronEntry = cronEntry;
- }
-
- /**
- * @return if this JobLocation represents a cron entry.
- */
- public boolean isCron() {
- return getCronEntry() != null && getCronEntry().length() > 0;
- }
-
- /**
- * @return the delay
- */
- public long getDelay() {
- return this.delay;
- }
-
- /**
- * @param delay
- * the delay to set
- */
- public void setDelay(long delay) {
- this.delay = delay;
- }
-
- /**
- * @return the location
- */
- public Location getLocation() {
- return this.location;
- }
-
- @Override
- public String toString() {
- return "Job [id=" + jobId + ", startTime=" + new Date(startTime) +
- ", delay=" + delay + ", period=" + period +
- ", repeat=" + repeat + ", nextTime=" + new Date(nextTime) + "]";
- }
-
- static class JobLocationMarshaller extends VariableMarshaller<List<LegacyJobLocation>> {
- static final JobLocationMarshaller INSTANCE = new JobLocationMarshaller();
-
- @Override
- public List<LegacyJobLocation> readPayload(DataInput dataIn) throws IOException {
- List<LegacyJobLocation> result = new ArrayList<LegacyJobLocation>();
- int size = dataIn.readInt();
- for (int i = 0; i < size; i++) {
- LegacyJobLocation jobLocation = new LegacyJobLocation();
- jobLocation.readExternal(dataIn);
- result.add(jobLocation);
- }
- return result;
- }
-
- @Override
- public void writePayload(List<LegacyJobLocation> value, DataOutput dataOut) throws IOException {
- dataOut.writeInt(value.size());
- for (LegacyJobLocation jobLocation : value) {
- jobLocation.writeExternal(dataOut);
- }
- }
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((cronEntry == null) ? 0 : cronEntry.hashCode());
- result = prime * result + (int) (delay ^ (delay >>> 32));
- result = prime * result + ((jobId == null) ? 0 : jobId.hashCode());
- result = prime * result + ((location == null) ? 0 : location.hashCode());
- result = prime * result + (int) (nextTime ^ (nextTime >>> 32));
- result = prime * result + (int) (period ^ (period >>> 32));
- result = prime * result + repeat;
- result = prime * result + (int) (startTime ^ (startTime >>> 32));
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
-
- if (obj == null) {
- return false;
- }
-
- if (getClass() != obj.getClass()) {
- return false;
- }
-
- LegacyJobLocation other = (LegacyJobLocation) obj;
-
- if (cronEntry == null) {
- if (other.cronEntry != null) {
- return false;
- }
- } else if (!cronEntry.equals(other.cronEntry)) {
- return false;
- }
-
- if (delay != other.delay) {
- return false;
- }
-
- if (jobId == null) {
- if (other.jobId != null)
- return false;
- } else if (!jobId.equals(other.jobId)) {
- return false;
- }
-
- if (location == null) {
- if (other.location != null) {
- return false;
- }
- } else if (!location.equals(other.location)) {
- return false;
- }
-
- if (nextTime != other.nextTime) {
- return false;
- }
- if (period != other.period) {
- return false;
- }
- if (repeat != other.repeat) {
- return false;
- }
- if (startTime != other.startTime) {
- return false;
- }
-
- return true;
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/legacy/LegacyJobSchedulerImpl.java
----------------------------------------------------------------------
diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/legacy/LegacyJobSchedulerImpl.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/legacy/LegacyJobSchedulerImpl.java
deleted file mode 100644
index 687ffd7..0000000
--- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/legacy/LegacyJobSchedulerImpl.java
+++ /dev/null
@@ -1,222 +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.store.kahadb.scheduler.legacy;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.activemq.store.kahadb.disk.index.BTreeIndex;
-import org.apache.activemq.store.kahadb.disk.journal.Location;
-import org.apache.activemq.store.kahadb.disk.page.Transaction;
-import org.apache.activemq.store.kahadb.disk.util.LongMarshaller;
-import org.apache.activemq.store.kahadb.disk.util.VariableMarshaller;
-import org.apache.activemq.util.ByteSequence;
-import org.apache.activemq.util.ServiceStopper;
-import org.apache.activemq.util.ServiceSupport;
-
-/**
- * Read-only view of a stored legacy JobScheduler instance.
- */
-final class LegacyJobSchedulerImpl extends ServiceSupport {
-
- private final LegacyJobSchedulerStoreImpl store;
- private String name;
- private BTreeIndex<Long, List<LegacyJobLocation>> index;
-
- LegacyJobSchedulerImpl(LegacyJobSchedulerStoreImpl store) {
- this.store = store;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getName() {
- return this.name;
- }
-
- /**
- * Returns the next time that a job would be scheduled to run.
- *
- * @return time of next scheduled job to run.
- *
- * @throws IOException if an error occurs while fetching the time.
- */
- public long getNextScheduleTime() throws IOException {
- Map.Entry<Long, List<LegacyJobLocation>> first = this.index.getFirst(this.store.getPageFile().tx());
- return first != null ? first.getKey() : -1l;
- }
-
- /**
- * Gets the list of the next batch of scheduled jobs in the store.
- *
- * @return a list of the next jobs that will run.
- *
- * @throws IOException if an error occurs while fetching the jobs list.
- */
- public List<LegacyJobImpl> getNextScheduleJobs() throws IOException {
- final List<LegacyJobImpl> result = new ArrayList<LegacyJobImpl>();
-
- this.store.getPageFile().tx().execute(new Transaction.Closure<IOException>() {
- @Override
- public void execute(Transaction tx) throws IOException {
- Map.Entry<Long, List<LegacyJobLocation>> first = index.getFirst(store.getPageFile().tx());
- if (first != null) {
- for (LegacyJobLocation jl : first.getValue()) {
- ByteSequence bs = getPayload(jl.getLocation());
- LegacyJobImpl job = new LegacyJobImpl(jl, bs);
- result.add(job);
- }
- }
- }
- });
- return result;
- }
-
- /**
- * Gets a list of all scheduled jobs in this store.
- *
- * @return a list of all the currently scheduled jobs in this store.
- *
- * @throws IOException if an error occurs while fetching the list of jobs.
- */
- public List<LegacyJobImpl> getAllJobs() throws IOException {
- final List<LegacyJobImpl> result = new ArrayList<LegacyJobImpl>();
- this.store.getPageFile().tx().execute(new Transaction.Closure<IOException>() {
- @Override
- public void execute(Transaction tx) throws IOException {
- Iterator<Map.Entry<Long, List<LegacyJobLocation>>> iter = index.iterator(store.getPageFile().tx());
- while (iter.hasNext()) {
- Map.Entry<Long, List<LegacyJobLocation>> next = iter.next();
- if (next != null) {
- for (LegacyJobLocation jl : next.getValue()) {
- ByteSequence bs = getPayload(jl.getLocation());
- LegacyJobImpl job = new LegacyJobImpl(jl, bs);
- result.add(job);
- }
- } else {
- break;
- }
- }
- }
- });
- return result;
- }
-
- /**
- * Gets a list of all scheduled jobs that exist between the given start and end time.
- *
- * @param start
- * The start time to look for scheduled jobs.
- * @param finish
- * The end time to stop looking for scheduled jobs.
- *
- * @return a list of all scheduled jobs that would run between the given start and end time.
- *
- * @throws IOException if an error occurs while fetching the list of jobs.
- */
- public List<LegacyJobImpl> getAllJobs(final long start, final long finish) throws IOException {
- final List<LegacyJobImpl> result = new ArrayList<LegacyJobImpl>();
- this.store.getPageFile().tx().execute(new Transaction.Closure<IOException>() {
- @Override
- public void execute(Transaction tx) throws IOException {
- Iterator<Map.Entry<Long, List<LegacyJobLocation>>> iter = index.iterator(store.getPageFile().tx(), start);
- while (iter.hasNext()) {
- Map.Entry<Long, List<LegacyJobLocation>> next = iter.next();
- if (next != null && next.getKey().longValue() <= finish) {
- for (LegacyJobLocation jl : next.getValue()) {
- ByteSequence bs = getPayload(jl.getLocation());
- LegacyJobImpl job = new LegacyJobImpl(jl, bs);
- result.add(job);
- }
- } else {
- break;
- }
- }
- }
- });
- return result;
- }
-
- ByteSequence getPayload(Location location) throws IllegalStateException, IOException {
- return this.store.getPayload(location);
- }
-
- @Override
- public String toString() {
- return "LegacyJobScheduler: " + this.name;
- }
-
- @Override
- protected void doStart() throws Exception {
- }
-
- @Override
- protected void doStop(ServiceStopper stopper) throws Exception {
- }
-
- void createIndexes(Transaction tx) throws IOException {
- this.index = new BTreeIndex<Long, List<LegacyJobLocation>>(this.store.getPageFile(), tx.allocate().getPageId());
- }
-
- void load(Transaction tx) throws IOException {
- this.index.setKeyMarshaller(LongMarshaller.INSTANCE);
- this.index.setValueMarshaller(ValueMarshaller.INSTANCE);
- this.index.load(tx);
- }
-
- void read(DataInput in) throws IOException {
- this.name = in.readUTF();
- this.index = new BTreeIndex<Long, List<LegacyJobLocation>>(this.store.getPageFile(), in.readLong());
- this.index.setKeyMarshaller(LongMarshaller.INSTANCE);
- this.index.setValueMarshaller(ValueMarshaller.INSTANCE);
- }
-
- public void write(DataOutput out) throws IOException {
- out.writeUTF(name);
- out.writeLong(this.index.getPageId());
- }
-
- static class ValueMarshaller extends VariableMarshaller<List<LegacyJobLocation>> {
- static ValueMarshaller INSTANCE = new ValueMarshaller();
-
- @Override
- public List<LegacyJobLocation> readPayload(DataInput dataIn) throws IOException {
- List<LegacyJobLocation> result = new ArrayList<LegacyJobLocation>();
- int size = dataIn.readInt();
- for (int i = 0; i < size; i++) {
- LegacyJobLocation jobLocation = new LegacyJobLocation();
- jobLocation.readExternal(dataIn);
- result.add(jobLocation);
- }
- return result;
- }
-
- @Override
- public void writePayload(List<LegacyJobLocation> value, DataOutput dataOut) throws IOException {
- dataOut.writeInt(value.size());
- for (LegacyJobLocation jobLocation : value) {
- jobLocation.writeExternal(dataOut);
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/legacy/LegacyJobSchedulerStoreImpl.java
----------------------------------------------------------------------
diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/legacy/LegacyJobSchedulerStoreImpl.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/legacy/LegacyJobSchedulerStoreImpl.java
deleted file mode 100644
index acbd4e7..0000000
--- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/legacy/LegacyJobSchedulerStoreImpl.java
+++ /dev/null
@@ -1,378 +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.store.kahadb.scheduler.legacy;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.apache.activemq.store.kahadb.disk.index.BTreeIndex;
-import org.apache.activemq.store.kahadb.disk.journal.Journal;
-import org.apache.activemq.store.kahadb.disk.journal.Location;
-import org.apache.activemq.store.kahadb.disk.page.Page;
-import org.apache.activemq.store.kahadb.disk.page.PageFile;
-import org.apache.activemq.store.kahadb.disk.page.Transaction;
-import org.apache.activemq.store.kahadb.disk.util.IntegerMarshaller;
-import org.apache.activemq.store.kahadb.disk.util.StringMarshaller;
-import org.apache.activemq.store.kahadb.disk.util.VariableMarshaller;
-import org.apache.activemq.util.ByteSequence;
-import org.apache.activemq.util.IOHelper;
-import org.apache.activemq.util.LockFile;
-import org.apache.activemq.util.ServiceStopper;
-import org.apache.activemq.util.ServiceSupport;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Read-only view of a legacy JobSchedulerStore implementation.
- */
-final class LegacyJobSchedulerStoreImpl extends ServiceSupport {
-
- static final Logger LOG = LoggerFactory.getLogger(LegacyJobSchedulerStoreImpl.class);
-
- private static final int DATABASE_LOCKED_WAIT_DELAY = 10 * 1000;
-
- private File directory;
- private PageFile pageFile;
- private Journal journal;
- private LockFile lockFile;
- private final AtomicLong journalSize = new AtomicLong(0);
- private boolean failIfDatabaseIsLocked;
- private int journalMaxFileLength = Journal.DEFAULT_MAX_FILE_LENGTH;
- private int journalMaxWriteBatchSize = Journal.DEFAULT_MAX_WRITE_BATCH_SIZE;
- private boolean enableIndexWriteAsync = false;
- private MetaData metaData = new MetaData(this);
- private final MetaDataMarshaller metaDataMarshaller = new MetaDataMarshaller(this);
- private final Map<String, LegacyJobSchedulerImpl> schedulers = new HashMap<String, LegacyJobSchedulerImpl>();
-
- protected class MetaData {
- protected MetaData(LegacyJobSchedulerStoreImpl store) {
- this.store = store;
- }
-
- private final LegacyJobSchedulerStoreImpl store;
- Page<MetaData> page;
- BTreeIndex<Integer, Integer> journalRC;
- BTreeIndex<String, LegacyJobSchedulerImpl> storedSchedulers;
-
- void createIndexes(Transaction tx) throws IOException {
- this.storedSchedulers = new BTreeIndex<String, LegacyJobSchedulerImpl>(pageFile, tx.allocate().getPageId());
- this.journalRC = new BTreeIndex<Integer, Integer>(pageFile, tx.allocate().getPageId());
- }
-
- void load(Transaction tx) throws IOException {
- this.storedSchedulers.setKeyMarshaller(StringMarshaller.INSTANCE);
- this.storedSchedulers.setValueMarshaller(new JobSchedulerMarshaller(this.store));
- this.storedSchedulers.load(tx);
- this.journalRC.setKeyMarshaller(IntegerMarshaller.INSTANCE);
- this.journalRC.setValueMarshaller(IntegerMarshaller.INSTANCE);
- this.journalRC.load(tx);
- }
-
- void loadScheduler(Transaction tx, Map<String, LegacyJobSchedulerImpl> schedulers) throws IOException {
- for (Iterator<Entry<String, LegacyJobSchedulerImpl>> i = this.storedSchedulers.iterator(tx); i.hasNext();) {
- Entry<String, LegacyJobSchedulerImpl> entry = i.next();
- entry.getValue().load(tx);
- schedulers.put(entry.getKey(), entry.getValue());
- }
- }
-
- public void read(DataInput is) throws IOException {
- this.storedSchedulers = new BTreeIndex<String, LegacyJobSchedulerImpl>(pageFile, is.readLong());
- this.storedSchedulers.setKeyMarshaller(StringMarshaller.INSTANCE);
- this.storedSchedulers.setValueMarshaller(new JobSchedulerMarshaller(this.store));
- this.journalRC = new BTreeIndex<Integer, Integer>(pageFile, is.readLong());
- this.journalRC.setKeyMarshaller(IntegerMarshaller.INSTANCE);
- this.journalRC.setValueMarshaller(IntegerMarshaller.INSTANCE);
- }
-
- public void write(DataOutput os) throws IOException {
- os.writeLong(this.storedSchedulers.getPageId());
- os.writeLong(this.journalRC.getPageId());
- }
- }
-
- class MetaDataMarshaller extends VariableMarshaller<MetaData> {
- private final LegacyJobSchedulerStoreImpl store;
-
- MetaDataMarshaller(LegacyJobSchedulerStoreImpl store) {
- this.store = store;
- }
-
- @Override
- public MetaData readPayload(DataInput dataIn) throws IOException {
- MetaData rc = new MetaData(this.store);
- rc.read(dataIn);
- return rc;
- }
-
- @Override
- public void writePayload(MetaData object, DataOutput dataOut) throws IOException {
- object.write(dataOut);
- }
- }
-
- class ValueMarshaller extends VariableMarshaller<List<LegacyJobLocation>> {
- @Override
- public List<LegacyJobLocation> readPayload(DataInput dataIn) throws IOException {
- List<LegacyJobLocation> result = new ArrayList<LegacyJobLocation>();
- int size = dataIn.readInt();
- for (int i = 0; i < size; i++) {
- LegacyJobLocation jobLocation = new LegacyJobLocation();
- jobLocation.readExternal(dataIn);
- result.add(jobLocation);
- }
- return result;
- }
-
- @Override
- public void writePayload(List<LegacyJobLocation> value, DataOutput dataOut) throws IOException {
- dataOut.writeInt(value.size());
- for (LegacyJobLocation jobLocation : value) {
- jobLocation.writeExternal(dataOut);
- }
- }
- }
-
- class JobSchedulerMarshaller extends VariableMarshaller<LegacyJobSchedulerImpl> {
- private final LegacyJobSchedulerStoreImpl store;
-
- JobSchedulerMarshaller(LegacyJobSchedulerStoreImpl store) {
- this.store = store;
- }
-
- @Override
- public LegacyJobSchedulerImpl readPayload(DataInput dataIn) throws IOException {
- LegacyJobSchedulerImpl result = new LegacyJobSchedulerImpl(this.store);
- result.read(dataIn);
- return result;
- }
-
- @Override
- public void writePayload(LegacyJobSchedulerImpl js, DataOutput dataOut) throws IOException {
- js.write(dataOut);
- }
- }
-
- public File getDirectory() {
- return directory;
- }
-
- public void setDirectory(File directory) {
- this.directory = directory;
- }
-
- public long size() {
- if (!isStarted()) {
- return 0;
- }
- try {
- return journalSize.get() + pageFile.getDiskSize();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Returns the named Job Scheduler if it exists, otherwise throws an exception.
- *
- * @param name
- * The name of the scheduler that is to be returned.
- *
- * @return the named scheduler if it exists.
- *
- * @throws Exception if the named scheduler does not exist in this store.
- */
- public LegacyJobSchedulerImpl getJobScheduler(final String name) throws Exception {
- LegacyJobSchedulerImpl result = this.schedulers.get(name);
- if (result == null) {
- throw new NoSuchElementException("No such Job Scheduler in this store: " + name);
- }
- return result;
- }
-
- /**
- * Returns the names of all the schedulers that exist in this scheduler store.
- *
- * @return a set of names of all scheduler instances in this store.
- *
- * @throws Exception if an error occurs while collecting the scheduler names.
- */
- public Set<String> getJobSchedulerNames() throws Exception {
- Set<String> names = Collections.emptySet();
-
- if (!schedulers.isEmpty()) {
- return this.schedulers.keySet();
- }
-
- return names;
- }
-
- @Override
- protected void doStart() throws Exception {
- if (this.directory == null) {
- this.directory = new File(IOHelper.getDefaultDataDirectory() + File.pathSeparator + "delayedDB");
- }
- IOHelper.mkdirs(this.directory);
- lock();
- this.journal = new Journal();
- this.journal.setDirectory(directory);
- this.journal.setMaxFileLength(getJournalMaxFileLength());
- this.journal.setWriteBatchSize(getJournalMaxWriteBatchSize());
- this.journal.setSizeAccumulator(this.journalSize);
- this.journal.start();
- this.pageFile = new PageFile(directory, "scheduleDB");
- this.pageFile.setWriteBatchSize(1);
- this.pageFile.load();
-
- this.pageFile.tx().execute(new Transaction.Closure<IOException>() {
- @Override
- public void execute(Transaction tx) throws IOException {
- if (pageFile.getPageCount() == 0) {
- Page<MetaData> page = tx.allocate();
- assert page.getPageId() == 0;
- page.set(metaData);
- metaData.page = page;
- metaData.createIndexes(tx);
- tx.store(metaData.page, metaDataMarshaller, true);
-
- } else {
- Page<MetaData> page = tx.load(0, metaDataMarshaller);
- metaData = page.get();
- metaData.page = page;
- }
- metaData.load(tx);
- metaData.loadScheduler(tx, schedulers);
- for (LegacyJobSchedulerImpl js : schedulers.values()) {
- try {
- js.start();
- } catch (Exception e) {
- LegacyJobSchedulerStoreImpl.LOG.error("Failed to load " + js.getName(), e);
- }
- }
- }
- });
-
- this.pageFile.flush();
- LOG.info(this + " started");
- }
-
- @Override
- protected void doStop(ServiceStopper stopper) throws Exception {
- for (LegacyJobSchedulerImpl js : this.schedulers.values()) {
- js.stop();
- }
- if (this.pageFile != null) {
- this.pageFile.unload();
- }
- if (this.journal != null) {
- journal.close();
- }
- if (this.lockFile != null) {
- this.lockFile.unlock();
- }
- this.lockFile = null;
- LOG.info(this + " stopped");
- }
-
- ByteSequence getPayload(Location location) throws IllegalStateException, IOException {
- ByteSequence result = null;
- result = this.journal.read(location);
- return result;
- }
-
- Location write(ByteSequence payload, boolean sync) throws IllegalStateException, IOException {
- return this.journal.write(payload, sync);
- }
-
- private void lock() throws IOException {
- if (lockFile == null) {
- File lockFileName = new File(directory, "lock");
- lockFile = new LockFile(lockFileName, true);
- if (failIfDatabaseIsLocked) {
- lockFile.lock();
- } else {
- while (true) {
- try {
- lockFile.lock();
- break;
- } catch (IOException e) {
- LOG.info("Database " + lockFileName + " is locked... waiting " + (DATABASE_LOCKED_WAIT_DELAY / 1000)
- + " seconds for the database to be unlocked. Reason: " + e);
- try {
- Thread.sleep(DATABASE_LOCKED_WAIT_DELAY);
- } catch (InterruptedException e1) {
- }
- }
- }
- }
- }
- }
-
- PageFile getPageFile() {
- this.pageFile.isLoaded();
- return this.pageFile;
- }
-
- public boolean isFailIfDatabaseIsLocked() {
- return failIfDatabaseIsLocked;
- }
-
- public void setFailIfDatabaseIsLocked(boolean failIfDatabaseIsLocked) {
- this.failIfDatabaseIsLocked = failIfDatabaseIsLocked;
- }
-
- public int getJournalMaxFileLength() {
- return journalMaxFileLength;
- }
-
- public void setJournalMaxFileLength(int journalMaxFileLength) {
- this.journalMaxFileLength = journalMaxFileLength;
- }
-
- public int getJournalMaxWriteBatchSize() {
- return journalMaxWriteBatchSize;
- }
-
- public void setJournalMaxWriteBatchSize(int journalMaxWriteBatchSize) {
- this.journalMaxWriteBatchSize = journalMaxWriteBatchSize;
- }
-
- public boolean isEnableIndexWriteAsync() {
- return enableIndexWriteAsync;
- }
-
- public void setEnableIndexWriteAsync(boolean enableIndexWriteAsync) {
- this.enableIndexWriteAsync = enableIndexWriteAsync;
- }
-
- @Override
- public String toString() {
- return "LegacyJobSchedulerStore:" + this.directory;
- }
-}
[5/5] activemq git commit: Revert
"https://issues.apache.org/jira/browse/AMQ-3758"
Posted by ha...@apache.org.
Revert "https://issues.apache.org/jira/browse/AMQ-3758"
This reverts commit fc244f48e48596c668a7d9dc3b84c26e60693823.
Project: http://git-wip-us.apache.org/repos/asf/activemq/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq/commit/3424e04f
Tree: http://git-wip-us.apache.org/repos/asf/activemq/tree/3424e04f
Diff: http://git-wip-us.apache.org/repos/asf/activemq/diff/3424e04f
Branch: refs/heads/activemq-5.10.x
Commit: 3424e04fad09ef69eaa72715669ebba40bb45019
Parents: 76357bd
Author: Hadrian Zbarcea <ha...@apache.org>
Authored: Wed Dec 24 17:59:47 2014 -0500
Committer: Hadrian Zbarcea <ha...@apache.org>
Committed: Wed Dec 24 17:59:47 2014 -0500
----------------------------------------------------------------------
.../apache/activemq/broker/BrokerService.java | 25 +-
.../activemq/broker/jmx/JobSchedulerView.java | 56 +-
.../broker/jmx/JobSchedulerViewMBean.java | 113 +-
.../apache/activemq/broker/scheduler/Job.java | 23 +-
.../activemq/broker/scheduler/JobListener.java | 16 +-
.../activemq/broker/scheduler/JobScheduler.java | 33 +-
.../broker/scheduler/JobSchedulerFacade.java | 6 -
.../broker/scheduler/JobSchedulerStore.java | 43 -
.../activemq/broker/scheduler/JobSupport.java | 5 +-
.../activemq/store/PersistenceAdapter.java | 119 +-
.../store/memory/MemoryPersistenceAdapter.java | 36 +-
.../java/org/apache/activemq/util/IOHelper.java | 68 +-
.../store/jdbc/JDBCPersistenceAdapter.java | 7 -
.../journal/JournalPersistenceAdapter.java | 71 +-
.../store/kahadb/AbstractKahaDBMetaData.java | 57 -
.../store/kahadb/AbstractKahaDBStore.java | 745 ------------
.../activemq/store/kahadb/KahaDBMetaData.java | 135 ---
.../store/kahadb/KahaDBPersistenceAdapter.java | 15 +-
.../activemq/store/kahadb/KahaDBStore.java | 55 +-
.../kahadb/MultiKahaDBPersistenceAdapter.java | 56 +-
.../kahadb/MultiKahaDBTransactionStore.java | 18 +-
.../activemq/store/kahadb/TempKahaDBStore.java | 138 +--
.../apache/activemq/store/kahadb/Visitor.java | 20 -
.../store/kahadb/scheduler/JobImpl.java | 21 +-
.../store/kahadb/scheduler/JobLocation.java | 77 +-
.../scheduler/JobLocationsMarshaller.java | 53 -
.../kahadb/scheduler/JobSchedulerImpl.java | 837 ++++++--------
.../scheduler/JobSchedulerKahaDBMetaData.java | 246 ----
.../kahadb/scheduler/JobSchedulerStoreImpl.java | 1076 +++++-------------
.../scheduler/UnknownStoreVersionException.java | 24 -
.../kahadb/scheduler/legacy/LegacyJobImpl.java | 72 --
.../scheduler/legacy/LegacyJobLocation.java | 296 -----
.../legacy/LegacyJobSchedulerImpl.java | 222 ----
.../legacy/LegacyJobSchedulerStoreImpl.java | 378 ------
.../scheduler/legacy/LegacyStoreReplayer.java | 155 ---
.../src/main/proto/journal-data.proto | 61 -
.../apache/activemq/leveldb/LevelDBStore.scala | 5 -
.../leveldb/replicated/ProxyLevelDBStore.scala | 5 -
.../JobSchedulerBrokerShutdownTest.java | 1 -
.../JobSchedulerJmxManagementTests.java | 155 ---
.../scheduler/JobSchedulerManagementTest.java | 84 +-
.../JobSchedulerStoreCheckpointTest.java | 125 --
.../broker/scheduler/JobSchedulerStoreTest.java | 46 +-
.../broker/scheduler/JobSchedulerTest.java | 36 -
.../scheduler/JobSchedulerTestSupport.java | 112 --
.../KahaDBSchedulerIndexRebuildTest.java | 179 ---
.../KahaDBSchedulerMissingJournalLogsTest.java | 204 ----
.../scheduler/SchedulerDBVersionTest.java | 164 ---
.../src/test/resources/log4j.properties | 1 -
.../activemq/store/schedulerDB/legacy/db-1.log | Bin 524288 -> 0 bytes
.../store/schedulerDB/legacy/scheduleDB.data | Bin 20480 -> 0 bytes
.../store/schedulerDB/legacy/scheduleDB.redo | Bin 16408 -> 0 bytes
52 files changed, 911 insertions(+), 5584 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java
----------------------------------------------------------------------
diff --git a/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java b/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java
index 5becec2..00d4abd 100644
--- a/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java
+++ b/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java
@@ -1861,23 +1861,6 @@ public class BrokerService implements Service {
try {
PersistenceAdapter pa = getPersistenceAdapter();
- if (pa != null) {
- this.jobSchedulerStore = pa.createJobSchedulerStore();
- jobSchedulerStore.setDirectory(getSchedulerDirectoryFile());
- configureService(jobSchedulerStore);
- jobSchedulerStore.start();
- return this.jobSchedulerStore;
- }
- } catch (IOException e) {
- throw new RuntimeException(e);
- } catch (UnsupportedOperationException ex) {
- // It's ok if the store doesn't implement a scheduler.
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
-
- try {
- PersistenceAdapter pa = getPersistenceAdapter();
if (pa != null && pa instanceof JobSchedulerStore) {
this.jobSchedulerStore = (JobSchedulerStore) pa;
configureService(jobSchedulerStore);
@@ -1887,13 +1870,9 @@ public class BrokerService implements Service {
throw new RuntimeException(e);
}
- // Load the KahaDB store as a last resort, this only works if KahaDB is
- // included at runtime, otherwise this will fail. User should disable
- // scheduler support if this fails.
try {
- String clazz = "org.apache.activemq.store.kahadb.KahaDBPersistenceAdapter";
- PersistenceAdapter adaptor = (PersistenceAdapter)getClass().getClassLoader().loadClass(clazz).newInstance();
- jobSchedulerStore = adaptor.createJobSchedulerStore();
+ String clazz = "org.apache.activemq.store.kahadb.scheduler.JobSchedulerStoreImpl";
+ jobSchedulerStore = (JobSchedulerStore) getClass().getClassLoader().loadClass(clazz).newInstance();
jobSchedulerStore.setDirectory(getSchedulerDirectoryFile());
configureService(jobSchedulerStore);
jobSchedulerStore.start();
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/JobSchedulerView.java
----------------------------------------------------------------------
diff --git a/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/JobSchedulerView.java b/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/JobSchedulerView.java
index 2118a96..9e5a1fb 100644
--- a/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/JobSchedulerView.java
+++ b/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/JobSchedulerView.java
@@ -16,39 +16,23 @@
*/
package org.apache.activemq.broker.jmx;
-import java.util.List;
-
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.TabularData;
-import javax.management.openmbean.TabularDataSupport;
-import javax.management.openmbean.TabularType;
-
import org.apache.activemq.broker.jmx.OpenTypeSupport.OpenTypeFactory;
import org.apache.activemq.broker.scheduler.Job;
import org.apache.activemq.broker.scheduler.JobScheduler;
import org.apache.activemq.broker.scheduler.JobSupport;
-/**
- * MBean object that can be used to manage a single instance of a JobScheduler. The object
- * provides methods for querying for jobs and removing some or all of the jobs that are
- * scheduled in the managed store.
- */
+import javax.management.openmbean.*;
+import java.io.IOException;
+import java.util.List;
+
public class JobSchedulerView implements JobSchedulerViewMBean {
private final JobScheduler jobScheduler;
- /**
- * Creates a new instance of the JobScheduler management MBean.
- *
- * @param jobScheduler
- * The scheduler instance to manage.
- */
public JobSchedulerView(JobScheduler jobScheduler) {
this.jobScheduler = jobScheduler;
}
- @Override
public TabularData getAllJobs() throws Exception {
OpenTypeFactory factory = OpenTypeSupport.getFactory(Job.class);
CompositeType ct = factory.getCompositeType();
@@ -61,7 +45,6 @@ public class JobSchedulerView implements JobSchedulerViewMBean {
return rc;
}
- @Override
public TabularData getAllJobs(String startTime, String finishTime) throws Exception {
OpenTypeFactory factory = OpenTypeSupport.getFactory(Job.class);
CompositeType ct = factory.getCompositeType();
@@ -76,7 +59,6 @@ public class JobSchedulerView implements JobSchedulerViewMBean {
return rc;
}
- @Override
public TabularData getNextScheduleJobs() throws Exception {
OpenTypeFactory factory = OpenTypeSupport.getFactory(Job.class);
CompositeType ct = factory.getCompositeType();
@@ -89,51 +71,31 @@ public class JobSchedulerView implements JobSchedulerViewMBean {
return rc;
}
- @Override
public String getNextScheduleTime() throws Exception {
long time = this.jobScheduler.getNextScheduleTime();
return JobSupport.getDateTime(time);
}
- @Override
public void removeAllJobs() throws Exception {
this.jobScheduler.removeAllJobs();
+
}
- @Override
public void removeAllJobs(String startTime, String finishTime) throws Exception {
long start = JobSupport.getDataTime(startTime);
long finish = JobSupport.getDataTime(finishTime);
this.jobScheduler.removeAllJobs(start, finish);
- }
- @Override
- public void removeAllJobsAtScheduledTime(String time) throws Exception {
- long removeAtTime = JobSupport.getDataTime(time);
- this.jobScheduler.remove(removeAtTime);
}
- @Override
- public void removeJobAtScheduledTime(String time) throws Exception {
- removeAllJobsAtScheduledTime(time);
- }
-
- @Override
public void removeJob(String jobId) throws Exception {
this.jobScheduler.remove(jobId);
- }
- @Override
- public int getExecutionCount(String jobId) throws Exception {
- int result = 0;
+ }
- List<Job> jobs = this.jobScheduler.getAllJobs();
- for (Job job : jobs) {
- if (job.getJobId().equals(jobId)) {
- result = job.getExecutionCount();
- }
- }
+ public void removeJobAtScheduledTime(String time) throws IOException {
+ // TODO Auto-generated method stub
- return result;
}
+
}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/JobSchedulerViewMBean.java
----------------------------------------------------------------------
diff --git a/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/JobSchedulerViewMBean.java b/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/JobSchedulerViewMBean.java
index 76a7926..f5745ea 100644
--- a/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/JobSchedulerViewMBean.java
+++ b/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/JobSchedulerViewMBean.java
@@ -18,125 +18,76 @@ package org.apache.activemq.broker.jmx;
import javax.management.openmbean.TabularData;
-public interface JobSchedulerViewMBean {
- /**
- * Remove all jobs scheduled to run at this time. If there are no jobs scheduled
- * at the given time this methods returns without making any modifications to the
- * scheduler store.
- *
- * @param time
- * the string formated time that should be used to remove jobs.
- *
- * @throws Exception if an error occurs while performing the remove.
- *
- * @deprecated use removeAllJobsAtScheduledTime instead as it is more explicit about what
- * the method is actually doing.
- */
- @Deprecated
- @MBeanInfo("remove jobs with matching execution time")
- public abstract void removeJobAtScheduledTime(@MBeanInfo("time: yyyy-MM-dd hh:mm:ss")String time) throws Exception;
+public interface JobSchedulerViewMBean {
/**
- * Remove all jobs scheduled to run at this time. If there are no jobs scheduled
- * at the given time this methods returns without making any modifications to the
- * scheduler store.
- *
+ * remove all jobs scheduled to run at this time
* @param time
- * the string formated time that should be used to remove jobs.
- *
- * @throws Exception if an error occurs while performing the remove.
+ * @throws Exception
*/
@MBeanInfo("remove jobs with matching execution time")
- public abstract void removeAllJobsAtScheduledTime(@MBeanInfo("time: yyyy-MM-dd hh:mm:ss")String time) throws Exception;
+ public abstract void removeJobAtScheduledTime(@MBeanInfo("time: yyyy-MM-dd hh:mm:ss")String time) throws Exception;
/**
- * Remove a job with the matching jobId. If the method does not find a matching job
- * then it returns without throwing an error or making any modifications to the job
- * scheduler store.
- *
+ * remove a job with the matching jobId
* @param jobId
- * the Job Id to remove from the scheduler store.
- *
- * @throws Exception if an error occurs while attempting to remove the Job.
+ * @throws Exception
*/
@MBeanInfo("remove jobs with matching jobId")
public abstract void removeJob(@MBeanInfo("jobId")String jobId) throws Exception;
-
+
/**
- * Remove all the Jobs from the scheduler,
- *
- * @throws Exception if an error occurs while purging the store.
+ * remove all the Jobs from the scheduler
+ * @throws Exception
*/
@MBeanInfo("remove all scheduled jobs")
public abstract void removeAllJobs() throws Exception;
-
+
/**
- * Remove all the Jobs from the scheduler that are due between the start and finish times.
- *
- * @param start
- * the starting time to remove jobs from.
- * @param finish
- * the finish time for the remove operation.
- *
- * @throws Exception if an error occurs while attempting to remove the jobs.
+ * remove all the Jobs from the scheduler that are due between the start and finish times
+ * @param start time
+ * @param finish time
+ * @throws Exception
*/
@MBeanInfo("remove all scheduled jobs between time ranges ")
public abstract void removeAllJobs(@MBeanInfo("start: yyyy-MM-dd hh:mm:ss")String start,@MBeanInfo("finish: yyyy-MM-dd hh:mm:ss")String finish) throws Exception;
+
+
/**
- * Get the next time jobs will be fired from this scheduler store.
- *
- * @return the time in milliseconds of the next job to execute.
- *
- * @throws Exception if an error occurs while accessing the store.
+ * Get the next time jobs will be fired
+ * @return the time in milliseconds
+ * @throws Exception
*/
@MBeanInfo("get the next time a job is due to be scheduled ")
public abstract String getNextScheduleTime() throws Exception;
-
- /**
- * Gets the number of times a scheduled Job has been executed.
- *
- * @return the total number of time a scheduled job has executed.
- *
- * @throws Exception if an error occurs while querying for the Job.
- */
- @MBeanInfo("get the next time a job is due to be scheduled ")
- public abstract int getExecutionCount(@MBeanInfo("jobId")String jobId) throws Exception;
-
+
/**
- * Get all the jobs scheduled to run next.
- *
+ * Get all the jobs scheduled to run next
* @return a list of jobs that will be scheduled next
- *
- * @throws Exception if an error occurs while reading the scheduler store.
+ * @throws Exception
*/
@MBeanInfo("get the next job(s) to be scheduled. Not HTML friendly ")
public abstract TabularData getNextScheduleJobs() throws Exception;
-
+
/**
- * Get all the outstanding Jobs that are scheduled in this scheduler store.
- *
- * @return a table of all jobs in this scheduler store.
- *
- * @throws Exception if an error occurs while reading the store.
+ * Get all the outstanding Jobs
+ * @return a table of all jobs
+ * @throws Exception
+
*/
@MBeanInfo("get the scheduled Jobs in the Store. Not HTML friendly ")
public abstract TabularData getAllJobs() throws Exception;
-
+
/**
- * Get all outstanding jobs due to run between start and finish time range.
- *
+ * Get all outstanding jobs due to run between start and finish
* @param start
- * the starting time range to query the store for jobs.
* @param finish
- * the ending time of this query for scheduled jobs.
- *
- * @return a table of jobs in the range given.
- *
- * @throws Exception if an error occurs while querying the scheduler store.
+ * @return a table of jobs in the range
+ * @throws Exception
+
*/
@MBeanInfo("get the scheduled Jobs in the Store within the time range. Not HTML friendly ")
public abstract TabularData getAllJobs(@MBeanInfo("start: yyyy-MM-dd hh:mm:ss")String start,@MBeanInfo("finish: yyyy-MM-dd hh:mm:ss")String finish)throws Exception;
-
}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/Job.java
----------------------------------------------------------------------
diff --git a/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/Job.java b/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/Job.java
index 047fe23..7b28a5b 100644
--- a/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/Job.java
+++ b/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/Job.java
@@ -16,12 +16,7 @@
*/
package org.apache.activemq.broker.scheduler;
-/**
- * Interface for a scheduled Job object.
- *
- * Each Job is identified by a unique Job Id which can be used to reference the Job
- * in the Job Scheduler store for updates or removal.
- */
+
public interface Job {
/**
@@ -43,12 +38,11 @@ public interface Job {
* @return the Delay
*/
public abstract long getDelay();
-
/**
* @return the period
*/
public abstract long getPeriod();
-
+
/**
* @return the cron entry
*/
@@ -58,24 +52,17 @@ public interface Job {
* @return the payload
*/
public abstract byte[] getPayload();
-
+
/**
* Get the start time as a Date time string
* @return the date time
*/
public String getStartTime();
-
+
/**
- * Get the time the job is next due to execute
+ * Get the time the job is next due to execute
* @return the date time
*/
public String getNextExecutionTime();
- /**
- * Gets the total number of times this job has executed.
- *
- * @returns the number of times this job has been executed.
- */
- public int getExecutionCount();
-
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobListener.java
----------------------------------------------------------------------
diff --git a/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobListener.java b/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobListener.java
index a453595..c53d9c6 100644
--- a/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobListener.java
+++ b/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobListener.java
@@ -18,21 +18,13 @@ package org.apache.activemq.broker.scheduler;
import org.apache.activemq.util.ByteSequence;
-/**
- * Job event listener interface. Provides event points for Job related events
- * such as job ready events.
- */
public interface JobListener {
-
+
/**
- * A Job that has been scheduled is now ready to be fired. The Job is passed
- * in its raw byte form and must be un-marshaled before being delivered.
- *
- * @param jobId
- * The unique Job Id of the Job that is ready to fire.
+ * A Job that has been scheduled is now ready
+ * @param id
* @param job
- * The job that is now ready, delivered in byte form.
*/
- public void scheduledJob(String id, ByteSequence job);
+ public void scheduledJob(String id,ByteSequence job);
}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobScheduler.java
----------------------------------------------------------------------
diff --git a/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobScheduler.java b/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobScheduler.java
index e951861..2e96eae 100644
--- a/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobScheduler.java
+++ b/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobScheduler.java
@@ -46,25 +46,20 @@ public interface JobScheduler {
void stopDispatching() throws Exception;
/**
- * Add a Job listener which will receive events related to scheduled jobs.
- *
- * @param listener
- * The job listener to add.
+ * Add a Job listener
*
+ * @param l
* @throws Exception
*/
- void addListener(JobListener listener) throws Exception;
+ void addListener(JobListener l) throws Exception;
/**
- * remove a JobListener that was previously registered. If the given listener is not in
- * the registry this method has no effect.
- *
- * @param listener
- * The listener that should be removed from the listener registry.
+ * remove a JobListener
*
+ * @param l
* @throws Exception
*/
- void removeListener(JobListener listener) throws Exception;
+ void removeListener(JobListener l) throws Exception;
/**
* Add a job to be scheduled
@@ -75,8 +70,7 @@ public interface JobScheduler {
* the message to be sent when the job is scheduled
* @param delay
* the time in milliseconds before the job will be run
- *
- * @throws Exception if an error occurs while scheduling the Job.
+ * @throws Exception
*/
void schedule(String jobId, ByteSequence payload, long delay) throws Exception;
@@ -88,9 +82,8 @@ public interface JobScheduler {
* @param payload
* the message to be sent when the job is scheduled
* @param cronEntry
- * The cron entry to use to schedule this job.
- *
- * @throws Exception if an error occurs while scheduling the Job.
+ * - cron entry
+ * @throws Exception
*/
void schedule(String jobId, ByteSequence payload, String cronEntry) throws Exception;
@@ -102,7 +95,7 @@ public interface JobScheduler {
* @param payload
* the message to be sent when the job is scheduled
* @param cronEntry
- * cron entry
+ * - cron entry
* @param delay
* time in ms to wait before scheduling
* @param period
@@ -117,8 +110,6 @@ public interface JobScheduler {
* remove all jobs scheduled to run at this time
*
* @param time
- * The UTC time to use to remove a batch of scheduled Jobs.
- *
* @throws Exception
*/
void remove(long time) throws Exception;
@@ -127,9 +118,7 @@ public interface JobScheduler {
* remove a job with the matching jobId
*
* @param jobId
- * The unique Job Id to search for and remove from the scheduled set of jobs.
- *
- * @throws Exception if an error occurs while removing the Job.
+ * @throws Exception
*/
void remove(String jobId) throws Exception;
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobSchedulerFacade.java
----------------------------------------------------------------------
diff --git a/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobSchedulerFacade.java b/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobSchedulerFacade.java
index 24a216a..d46d04a 100644
--- a/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobSchedulerFacade.java
+++ b/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobSchedulerFacade.java
@@ -21,12 +21,6 @@ import java.util.List;
import org.apache.activemq.util.ByteSequence;
-/**
- * A wrapper for instances of the JobScheduler interface that ensures that methods
- * provides safe and sane return values and can deal with null values being passed
- * in etc. Provides a measure of safety when using unknown implementations of the
- * JobSchedulerStore which might not always do the right thing.
- */
public class JobSchedulerFacade implements JobScheduler {
private final SchedulerBroker broker;
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobSchedulerStore.java
----------------------------------------------------------------------
diff --git a/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobSchedulerStore.java b/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobSchedulerStore.java
index c6863c7..3cbc367 100644
--- a/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobSchedulerStore.java
+++ b/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobSchedulerStore.java
@@ -26,56 +26,13 @@ import org.apache.activemq.Service;
*/
public interface JobSchedulerStore extends Service {
- /**
- * Gets the location where the Job Scheduler will write the persistent data used
- * to preserve and recover scheduled Jobs.
- *
- * If the scheduler implementation does not utilize a file system based store this
- * method returns null.
- *
- * @return the directory where persistent store data is written.
- */
File getDirectory();
- /**
- * Sets the directory where persistent store data will be written. This method
- * must be called before the scheduler store is started to have any effect.
- *
- * @param directory
- * The directory where the job scheduler store is to be located.
- */
void setDirectory(File directory);
- /**
- * The size of the current store on disk if the store utilizes a disk based store
- * mechanism.
- *
- * @return the current store size on disk.
- */
long size();
- /**
- * Returns the JobScheduler instance identified by the given name.
- *
- * @param name
- * the name of the JobScheduler instance to lookup.
- *
- * @return the named JobScheduler or null if none exists with the given name.
- *
- * @throws Exception if an error occurs while loading the named scheduler.
- */
JobScheduler getJobScheduler(String name) throws Exception;
- /**
- * Removes the named JobScheduler if it exists, purging all scheduled messages
- * assigned to it.
- *
- * @param name
- * the name of the scheduler instance to remove.
- *
- * @return true if there was a scheduler with the given name to remove.
- *
- * @throws Exception if an error occurs while removing the scheduler.
- */
boolean removeJobScheduler(String name) throws Exception;
}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobSupport.java
----------------------------------------------------------------------
diff --git a/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobSupport.java b/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobSupport.java
index fc5b8dd..6b78d77 100644
--- a/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobSupport.java
+++ b/activemq-broker/src/main/java/org/apache/activemq/broker/scheduler/JobSupport.java
@@ -20,11 +20,7 @@ import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
-/**
- * A class to provide common Job Scheduler related methods.
- */
public class JobSupport {
-
public static String getDateTime(long value) {
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date(value);
@@ -36,4 +32,5 @@ public class JobSupport {
Date date = dfm.parse(value);
return date.getTime();
}
+
}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-broker/src/main/java/org/apache/activemq/store/PersistenceAdapter.java
----------------------------------------------------------------------
diff --git a/activemq-broker/src/main/java/org/apache/activemq/store/PersistenceAdapter.java b/activemq-broker/src/main/java/org/apache/activemq/store/PersistenceAdapter.java
index 01a9634..31efd32 100755
--- a/activemq-broker/src/main/java/org/apache/activemq/store/PersistenceAdapter.java
+++ b/activemq-broker/src/main/java/org/apache/activemq/store/PersistenceAdapter.java
@@ -22,7 +22,6 @@ import java.util.Set;
import org.apache.activemq.Service;
import org.apache.activemq.broker.ConnectionContext;
-import org.apache.activemq.broker.scheduler.JobSchedulerStore;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
@@ -32,99 +31,74 @@ import org.apache.activemq.usage.SystemUsage;
/**
* Adapter to the actual persistence mechanism used with ActiveMQ
*
- *
+ *
*/
public interface PersistenceAdapter extends Service {
/**
- * Returns a set of all the
- * {@link org.apache.activemq.command.ActiveMQDestination} objects that the
- * persistence store is aware exist.
+ * Returns a set of all the {@link org.apache.activemq.command.ActiveMQDestination}
+ * objects that the persistence store is aware exist.
*
* @return active destinations
*/
Set<ActiveMQDestination> getDestinations();
/**
- * Factory method to create a new queue message store with the given
- * destination name
- *
+ * Factory method to create a new queue message store with the given destination name
* @param destination
* @return the message store
- * @throws IOException
+ * @throws IOException
*/
MessageStore createQueueMessageStore(ActiveMQQueue destination) throws IOException;
/**
- * Factory method to create a new topic message store with the given
- * destination name
- *
- * @param destination
+ * Factory method to create a new topic message store with the given destination name
+ * @param destination
* @return the topic message store
- * @throws IOException
+ * @throws IOException
*/
TopicMessageStore createTopicMessageStore(ActiveMQTopic destination) throws IOException;
/**
- * Creates and returns a new Job Scheduler store instance.
- *
- * @return a new JobSchedulerStore instance if this Persistence adapter provides its own.
- *
- * @throws IOException If an error occurs while creating the new JobSchedulerStore.
- * @throws UnsupportedOperationException If this adapter does not provide its own
- * scheduler store implementation.
- */
- JobSchedulerStore createJobSchedulerStore() throws IOException, UnsupportedOperationException;
-
- /**
* Cleanup method to remove any state associated with the given destination.
* This method does not stop the message store (it might not be cached).
- *
- * @param destination
- * Destination to forget
+ * @param destination Destination to forget
*/
void removeQueueMessageStore(ActiveMQQueue destination);
/**
* Cleanup method to remove any state associated with the given destination
* This method does not stop the message store (it might not be cached).
- *
- * @param destination
- * Destination to forget
+ * @param destination Destination to forget
*/
void removeTopicMessageStore(ActiveMQTopic destination);
/**
- * Factory method to create a new persistent prepared transaction store for
- * XA recovery
- *
+ * Factory method to create a new persistent prepared transaction store for XA recovery
* @return transaction store
- * @throws IOException
+ * @throws IOException
*/
TransactionStore createTransactionStore() throws IOException;
/**
- * This method starts a transaction on the persistent storage - which is
- * nothing to do with JMS or XA transactions - its purely a mechanism to
- * perform multiple writes to a persistent store in 1 transaction as a
- * performance optimization.
+ * This method starts a transaction on the persistent storage - which is nothing to
+ * do with JMS or XA transactions - its purely a mechanism to perform multiple writes
+ * to a persistent store in 1 transaction as a performance optimization.
* <p/>
- * Typically one transaction will require one disk synchronization point and
- * so for real high performance its usually faster to perform many writes
- * within the same transaction to minimize latency caused by disk
- * synchronization. This is especially true when using tools like Berkeley
- * Db or embedded JDBC servers.
- *
- * @param context
- * @throws IOException
+ * Typically one transaction will require one disk synchronization point and so for
+ * real high performance its usually faster to perform many writes within the same
+ * transaction to minimize latency caused by disk synchronization. This is especially
+ * true when using tools like Berkeley Db or embedded JDBC servers.
+ * @param context
+ * @throws IOException
*/
void beginTransaction(ConnectionContext context) throws IOException;
+
/**
* Commit a persistence transaction
- *
- * @param context
- * @throws IOException
+ * @param context
+ * @throws IOException
*
* @see PersistenceAdapter#beginTransaction(ConnectionContext context)
*/
@@ -132,45 +106,40 @@ public interface PersistenceAdapter extends Service {
/**
* Rollback a persistence transaction
- *
- * @param context
- * @throws IOException
+ * @param context
+ * @throws IOException
*
* @see PersistenceAdapter#beginTransaction(ConnectionContext context)
*/
void rollbackTransaction(ConnectionContext context) throws IOException;
-
+
/**
- *
+ *
* @return last broker sequence
* @throws IOException
*/
long getLastMessageBrokerSequenceId() throws IOException;
-
+
/**
* Delete's all the messages in the persistent store.
- *
+ *
* @throws IOException
*/
void deleteAllMessages() throws IOException;
-
+
/**
- * @param usageManager
- * The UsageManager that is controlling the broker's memory
- * usage.
+ * @param usageManager The UsageManager that is controlling the broker's memory usage.
*/
void setUsageManager(SystemUsage usageManager);
-
+
/**
* Set the name of the broker using the adapter
- *
* @param brokerName
*/
void setBrokerName(String brokerName);
-
+
/**
* Set the directory where any data files should be created
- *
* @param dir
*/
void setDirectory(File dir);
@@ -179,30 +148,26 @@ public interface PersistenceAdapter extends Service {
* @return the directory used by the persistence adaptor
*/
File getDirectory();
-
+
/**
* checkpoint any
- *
- * @param sync
- * @throws IOException
+ * @param sync
+ * @throws IOException
*
*/
void checkpoint(boolean sync) throws IOException;
-
+
/**
* A hint to return the size of the store on disk
- *
* @return disk space used in bytes of 0 if not implemented
*/
long size();
/**
- * return the last stored producer sequenceId for this producer Id used to
- * suppress duplicate sends on failover reconnect at the transport when a
- * reconnect occurs
- *
- * @param id
- * the producerId to find a sequenceId for
+ * return the last stored producer sequenceId for this producer Id
+ * used to suppress duplicate sends on failover reconnect at the transport
+ * when a reconnect occurs
+ * @param id the producerId to find a sequenceId for
* @return the last stored sequence id or -1 if no suppression needed
*/
long getLastProducerSequenceId(ProducerId id) throws IOException;
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-broker/src/main/java/org/apache/activemq/store/memory/MemoryPersistenceAdapter.java
----------------------------------------------------------------------
diff --git a/activemq-broker/src/main/java/org/apache/activemq/store/memory/MemoryPersistenceAdapter.java b/activemq-broker/src/main/java/org/apache/activemq/store/memory/MemoryPersistenceAdapter.java
index 73ea104..0fd6bfc 100755
--- a/activemq-broker/src/main/java/org/apache/activemq/store/memory/MemoryPersistenceAdapter.java
+++ b/activemq-broker/src/main/java/org/apache/activemq/store/memory/MemoryPersistenceAdapter.java
@@ -24,7 +24,6 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.activemq.broker.ConnectionContext;
-import org.apache.activemq.broker.scheduler.JobSchedulerStore;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
@@ -40,7 +39,7 @@ import org.slf4j.LoggerFactory;
/**
* @org.apache.xbean.XBean
- *
+ *
*/
public class MemoryPersistenceAdapter implements PersistenceAdapter {
private static final Logger LOG = LoggerFactory.getLogger(MemoryPersistenceAdapter.class);
@@ -50,7 +49,6 @@ public class MemoryPersistenceAdapter implements PersistenceAdapter {
ConcurrentHashMap<ActiveMQDestination, MessageStore> queues = new ConcurrentHashMap<ActiveMQDestination, MessageStore>();
private boolean useExternalMessageReferences;
- @Override
public Set<ActiveMQDestination> getDestinations() {
Set<ActiveMQDestination> rc = new HashSet<ActiveMQDestination>(queues.size() + topics.size());
for (Iterator<ActiveMQDestination> iter = queues.keySet().iterator(); iter.hasNext();) {
@@ -66,7 +64,6 @@ public class MemoryPersistenceAdapter implements PersistenceAdapter {
return new MemoryPersistenceAdapter();
}
- @Override
public MessageStore createQueueMessageStore(ActiveMQQueue destination) throws IOException {
MessageStore rc = queues.get(destination);
if (rc == null) {
@@ -79,7 +76,6 @@ public class MemoryPersistenceAdapter implements PersistenceAdapter {
return rc;
}
- @Override
public TopicMessageStore createTopicMessageStore(ActiveMQTopic destination) throws IOException {
TopicMessageStore rc = topics.get(destination);
if (rc == null) {
@@ -97,7 +93,6 @@ public class MemoryPersistenceAdapter implements PersistenceAdapter {
*
* @param destination Destination to forget
*/
- @Override
public void removeQueueMessageStore(ActiveMQQueue destination) {
queues.remove(destination);
}
@@ -107,12 +102,10 @@ public class MemoryPersistenceAdapter implements PersistenceAdapter {
*
* @param destination Destination to forget
*/
- @Override
public void removeTopicMessageStore(ActiveMQTopic destination) {
topics.remove(destination);
}
- @Override
public TransactionStore createTransactionStore() throws IOException {
if (transactionStore == null) {
transactionStore = new MemoryTransactionStore(this);
@@ -120,32 +113,25 @@ public class MemoryPersistenceAdapter implements PersistenceAdapter {
return transactionStore;
}
- @Override
public void beginTransaction(ConnectionContext context) {
}
- @Override
public void commitTransaction(ConnectionContext context) {
}
- @Override
public void rollbackTransaction(ConnectionContext context) {
}
- @Override
public void start() throws Exception {
}
- @Override
public void stop() throws Exception {
}
- @Override
public long getLastMessageBrokerSequenceId() throws IOException {
return 0;
}
- @Override
public void deleteAllMessages() throws IOException {
for (Iterator<TopicMessageStore> iter = topics.values().iterator(); iter.hasNext();) {
MemoryMessageStore store = asMemoryMessageStore(iter.next());
@@ -191,52 +177,38 @@ public class MemoryPersistenceAdapter implements PersistenceAdapter {
* @param usageManager The UsageManager that is controlling the broker's
* memory usage.
*/
- @Override
public void setUsageManager(SystemUsage usageManager) {
}
- @Override
public String toString() {
return "MemoryPersistenceAdapter";
}
- @Override
public void setBrokerName(String brokerName) {
}
- @Override
public void setDirectory(File dir) {
}
-
- @Override
+
public File getDirectory(){
return null;
}
- @Override
public void checkpoint(boolean sync) throws IOException {
}
-
- @Override
+
public long size(){
return 0;
}
-
+
public void setCreateTransactionStore(boolean create) throws IOException {
if (create) {
createTransactionStore();
}
}
- @Override
public long getLastProducerSequenceId(ProducerId id) {
// memory map does duplicate suppression
return -1;
}
-
- @Override
- public JobSchedulerStore createJobSchedulerStore() throws IOException, UnsupportedOperationException {
- // We could eventuall implement an in memory scheduler.
- throw new UnsupportedOperationException();
- }
}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-broker/src/main/java/org/apache/activemq/util/IOHelper.java
----------------------------------------------------------------------
diff --git a/activemq-broker/src/main/java/org/apache/activemq/util/IOHelper.java b/activemq-broker/src/main/java/org/apache/activemq/util/IOHelper.java
index 2a70194..a623de9 100644
--- a/activemq-broker/src/main/java/org/apache/activemq/util/IOHelper.java
+++ b/activemq-broker/src/main/java/org/apache/activemq/util/IOHelper.java
@@ -61,9 +61,8 @@ public final class IOHelper {
}
/**
- * Converts any string into a string that is safe to use as a file name. The
- * result will only include ascii characters and numbers, and the "-","_",
- * and "." characters.
+ * Converts any string into a string that is safe to use as a file name.
+ * The result will only include ascii characters and numbers, and the "-","_", and "." characters.
*
* @param name
* @return
@@ -77,16 +76,15 @@ public final class IOHelper {
}
/**
- * Converts any string into a string that is safe to use as a file name. The
- * result will only include ascii characters and numbers, and the "-","_",
- * and "." characters.
+ * Converts any string into a string that is safe to use as a file name.
+ * The result will only include ascii characters and numbers, and the "-","_", and "." characters.
*
* @param name
* @param dirSeparators
* @param maxFileLength
* @return
*/
- public static String toFileSystemSafeName(String name, boolean dirSeparators, int maxFileLength) {
+ public static String toFileSystemSafeName(String name,boolean dirSeparators,int maxFileLength) {
int size = name.length();
StringBuffer rc = new StringBuffer(size * 2);
for (int i = 0; i < size; i++) {
@@ -94,7 +92,8 @@ public final class IOHelper {
boolean valid = c >= 'a' && c <= 'z';
valid = valid || (c >= 'A' && c <= 'Z');
valid = valid || (c >= '0' && c <= '9');
- valid = valid || (c == '_') || (c == '-') || (c == '.') || (c == '#') || (dirSeparators && ((c == '/') || (c == '\\')));
+ valid = valid || (c == '_') || (c == '-') || (c == '.') || (c=='#')
+ ||(dirSeparators && ( (c == '/') || (c == '\\')));
if (valid) {
rc.append(c);
@@ -106,7 +105,7 @@ public final class IOHelper {
}
String result = rc.toString();
if (result.length() > maxFileLength) {
- result = result.substring(result.length() - maxFileLength, result.length());
+ result = result.substring(result.length()-maxFileLength,result.length());
}
return result;
}
@@ -169,7 +168,8 @@ public final class IOHelper {
} else {
for (int i = 0; i < files.length; i++) {
File file = files[i];
- if (file.getName().equals(".") || file.getName().equals("..")) {
+ if (file.getName().equals(".")
+ || file.getName().equals("..")) {
continue;
}
if (file.isDirectory()) {
@@ -190,27 +190,6 @@ public final class IOHelper {
}
}
- public static void moveFiles(File srcDirectory, File targetDirectory, FilenameFilter filter) throws IOException {
- if (!srcDirectory.isDirectory()) {
- throw new IOException("source is not a directory");
- }
-
- if (targetDirectory.exists() && !targetDirectory.isDirectory()) {
- throw new IOException("target exists and is not a directory");
- } else {
- mkdirs(targetDirectory);
- }
-
- List<File> filesToMove = new ArrayList<File>();
- getFiles(srcDirectory, filesToMove, filter);
-
- for (File file : filesToMove) {
- if (!file.isDirectory()) {
- moveFile(file, targetDirectory);
- }
- }
- }
-
public static void copyFile(File src, File dest) throws IOException {
copyFile(src, dest, null);
}
@@ -243,32 +222,32 @@ public final class IOHelper {
File parent = src.getParentFile();
String fromPath = from.getAbsolutePath();
if (parent.getAbsolutePath().equals(fromPath)) {
- // one level down
+ //one level down
result = to;
- } else {
+ }else {
String parentPath = parent.getAbsolutePath();
String path = parentPath.substring(fromPath.length());
- result = new File(to.getAbsolutePath() + File.separator + path);
+ result = new File(to.getAbsolutePath()+File.separator+path);
}
return result;
}
- static List<File> getFiles(File dir, FilenameFilter filter) {
+ static List<File> getFiles(File dir,FilenameFilter filter){
List<File> result = new ArrayList<File>();
- getFiles(dir, result, filter);
+ getFiles(dir,result,filter);
return result;
}
- static void getFiles(File dir, List<File> list, FilenameFilter filter) {
+ static void getFiles(File dir,List<File> list,FilenameFilter filter) {
if (!list.contains(dir)) {
list.add(dir);
- String[] fileNames = dir.list(filter);
- for (int i = 0; i < fileNames.length; i++) {
- File f = new File(dir, fileNames[i]);
+ String[] fileNames=dir.list(filter);
+ for (int i =0; i < fileNames.length;i++) {
+ File f = new File(dir,fileNames[i]);
if (f.isFile()) {
list.add(f);
- } else {
- getFiles(dir, list, filter);
+ }else {
+ getFiles(dir,list,filter);
}
}
}
@@ -307,13 +286,12 @@ public final class IOHelper {
public static void mkdirs(File dir) throws IOException {
if (dir.exists()) {
if (!dir.isDirectory()) {
- throw new IOException("Failed to create directory '" + dir +
- "', regular file already existed with that name");
+ throw new IOException("Failed to create directory '" + dir +"', regular file already existed with that name");
}
} else {
if (!dir.mkdirs()) {
- throw new IOException("Failed to create directory '" + dir + "'");
+ throw new IOException("Failed to create directory '" + dir+"'");
}
}
}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-jdbc-store/src/main/java/org/apache/activemq/store/jdbc/JDBCPersistenceAdapter.java
----------------------------------------------------------------------
diff --git a/activemq-jdbc-store/src/main/java/org/apache/activemq/store/jdbc/JDBCPersistenceAdapter.java b/activemq-jdbc-store/src/main/java/org/apache/activemq/store/jdbc/JDBCPersistenceAdapter.java
index a3a8250..7ff4ae0 100755
--- a/activemq-jdbc-store/src/main/java/org/apache/activemq/store/jdbc/JDBCPersistenceAdapter.java
+++ b/activemq-jdbc-store/src/main/java/org/apache/activemq/store/jdbc/JDBCPersistenceAdapter.java
@@ -34,7 +34,6 @@ import org.apache.activemq.ActiveMQMessageAudit;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.broker.ConnectionContext;
import org.apache.activemq.broker.Locker;
-import org.apache.activemq.broker.scheduler.JobSchedulerStore;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
@@ -423,7 +422,6 @@ public class JDBCPersistenceAdapter extends DataSourceServiceSupport implements
this.lockDataSource = dataSource;
}
- @Override
public BrokerService getBrokerService() {
return brokerService;
}
@@ -848,9 +846,4 @@ public class JDBCPersistenceAdapter extends DataSourceServiceSupport implements
}
return result;
}
-
- @Override
- public JobSchedulerStore createJobSchedulerStore() throws IOException, UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-jdbc-store/src/main/java/org/apache/activemq/store/journal/JournalPersistenceAdapter.java
----------------------------------------------------------------------
diff --git a/activemq-jdbc-store/src/main/java/org/apache/activemq/store/journal/JournalPersistenceAdapter.java b/activemq-jdbc-store/src/main/java/org/apache/activemq/store/journal/JournalPersistenceAdapter.java
index cc5282f..565fc9f 100755
--- a/activemq-jdbc-store/src/main/java/org/apache/activemq/store/journal/JournalPersistenceAdapter.java
+++ b/activemq-jdbc-store/src/main/java/org/apache/activemq/store/journal/JournalPersistenceAdapter.java
@@ -31,7 +31,6 @@ import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
-
import org.apache.activeio.journal.InvalidRecordLocationException;
import org.apache.activeio.journal.Journal;
import org.apache.activeio.journal.JournalEventListener;
@@ -41,7 +40,6 @@ import org.apache.activeio.packet.Packet;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.broker.BrokerServiceAware;
import org.apache.activemq.broker.ConnectionContext;
-import org.apache.activemq.broker.scheduler.JobSchedulerStore;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
@@ -80,14 +78,14 @@ import org.slf4j.LoggerFactory;
* An implementation of {@link PersistenceAdapter} designed for use with a
* {@link Journal} and then check pointing asynchronously on a timeout with some
* other long term persistent storage.
- *
+ *
* @org.apache.xbean.XBean
- *
+ *
*/
public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEventListener, UsageListener, BrokerServiceAware {
private BrokerService brokerService;
-
+
protected Scheduler scheduler;
private static final Logger LOG = LoggerFactory.getLogger(JournalPersistenceAdapter.class);
@@ -120,9 +118,9 @@ public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEve
private TaskRunnerFactory taskRunnerFactory;
private File directory;
- public JournalPersistenceAdapter() {
+ public JournalPersistenceAdapter() {
}
-
+
public JournalPersistenceAdapter(Journal journal, PersistenceAdapter longTermPersistence, TaskRunnerFactory taskRunnerFactory) throws IOException {
setJournal(journal);
setTaskRunnerFactory(taskRunnerFactory);
@@ -137,14 +135,13 @@ public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEve
this.journal = journal;
journal.setJournalEventListener(this);
}
-
+
public void setPersistenceAdapter(PersistenceAdapter longTermPersistence) {
this.longTermPersistence = longTermPersistence;
}
-
+
final Runnable createPeriodicCheckpointTask() {
return new Runnable() {
- @Override
public void run() {
long lastTime = 0;
synchronized (this) {
@@ -161,13 +158,11 @@ public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEve
* @param usageManager The UsageManager that is controlling the
* destination's memory usage.
*/
- @Override
public void setUsageManager(SystemUsage usageManager) {
this.usageManager = usageManager;
longTermPersistence.setUsageManager(usageManager);
}
- @Override
public Set<ActiveMQDestination> getDestinations() {
Set<ActiveMQDestination> destinations = new HashSet<ActiveMQDestination>(longTermPersistence.getDestinations());
destinations.addAll(queues.keySet());
@@ -183,7 +178,6 @@ public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEve
}
}
- @Override
public MessageStore createQueueMessageStore(ActiveMQQueue destination) throws IOException {
JournalMessageStore store = queues.get(destination);
if (store == null) {
@@ -194,7 +188,6 @@ public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEve
return store;
}
- @Override
public TopicMessageStore createTopicMessageStore(ActiveMQTopic destinationName) throws IOException {
JournalTopicMessageStore store = topics.get(destinationName);
if (store == null) {
@@ -210,7 +203,6 @@ public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEve
*
* @param destination Destination to forget
*/
- @Override
public void removeQueueMessageStore(ActiveMQQueue destination) {
queues.remove(destination);
}
@@ -220,37 +212,30 @@ public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEve
*
* @param destination Destination to forget
*/
- @Override
public void removeTopicMessageStore(ActiveMQTopic destination) {
topics.remove(destination);
}
- @Override
public TransactionStore createTransactionStore() throws IOException {
return transactionStore;
}
- @Override
public long getLastMessageBrokerSequenceId() throws IOException {
return longTermPersistence.getLastMessageBrokerSequenceId();
}
- @Override
public void beginTransaction(ConnectionContext context) throws IOException {
longTermPersistence.beginTransaction(context);
}
- @Override
public void commitTransaction(ConnectionContext context) throws IOException {
longTermPersistence.commitTransaction(context);
}
- @Override
public void rollbackTransaction(ConnectionContext context) throws IOException {
longTermPersistence.rollbackTransaction(context);
}
- @Override
public synchronized void start() throws Exception {
if (!started.compareAndSet(false, true)) {
return;
@@ -261,14 +246,12 @@ public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEve
}
checkpointTask = taskRunnerFactory.createTaskRunner(new Task() {
- @Override
public boolean iterate() {
return doCheckpoint();
}
}, "ActiveMQ Journal Checkpoint Worker");
checkpointExecutor = new ThreadPoolExecutor(maxCheckpointWorkers, maxCheckpointWorkers, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new ThreadFactory() {
- @Override
public Thread newThread(Runnable runable) {
Thread t = new Thread(runable, "Journal checkpoint worker");
t.setPriority(7);
@@ -296,7 +279,6 @@ public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEve
}
- @Override
public void stop() throws Exception {
this.usageManager.getMemoryUsage().removeUsageListener(this);
@@ -348,17 +330,16 @@ public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEve
/**
* The Journal give us a call back so that we can move old data out of the
* journal. Taking a checkpoint does this for us.
- *
+ *
* @see org.apache.activemq.journal.JournalEventListener#overflowNotification(org.apache.activemq.journal.RecordLocation)
*/
- @Override
public void overflowNotification(RecordLocation safeLocation) {
checkpoint(false, true);
}
/**
* When we checkpoint we move all the journalled data to long term storage.
- *
+ *
*/
public void checkpoint(boolean sync, boolean fullCheckpoint) {
try {
@@ -388,14 +369,13 @@ public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEve
}
}
- @Override
public void checkpoint(boolean sync) {
checkpoint(sync, sync);
}
/**
* This does the actual checkpoint.
- *
+ *
* @return
*/
public boolean doCheckpoint() {
@@ -418,7 +398,7 @@ public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEve
// We do many partial checkpoints (fullCheckpoint==false) to move
// topic messages
// to long term store as soon as possible.
- //
+ //
// We want to avoid doing that for queue messages since removes the
// come in the same
// checkpoint cycle will nullify the previous message add.
@@ -431,7 +411,6 @@ public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEve
try {
final JournalMessageStore ms = iterator.next();
FutureTask<RecordLocation> task = new FutureTask<RecordLocation>(new Callable<RecordLocation>() {
- @Override
public RecordLocation call() throws Exception {
return ms.checkpoint();
}
@@ -449,7 +428,6 @@ public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEve
try {
final JournalTopicMessageStore ms = iterator.next();
FutureTask<RecordLocation> task = new FutureTask<RecordLocation>(new Callable<RecordLocation>() {
- @Override
public RecordLocation call() throws Exception {
return ms.checkpoint();
}
@@ -527,7 +505,7 @@ public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEve
/**
* Move all the messages that were in the journal into long term storage. We
* just replay and do a checkpoint.
- *
+ *
* @throws IOException
* @throws IOException
* @throws InvalidRecordLocationException
@@ -666,11 +644,11 @@ public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEve
public RecordLocation writeCommand(DataStructure command, boolean sync) throws IOException {
if (started.get()) {
try {
- return journal.write(toPacket(wireFormat.marshal(command)), sync);
+ return journal.write(toPacket(wireFormat.marshal(command)), sync);
} catch (IOException ioe) {
- LOG.error("Cannot write to the journal", ioe);
- brokerService.handleIOException(ioe);
- throw ioe;
+ LOG.error("Cannot write to the journal", ioe);
+ brokerService.handleIOException(ioe);
+ throw ioe;
}
}
throw new IOException("closed");
@@ -682,7 +660,6 @@ public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEve
return writeCommand(trace, sync);
}
- @Override
public void onUsageChanged(Usage usage, int oldPercentUsage, int newPercentUsage) {
newPercentUsage = (newPercentUsage / 10) * 10;
oldPercentUsage = (oldPercentUsage / 10) * 10;
@@ -696,7 +673,6 @@ public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEve
return transactionStore;
}
- @Override
public void deleteAllMessages() throws IOException {
try {
JournalTrace trace = new JournalTrace();
@@ -759,7 +735,6 @@ public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEve
return new ByteSequence(sequence.getData(), sequence.getOffset(), sequence.getLength());
}
- @Override
public void setBrokerName(String brokerName) {
longTermPersistence.setBrokerName(brokerName);
}
@@ -769,22 +744,18 @@ public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEve
return "JournalPersistenceAdapter(" + longTermPersistence + ")";
}
- @Override
public void setDirectory(File dir) {
this.directory=dir;
}
-
- @Override
+
public File getDirectory(){
return directory;
}
-
- @Override
+
public long size(){
return 0;
}
- @Override
public void setBrokerService(BrokerService brokerService) {
this.brokerService = brokerService;
PersistenceAdapter pa = getLongTermPersistence();
@@ -793,14 +764,8 @@ public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEve
}
}
- @Override
public long getLastProducerSequenceId(ProducerId id) {
return -1;
}
- @Override
- public JobSchedulerStore createJobSchedulerStore() throws IOException, UnsupportedOperationException {
- return longTermPersistence.createJobSchedulerStore();
- }
-
}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/AbstractKahaDBMetaData.java
----------------------------------------------------------------------
diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/AbstractKahaDBMetaData.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/AbstractKahaDBMetaData.java
deleted file mode 100644
index edb2750..0000000
--- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/AbstractKahaDBMetaData.java
+++ /dev/null
@@ -1,57 +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.store.kahadb;
-
-import org.apache.activemq.store.kahadb.disk.journal.Location;
-import org.apache.activemq.store.kahadb.disk.page.Page;
-
-public abstract class AbstractKahaDBMetaData<T> implements KahaDBMetaData<T> {
-
- private int state;
- private Location lastUpdateLocation;
- private Page<T> page;
-
- @Override
- public Page<T> getPage() {
- return page;
- }
-
- @Override
- public int getState() {
- return state;
- }
-
- @Override
- public Location getLastUpdateLocation() {
- return lastUpdateLocation;
- }
-
- @Override
- public void setPage(Page<T> page) {
- this.page = page;
- }
-
- @Override
- public void setState(int value) {
- this.state = value;
- }
-
- @Override
- public void setLastUpdateLocation(Location location) {
- this.lastUpdateLocation = location;
- }
-}
[4/5] activemq git commit: Revert
"https://issues.apache.org/jira/browse/AMQ-3758"
Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/AbstractKahaDBStore.java
----------------------------------------------------------------------
diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/AbstractKahaDBStore.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/AbstractKahaDBStore.java
deleted file mode 100644
index 6003c87..0000000
--- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/AbstractKahaDBStore.java
+++ /dev/null
@@ -1,745 +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.store.kahadb;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Date;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-import org.apache.activemq.broker.LockableServiceSupport;
-import org.apache.activemq.broker.Locker;
-import org.apache.activemq.store.SharedFileLocker;
-import org.apache.activemq.store.kahadb.data.KahaEntryType;
-import org.apache.activemq.store.kahadb.data.KahaTraceCommand;
-import org.apache.activemq.store.kahadb.disk.journal.Journal;
-import org.apache.activemq.store.kahadb.disk.journal.Location;
-import org.apache.activemq.store.kahadb.disk.page.PageFile;
-import org.apache.activemq.store.kahadb.disk.page.Transaction;
-import org.apache.activemq.util.ByteSequence;
-import org.apache.activemq.util.DataByteArrayInputStream;
-import org.apache.activemq.util.DataByteArrayOutputStream;
-import org.apache.activemq.util.IOHelper;
-import org.apache.activemq.util.ServiceStopper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class AbstractKahaDBStore extends LockableServiceSupport {
-
- static final Logger LOG = LoggerFactory.getLogger(AbstractKahaDBStore.class);
-
- public static final String PROPERTY_LOG_SLOW_ACCESS_TIME = "org.apache.activemq.store.kahadb.LOG_SLOW_ACCESS_TIME";
- public static final int LOG_SLOW_ACCESS_TIME = Integer.getInteger(PROPERTY_LOG_SLOW_ACCESS_TIME, 0);
-
- protected File directory;
- protected PageFile pageFile;
- protected Journal journal;
- protected AtomicLong journalSize = new AtomicLong(0);
- protected boolean failIfDatabaseIsLocked;
- protected long checkpointInterval = 5*1000;
- protected long cleanupInterval = 30*1000;
- protected boolean checkForCorruptJournalFiles = false;
- protected boolean checksumJournalFiles = true;
- protected boolean forceRecoverIndex = false;
- protected int journalMaxFileLength = Journal.DEFAULT_MAX_FILE_LENGTH;
- protected int journalMaxWriteBatchSize = Journal.DEFAULT_MAX_WRITE_BATCH_SIZE;
- protected boolean archiveCorruptedIndex = false;
- protected boolean enableIndexWriteAsync = false;
- protected boolean enableJournalDiskSyncs = false;
- protected boolean deleteAllJobs = false;
- protected int indexWriteBatchSize = PageFile.DEFAULT_WRITE_BATCH_SIZE;
- protected boolean useIndexLFRUEviction = false;
- protected float indexLFUEvictionFactor = 0.2f;
- protected boolean ignoreMissingJournalfiles = false;
- protected int indexCacheSize = 1000;
- protected boolean enableIndexDiskSyncs = true;
- protected boolean enableIndexRecoveryFile = true;
- protected boolean enableIndexPageCaching = true;
- protected boolean archiveDataLogs;
- protected boolean purgeStoreOnStartup;
- protected File directoryArchive;
-
- protected AtomicBoolean opened = new AtomicBoolean();
- protected Thread checkpointThread;
- protected final Object checkpointThreadLock = new Object();
- protected ReentrantReadWriteLock checkpointLock = new ReentrantReadWriteLock();
- protected ReentrantReadWriteLock indexLock = new ReentrantReadWriteLock();
-
- /**
- * @return the name to give this store's PageFile instance.
- */
- protected abstract String getPageFileName();
-
- /**
- * @return the location of the data directory if no set by configuration.
- */
- protected abstract File getDefaultDataDirectory();
-
- /**
- * Loads the store from disk.
- *
- * Based on configuration this method can either load an existing store or it can purge
- * an existing store and start in a clean state.
- *
- * @throws IOException if an error occurs during the load.
- */
- public abstract void load() throws IOException;
-
- /**
- * Unload the state of the Store to disk and shuts down all resources assigned to this
- * KahaDB store implementation.
- *
- * @throws IOException if an error occurs during the store unload.
- */
- public abstract void unload() throws IOException;
-
- @Override
- protected void doStart() throws Exception {
- this.indexLock.writeLock().lock();
- if (getDirectory() == null) {
- setDirectory(getDefaultDataDirectory());
- }
- IOHelper.mkdirs(getDirectory());
- try {
- if (isPurgeStoreOnStartup()) {
- getJournal().start();
- getJournal().delete();
- getJournal().close();
- journal = null;
- getPageFile().delete();
- LOG.info("{} Persistence store purged.", this);
- setPurgeStoreOnStartup(false);
- }
-
- load();
- store(new KahaTraceCommand().setMessage("LOADED " + new Date()));
- } finally {
- this.indexLock.writeLock().unlock();
- }
- }
-
- @Override
- protected void doStop(ServiceStopper stopper) throws Exception {
- unload();
- }
-
- public PageFile getPageFile() {
- if (pageFile == null) {
- pageFile = createPageFile();
- }
- return pageFile;
- }
-
- public Journal getJournal() throws IOException {
- if (journal == null) {
- journal = createJournal();
- }
- return journal;
- }
-
- public File getDirectory() {
- return directory;
- }
-
- public void setDirectory(File directory) {
- this.directory = directory;
- }
-
- public boolean isArchiveCorruptedIndex() {
- return archiveCorruptedIndex;
- }
-
- public void setArchiveCorruptedIndex(boolean archiveCorruptedIndex) {
- this.archiveCorruptedIndex = archiveCorruptedIndex;
- }
-
- public boolean isFailIfDatabaseIsLocked() {
- return failIfDatabaseIsLocked;
- }
-
- public void setFailIfDatabaseIsLocked(boolean failIfDatabaseIsLocked) {
- this.failIfDatabaseIsLocked = failIfDatabaseIsLocked;
- }
-
- public boolean isCheckForCorruptJournalFiles() {
- return checkForCorruptJournalFiles;
- }
-
- public void setCheckForCorruptJournalFiles(boolean checkForCorruptJournalFiles) {
- this.checkForCorruptJournalFiles = checkForCorruptJournalFiles;
- }
-
- public long getCheckpointInterval() {
- return checkpointInterval;
- }
-
- public void setCheckpointInterval(long checkpointInterval) {
- this.checkpointInterval = checkpointInterval;
- }
-
- public long getCleanupInterval() {
- return cleanupInterval;
- }
-
- public void setCleanupInterval(long cleanupInterval) {
- this.cleanupInterval = cleanupInterval;
- }
-
- public boolean isChecksumJournalFiles() {
- return checksumJournalFiles;
- }
-
- public void setChecksumJournalFiles(boolean checksumJournalFiles) {
- this.checksumJournalFiles = checksumJournalFiles;
- }
-
- public boolean isForceRecoverIndex() {
- return forceRecoverIndex;
- }
-
- public void setForceRecoverIndex(boolean forceRecoverIndex) {
- this.forceRecoverIndex = forceRecoverIndex;
- }
-
- public int getJournalMaxFileLength() {
- return journalMaxFileLength;
- }
-
- public void setJournalMaxFileLength(int journalMaxFileLength) {
- this.journalMaxFileLength = journalMaxFileLength;
- }
-
- public int getJournalMaxWriteBatchSize() {
- return journalMaxWriteBatchSize;
- }
-
- public void setJournalMaxWriteBatchSize(int journalMaxWriteBatchSize) {
- this.journalMaxWriteBatchSize = journalMaxWriteBatchSize;
- }
-
- public boolean isEnableIndexWriteAsync() {
- return enableIndexWriteAsync;
- }
-
- public void setEnableIndexWriteAsync(boolean enableIndexWriteAsync) {
- this.enableIndexWriteAsync = enableIndexWriteAsync;
- }
-
- public boolean isEnableJournalDiskSyncs() {
- return enableJournalDiskSyncs;
- }
-
- public void setEnableJournalDiskSyncs(boolean syncWrites) {
- this.enableJournalDiskSyncs = syncWrites;
- }
-
- public boolean isDeleteAllJobs() {
- return deleteAllJobs;
- }
-
- public void setDeleteAllJobs(boolean deleteAllJobs) {
- this.deleteAllJobs = deleteAllJobs;
- }
-
- /**
- * @return the archiveDataLogs
- */
- public boolean isArchiveDataLogs() {
- return this.archiveDataLogs;
- }
-
- /**
- * @param archiveDataLogs the archiveDataLogs to set
- */
- public void setArchiveDataLogs(boolean archiveDataLogs) {
- this.archiveDataLogs = archiveDataLogs;
- }
-
- /**
- * @return the directoryArchive
- */
- public File getDirectoryArchive() {
- return this.directoryArchive;
- }
-
- /**
- * @param directoryArchive the directoryArchive to set
- */
- public void setDirectoryArchive(File directoryArchive) {
- this.directoryArchive = directoryArchive;
- }
-
- public int getIndexCacheSize() {
- return indexCacheSize;
- }
-
- public void setIndexCacheSize(int indexCacheSize) {
- this.indexCacheSize = indexCacheSize;
- }
-
- public int getIndexWriteBatchSize() {
- return indexWriteBatchSize;
- }
-
- public void setIndexWriteBatchSize(int indexWriteBatchSize) {
- this.indexWriteBatchSize = indexWriteBatchSize;
- }
-
- public boolean isUseIndexLFRUEviction() {
- return useIndexLFRUEviction;
- }
-
- public void setUseIndexLFRUEviction(boolean useIndexLFRUEviction) {
- this.useIndexLFRUEviction = useIndexLFRUEviction;
- }
-
- public float getIndexLFUEvictionFactor() {
- return indexLFUEvictionFactor;
- }
-
- public void setIndexLFUEvictionFactor(float indexLFUEvictionFactor) {
- this.indexLFUEvictionFactor = indexLFUEvictionFactor;
- }
-
- public boolean isEnableIndexDiskSyncs() {
- return enableIndexDiskSyncs;
- }
-
- public void setEnableIndexDiskSyncs(boolean enableIndexDiskSyncs) {
- this.enableIndexDiskSyncs = enableIndexDiskSyncs;
- }
-
- public boolean isEnableIndexRecoveryFile() {
- return enableIndexRecoveryFile;
- }
-
- public void setEnableIndexRecoveryFile(boolean enableIndexRecoveryFile) {
- this.enableIndexRecoveryFile = enableIndexRecoveryFile;
- }
-
- public boolean isEnableIndexPageCaching() {
- return enableIndexPageCaching;
- }
-
- public void setEnableIndexPageCaching(boolean enableIndexPageCaching) {
- this.enableIndexPageCaching = enableIndexPageCaching;
- }
-
- public boolean isPurgeStoreOnStartup() {
- return this.purgeStoreOnStartup;
- }
-
- public void setPurgeStoreOnStartup(boolean purge) {
- this.purgeStoreOnStartup = purge;
- }
-
- public boolean isIgnoreMissingJournalfiles() {
- return ignoreMissingJournalfiles;
- }
-
- public void setIgnoreMissingJournalfiles(boolean ignoreMissingJournalfiles) {
- this.ignoreMissingJournalfiles = ignoreMissingJournalfiles;
- }
-
- public long size() {
- if (!isStarted()) {
- return 0;
- }
- try {
- return journalSize.get() + pageFile.getDiskSize();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public Locker createDefaultLocker() throws IOException {
- SharedFileLocker locker = new SharedFileLocker();
- locker.setDirectory(this.getDirectory());
- return locker;
- }
-
- @Override
- public void init() throws Exception {
- }
-
- /**
- * Store a command in the Journal and process to update the Store index.
- *
- * @param command
- * The specific JournalCommand to store and process.
- *
- * @returns the Location where the data was written in the Journal.
- *
- * @throws IOException if an error occurs storing or processing the command.
- */
- public Location store(JournalCommand<?> command) throws IOException {
- return store(command, isEnableIndexDiskSyncs(), null, null, null);
- }
-
- /**
- * Store a command in the Journal and process to update the Store index.
- *
- * @param command
- * The specific JournalCommand to store and process.
- * @param sync
- * Should the store operation be done synchronously. (ignored if completion passed).
- *
- * @returns the Location where the data was written in the Journal.
- *
- * @throws IOException if an error occurs storing or processing the command.
- */
- public Location store(JournalCommand<?> command, boolean sync) throws IOException {
- return store(command, sync, null, null, null);
- }
-
- /**
- * Store a command in the Journal and process to update the Store index.
- *
- * @param command
- * The specific JournalCommand to store and process.
- * @param onJournalStoreComplete
- * The Runnable to call when the Journal write operation completes.
- *
- * @returns the Location where the data was written in the Journal.
- *
- * @throws IOException if an error occurs storing or processing the command.
- */
- public Location store(JournalCommand<?> command, Runnable onJournalStoreComplete) throws IOException {
- return store(command, isEnableIndexDiskSyncs(), null, null, onJournalStoreComplete);
- }
-
- /**
- * Store a command in the Journal and process to update the Store index.
- *
- * @param command
- * The specific JournalCommand to store and process.
- * @param sync
- * Should the store operation be done synchronously. (ignored if completion passed).
- * @param before
- * The Runnable instance to execute before performing the store and process operation.
- * @param after
- * The Runnable instance to execute after performing the store and process operation.
- *
- * @returns the Location where the data was written in the Journal.
- *
- * @throws IOException if an error occurs storing or processing the command.
- */
- public Location store(JournalCommand<?> command, boolean sync, Runnable before, Runnable after) throws IOException {
- return store(command, sync, before, after, null);
- }
-
- /**
- * All updated are are funneled through this method. The updates are converted to a
- * JournalMessage which is logged to the journal and then the data from the JournalMessage
- * is used to update the index just like it would be done during a recovery process.
- *
- * @param command
- * The specific JournalCommand to store and process.
- * @param sync
- * Should the store operation be done synchronously. (ignored if completion passed).
- * @param before
- * The Runnable instance to execute before performing the store and process operation.
- * @param after
- * The Runnable instance to execute after performing the store and process operation.
- * @param onJournalStoreComplete
- * Callback to be run when the journal write operation is complete.
- *
- * @returns the Location where the data was written in the Journal.
- *
- * @throws IOException if an error occurs storing or processing the command.
- */
- public Location store(JournalCommand<?> command, boolean sync, Runnable before, Runnable after, Runnable onJournalStoreComplete) throws IOException {
- try {
-
- if (before != null) {
- before.run();
- }
-
- ByteSequence sequence = toByteSequence(command);
- Location location;
- checkpointLock.readLock().lock();
- try {
-
- long start = System.currentTimeMillis();
- location = onJournalStoreComplete == null ? journal.write(sequence, sync) :
- journal.write(sequence, onJournalStoreComplete);
- long start2 = System.currentTimeMillis();
-
- process(command, location);
-
- long end = System.currentTimeMillis();
- if (LOG_SLOW_ACCESS_TIME > 0 && end - start > LOG_SLOW_ACCESS_TIME) {
- LOG.info("Slow KahaDB access: Journal append took: {} ms, Index update took {} ms",
- (start2-start), (end-start2));
- }
- } finally {
- checkpointLock.readLock().unlock();
- }
-
- if (after != null) {
- after.run();
- }
-
- if (checkpointThread != null && !checkpointThread.isAlive()) {
- startCheckpoint();
- }
- return location;
- } catch (IOException ioe) {
- LOG.error("KahaDB failed to store to Journal", ioe);
- if (brokerService != null) {
- brokerService.handleIOException(ioe);
- }
- throw ioe;
- }
- }
-
- /**
- * Loads a previously stored JournalMessage
- *
- * @param location
- * The location of the journal command to read.
- *
- * @return a new un-marshaled JournalCommand instance.
- *
- * @throws IOException if an error occurs reading the stored command.
- */
- protected JournalCommand<?> load(Location location) throws IOException {
- ByteSequence data = journal.read(location);
- DataByteArrayInputStream is = new DataByteArrayInputStream(data);
- byte readByte = is.readByte();
- KahaEntryType type = KahaEntryType.valueOf(readByte);
- if (type == null) {
- try {
- is.close();
- } catch (IOException e) {
- }
- throw new IOException("Could not load journal record. Invalid location: " + location);
- }
- JournalCommand<?> message = (JournalCommand<?>)type.createMessage();
- message.mergeFramed(is);
- return message;
- }
-
- /**
- * Process a stored or recovered JournalCommand instance and update the DB Index with the
- * state changes that this command produces. This can be called either as a new DB operation
- * or as a replay during recovery operations.
- *
- * @param command
- * The JournalCommand to process.
- * @param location
- * The location in the Journal where the command was written or read from.
- */
- protected abstract void process(JournalCommand<?> command, Location location) throws IOException;
-
- /**
- * Perform a checkpoint operation with optional cleanup.
- *
- * Called by the checkpoint background thread periodically to initiate a checkpoint operation
- * and if the cleanup flag is set a cleanup sweep should be done to allow for release of no
- * longer needed journal log files etc.
- *
- * @param cleanup
- * Should the method do a simple checkpoint or also perform a journal cleanup.
- *
- * @throws IOException if an error occurs during the checkpoint operation.
- */
- protected void checkpointUpdate(final boolean cleanup) throws IOException {
- checkpointLock.writeLock().lock();
- try {
- this.indexLock.writeLock().lock();
- try {
- pageFile.tx().execute(new Transaction.Closure<IOException>() {
- @Override
- public void execute(Transaction tx) throws IOException {
- checkpointUpdate(tx, cleanup);
- }
- });
- } finally {
- this.indexLock.writeLock().unlock();
- }
-
- } finally {
- checkpointLock.writeLock().unlock();
- }
- }
-
- /**
- * Perform the checkpoint update operation. If the cleanup flag is true then the
- * operation should also purge any unused Journal log files.
- *
- * This method must always be called with the checkpoint and index write locks held.
- *
- * @param tx
- * The TX under which to perform the checkpoint update.
- * @param cleanup
- * Should the checkpoint also do unused Journal file cleanup.
- *
- * @throws IOException if an error occurs while performing the checkpoint.
- */
- protected abstract void checkpointUpdate(Transaction tx, boolean cleanup) throws IOException;
-
- /**
- * Creates a new ByteSequence that represents the marshaled form of the given Journal Command.
- *
- * @param command
- * The Journal Command that should be marshaled to bytes for writing.
- *
- * @return the byte representation of the given journal command.
- *
- * @throws IOException if an error occurs while serializing the command.
- */
- protected ByteSequence toByteSequence(JournalCommand<?> data) throws IOException {
- int size = data.serializedSizeFramed();
- DataByteArrayOutputStream os = new DataByteArrayOutputStream(size + 1);
- os.writeByte(data.type().getNumber());
- data.writeFramed(os);
- return os.toByteSequence();
- }
-
- /**
- * Create the PageFile instance and configure it using the configuration options
- * currently set.
- *
- * @return the newly created and configured PageFile instance.
- */
- protected PageFile createPageFile() {
- PageFile index = new PageFile(getDirectory(), getPageFileName());
- index.setEnableWriteThread(isEnableIndexWriteAsync());
- index.setWriteBatchSize(getIndexWriteBatchSize());
- index.setPageCacheSize(getIndexCacheSize());
- index.setUseLFRUEviction(isUseIndexLFRUEviction());
- index.setLFUEvictionFactor(getIndexLFUEvictionFactor());
- index.setEnableDiskSyncs(isEnableIndexDiskSyncs());
- index.setEnableRecoveryFile(isEnableIndexRecoveryFile());
- index.setEnablePageCaching(isEnableIndexPageCaching());
- return index;
- }
-
- /**
- * Create a new Journal instance and configure it using the currently set configuration
- * options. If an archive directory is configured than this method will attempt to create
- * that directory if it does not already exist.
- *
- * @return the newly created an configured Journal instance.
- *
- * @throws IOException if an error occurs while creating the Journal object.
- */
- protected Journal createJournal() throws IOException {
- Journal manager = new Journal();
- manager.setDirectory(getDirectory());
- manager.setMaxFileLength(getJournalMaxFileLength());
- manager.setCheckForCorruptionOnStartup(isCheckForCorruptJournalFiles());
- manager.setChecksum(isChecksumJournalFiles() || isCheckForCorruptJournalFiles());
- manager.setWriteBatchSize(getJournalMaxWriteBatchSize());
- manager.setArchiveDataLogs(isArchiveDataLogs());
- manager.setSizeAccumulator(journalSize);
- manager.setEnableAsyncDiskSync(isEnableJournalDiskSyncs());
- if (getDirectoryArchive() != null) {
- IOHelper.mkdirs(getDirectoryArchive());
- manager.setDirectoryArchive(getDirectoryArchive());
- }
- return manager;
- }
-
- /**
- * Starts the checkpoint Thread instance if not already running and not disabled
- * by configuration.
- */
- protected void startCheckpoint() {
- if (checkpointInterval == 0 && cleanupInterval == 0) {
- LOG.info("periodic checkpoint/cleanup disabled, will ocurr on clean shutdown/restart");
- return;
- }
- synchronized (checkpointThreadLock) {
- boolean start = false;
- if (checkpointThread == null) {
- start = true;
- } else if (!checkpointThread.isAlive()) {
- start = true;
- LOG.info("KahaDB: Recovering checkpoint thread after death");
- }
- if (start) {
- checkpointThread = new Thread("ActiveMQ Journal Checkpoint Worker") {
- @Override
- public void run() {
- try {
- long lastCleanup = System.currentTimeMillis();
- long lastCheckpoint = System.currentTimeMillis();
- // Sleep for a short time so we can periodically check
- // to see if we need to exit this thread.
- long sleepTime = Math.min(checkpointInterval > 0 ? checkpointInterval : cleanupInterval, 500);
- while (opened.get()) {
- Thread.sleep(sleepTime);
- long now = System.currentTimeMillis();
- if( cleanupInterval > 0 && (now - lastCleanup >= cleanupInterval) ) {
- checkpointCleanup(true);
- lastCleanup = now;
- lastCheckpoint = now;
- } else if( checkpointInterval > 0 && (now - lastCheckpoint >= checkpointInterval )) {
- checkpointCleanup(false);
- lastCheckpoint = now;
- }
- }
- } catch (InterruptedException e) {
- // Looks like someone really wants us to exit this thread...
- } catch (IOException ioe) {
- LOG.error("Checkpoint failed", ioe);
- brokerService.handleIOException(ioe);
- }
- }
- };
-
- checkpointThread.setDaemon(true);
- checkpointThread.start();
- }
- }
- }
-
- /**
- * Called from the worker thread to start a checkpoint.
- *
- * This method ensure that the store is in an opened state and optionaly logs information
- * related to slow store access times.
- *
- * @param cleanup
- * Should a cleanup of the journal occur during the checkpoint operation.
- *
- * @throws IOException if an error occurs during the checkpoint operation.
- */
- protected void checkpointCleanup(final boolean cleanup) throws IOException {
- long start;
- this.indexLock.writeLock().lock();
- try {
- start = System.currentTimeMillis();
- if (!opened.get()) {
- return;
- }
- } finally {
- this.indexLock.writeLock().unlock();
- }
- checkpointUpdate(cleanup);
- long end = System.currentTimeMillis();
- if (LOG_SLOW_ACCESS_TIME > 0 && end - start > LOG_SLOW_ACCESS_TIME) {
- LOG.info("Slow KahaDB access: cleanup took {}", (end - start));
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/KahaDBMetaData.java
----------------------------------------------------------------------
diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/KahaDBMetaData.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/KahaDBMetaData.java
deleted file mode 100644
index defb238..0000000
--- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/KahaDBMetaData.java
+++ /dev/null
@@ -1,135 +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.store.kahadb;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-
-import org.apache.activemq.store.kahadb.disk.journal.Location;
-import org.apache.activemq.store.kahadb.disk.page.Page;
-import org.apache.activemq.store.kahadb.disk.page.Transaction;
-
-/**
- * Interface for the store meta data used to hold the index value and other needed
- * information to manage a KahaDB store instance.
- */
-public interface KahaDBMetaData<T> {
-
- /**
- * Indicates that this meta data instance has been opened and is active.
- */
- public static final int OPEN_STATE = 2;
-
- /**
- * Indicates that this meta data instance has been closed and is no longer active.
- */
- public static final int CLOSED_STATE = 1;
-
- /**
- * Gets the Page in the store PageFile where the KahaDBMetaData instance is stored.
- *
- * @return the Page to use to start access the KahaDBMetaData instance.
- */
- Page<T> getPage();
-
- /**
- * Sets the Page instance used to load and store the KahaDBMetaData instance.
- *
- * @param page
- * the new Page value to use.
- */
- void setPage(Page<T> page);
-
- /**
- * Gets the state flag of this meta data instance.
- *
- * @return the current state value for this instance.
- */
- int getState();
-
- /**
- * Sets the current value of the state flag.
- *
- * @param value
- * the new value to assign to the state flag.
- */
- void setState(int value);
-
- /**
- * Returns the Journal Location value that indicates that last recorded update
- * that was successfully performed for this KahaDB store implementation.
- *
- * @return the location of the last successful update location.
- */
- Location getLastUpdateLocation();
-
- /**
- * Updates the value of the last successful update.
- *
- * @param location
- * the new value to assign the last update location field.
- */
- void setLastUpdateLocation(Location location);
-
- /**
- * For a newly created KahaDBMetaData instance this method is called to allow
- * the instance to create all of it's internal indices and other state data.
- *
- * @param tx
- * the Transaction instance under which the operation is executed.
- *
- * @throws IOException if an error occurs while creating the meta data structures.
- */
- void initialize(Transaction tx) throws IOException;
-
- /**
- * Instructs this object to load its internal data structures from the KahaDB PageFile
- * and prepare itself for use.
- *
- * @param tx
- * the Transaction instance under which the operation is executed.
- *
- * @throws IOException if an error occurs while creating the meta data structures.
- */
- void load(Transaction tx) throws IOException;
-
- /**
- * Reads the serialized for of this object from the KadaDB PageFile and prepares it
- * for use. This method does not need to perform a full load of the meta data structures
- * only read in the information necessary to load them from the PageFile on a call to the
- * load method.
- *
- * @param in
- * the DataInput instance used to read this objects serialized form.
- *
- * @throws IOException if an error occurs while reading the serialized form.
- */
- void read(DataInput in) throws IOException;
-
- /**
- * Writes the object into a serialized form which can be read back in again using the
- * read method.
- *
- * @param out
- * the DataOutput instance to use to write the current state to a serialized form.
- *
- * @throws IOException if an error occurs while serializing this instance.
- */
- void write(DataOutput out) throws IOException;
-
-}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/KahaDBPersistenceAdapter.java
----------------------------------------------------------------------
diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/KahaDBPersistenceAdapter.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/KahaDBPersistenceAdapter.java
index 9b83a0e..e199d68 100644
--- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/KahaDBPersistenceAdapter.java
+++ b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/KahaDBPersistenceAdapter.java
@@ -31,7 +31,6 @@ import org.apache.activemq.broker.LockableServiceSupport;
import org.apache.activemq.broker.Locker;
import org.apache.activemq.broker.jmx.AnnotatedMBean;
import org.apache.activemq.broker.jmx.PersistenceAdapterView;
-import org.apache.activemq.broker.scheduler.JobSchedulerStore;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
@@ -40,14 +39,7 @@ import org.apache.activemq.command.ProducerId;
import org.apache.activemq.command.TransactionId;
import org.apache.activemq.command.XATransactionId;
import org.apache.activemq.protobuf.Buffer;
-import org.apache.activemq.store.JournaledStore;
-import org.apache.activemq.store.MessageStore;
-import org.apache.activemq.store.PersistenceAdapter;
-import org.apache.activemq.store.SharedFileLocker;
-import org.apache.activemq.store.TopicMessageStore;
-import org.apache.activemq.store.TransactionIdTransformer;
-import org.apache.activemq.store.TransactionIdTransformerAware;
-import org.apache.activemq.store.TransactionStore;
+import org.apache.activemq.store.*;
import org.apache.activemq.store.kahadb.data.KahaLocalTransactionId;
import org.apache.activemq.store.kahadb.data.KahaTransactionInfo;
import org.apache.activemq.store.kahadb.data.KahaXATransactionId;
@@ -667,9 +659,4 @@ public class KahaDBPersistenceAdapter extends LockableServiceSupport implements
public void setTransactionIdTransformer(TransactionIdTransformer transactionIdTransformer) {
getStore().setTransactionIdTransformer(transactionIdTransformer);
}
-
- @Override
- public JobSchedulerStore createJobSchedulerStore() throws IOException, UnsupportedOperationException {
- return this.letter.createJobSchedulerStore();
- }
}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/KahaDBStore.java
----------------------------------------------------------------------
diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/KahaDBStore.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/KahaDBStore.java
index 975cd05..60c0738 100644
--- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/KahaDBStore.java
+++ b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/KahaDBStore.java
@@ -42,7 +42,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.apache.activemq.broker.ConnectionContext;
import org.apache.activemq.broker.region.Destination;
import org.apache.activemq.broker.region.RegionBroker;
-import org.apache.activemq.broker.scheduler.JobSchedulerStore;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTempQueue;
@@ -56,14 +55,7 @@ import org.apache.activemq.command.SubscriptionInfo;
import org.apache.activemq.command.TransactionId;
import org.apache.activemq.openwire.OpenWireFormat;
import org.apache.activemq.protobuf.Buffer;
-import org.apache.activemq.store.AbstractMessageStore;
-import org.apache.activemq.store.ListenableFuture;
-import org.apache.activemq.store.MessageRecoveryListener;
-import org.apache.activemq.store.MessageStore;
-import org.apache.activemq.store.PersistenceAdapter;
-import org.apache.activemq.store.TopicMessageStore;
-import org.apache.activemq.store.TransactionIdTransformer;
-import org.apache.activemq.store.TransactionStore;
+import org.apache.activemq.store.*;
import org.apache.activemq.store.kahadb.data.KahaAddMessageCommand;
import org.apache.activemq.store.kahadb.data.KahaDestination;
import org.apache.activemq.store.kahadb.data.KahaDestination.DestinationType;
@@ -74,7 +66,6 @@ import org.apache.activemq.store.kahadb.data.KahaSubscriptionCommand;
import org.apache.activemq.store.kahadb.data.KahaUpdateMessageCommand;
import org.apache.activemq.store.kahadb.disk.journal.Location;
import org.apache.activemq.store.kahadb.disk.page.Transaction;
-import org.apache.activemq.store.kahadb.scheduler.JobSchedulerStoreImpl;
import org.apache.activemq.usage.MemoryUsage;
import org.apache.activemq.usage.SystemUsage;
import org.apache.activemq.util.ServiceStopper;
@@ -181,7 +172,6 @@ public class KahaDBStore extends MessageDatabase implements PersistenceAdapter {
public int getMaxAsyncJobs() {
return this.maxAsyncJobs;
}
-
/**
* @param maxAsyncJobs
* the maxAsyncJobs to set
@@ -436,7 +426,6 @@ public class KahaDBStore extends MessageDatabase implements PersistenceAdapter {
}
- @Override
public void updateMessage(Message message) throws IOException {
if (LOG.isTraceEnabled()) {
LOG.trace("updating: " + message.getMessageId() + " with deliveryCount: " + message.getRedeliveryCounter());
@@ -483,7 +472,7 @@ public class KahaDBStore extends MessageDatabase implements PersistenceAdapter {
indexLock.writeLock().lock();
try {
location = findMessageLocation(key, dest);
- } finally {
+ }finally {
indexLock.writeLock().unlock();
}
if (location == null) {
@@ -503,17 +492,19 @@ public class KahaDBStore extends MessageDatabase implements PersistenceAdapter {
@Override
public Integer execute(Transaction tx) throws IOException {
// Iterate through all index entries to get a count
- // of messages in the destination.
+ // of
+ // messages in the destination.
StoredDestination sd = getStoredDestination(dest, tx);
int rc = 0;
- for (Iterator<Entry<Location, Long>> iterator = sd.locationIndex.iterator(tx); iterator.hasNext();) {
+ for (Iterator<Entry<Location, Long>> iterator = sd.locationIndex.iterator(tx); iterator
+ .hasNext();) {
iterator.next();
rc++;
}
return rc;
}
});
- } finally {
+ }finally {
indexLock.writeLock().unlock();
}
} finally {
@@ -534,7 +525,7 @@ public class KahaDBStore extends MessageDatabase implements PersistenceAdapter {
return sd.locationIndex.isEmpty(tx);
}
});
- } finally {
+ }finally {
indexLock.writeLock().unlock();
}
}
@@ -561,11 +552,12 @@ public class KahaDBStore extends MessageDatabase implements PersistenceAdapter {
}
}
});
- } finally {
+ }finally {
indexLock.writeLock().unlock();
}
}
+
@Override
public void recoverNextMessages(final int maxReturned, final MessageRecoveryListener listener) throws Exception {
indexLock.writeLock().lock();
@@ -591,7 +583,7 @@ public class KahaDBStore extends MessageDatabase implements PersistenceAdapter {
sd.orderIndex.stoppedIterating();
}
});
- } finally {
+ }finally {
indexLock.writeLock().unlock();
}
}
@@ -636,7 +628,7 @@ public class KahaDBStore extends MessageDatabase implements PersistenceAdapter {
});
} catch (Exception e) {
LOG.error("Failed to reset batching",e);
- } finally {
+ }finally {
indexLock.writeLock().unlock();
}
}
@@ -649,7 +641,8 @@ public class KahaDBStore extends MessageDatabase implements PersistenceAdapter {
lockAsyncJobQueue();
// Hopefully one day the page file supports concurrent read
- // operations... but for now we must externally synchronize...
+ // operations... but for now we must
+ // externally synchronize...
indexLock.writeLock().lock();
try {
@@ -732,7 +725,8 @@ public class KahaDBStore extends MessageDatabase implements PersistenceAdapter {
@Override
public void acknowledge(ConnectionContext context, String clientId, String subscriptionName,
- MessageId messageId, MessageAck ack) throws IOException {
+ MessageId messageId, MessageAck ack)
+ throws IOException {
String subscriptionKey = subscriptionKey(clientId, subscriptionName).toString();
if (isConcurrentStoreAndDispatchTopics()) {
AsyncJobKey key = new AsyncJobKey(messageId, getDestination());
@@ -816,7 +810,7 @@ public class KahaDBStore extends MessageDatabase implements PersistenceAdapter {
}
}
});
- } finally {
+ }finally {
indexLock.writeLock().unlock();
}
@@ -842,7 +836,7 @@ public class KahaDBStore extends MessageDatabase implements PersistenceAdapter {
.getSubscriptionInfo().newInput()));
}
});
- } finally {
+ }finally {
indexLock.writeLock().unlock();
}
}
@@ -865,7 +859,7 @@ public class KahaDBStore extends MessageDatabase implements PersistenceAdapter {
return (int) getStoredMessageCount(tx, sd, subscriptionKey);
}
});
- } finally {
+ }finally {
indexLock.writeLock().unlock();
}
}
@@ -896,7 +890,7 @@ public class KahaDBStore extends MessageDatabase implements PersistenceAdapter {
sd.orderIndex.resetCursorPosition();
}
});
- } finally {
+ }finally {
indexLock.writeLock().unlock();
}
}
@@ -949,7 +943,7 @@ public class KahaDBStore extends MessageDatabase implements PersistenceAdapter {
}
}
});
- } finally {
+ }finally {
indexLock.writeLock().unlock();
}
}
@@ -1364,6 +1358,7 @@ public class KahaDBStore extends MessageDatabase implements PersistenceAdapter {
LOG.warn("Failed to aquire lock", e);
}
}
+
}
@Override
@@ -1427,11 +1422,7 @@ public class KahaDBStore extends MessageDatabase implements PersistenceAdapter {
if (runnable instanceof StoreTask) {
((StoreTask)runnable).releaseLocks();
}
- }
- }
- @Override
- public JobSchedulerStore createJobSchedulerStore() throws IOException, UnsupportedOperationException {
- return new JobSchedulerStoreImpl();
+ }
}
}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/MultiKahaDBPersistenceAdapter.java
----------------------------------------------------------------------
diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/MultiKahaDBPersistenceAdapter.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/MultiKahaDBPersistenceAdapter.java
index eca83e8..d10c4eb 100644
--- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/MultiKahaDBPersistenceAdapter.java
+++ b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/MultiKahaDBPersistenceAdapter.java
@@ -16,44 +16,12 @@
*/
package org.apache.activemq.store.kahadb;
-import java.io.File;
-import java.io.FileFilter;
-import java.io.IOException;
-import java.nio.charset.Charset;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.transaction.xa.Xid;
-
-import org.apache.activemq.broker.BrokerService;
-import org.apache.activemq.broker.BrokerServiceAware;
-import org.apache.activemq.broker.ConnectionContext;
-import org.apache.activemq.broker.Lockable;
-import org.apache.activemq.broker.LockableServiceSupport;
-import org.apache.activemq.broker.Locker;
-import org.apache.activemq.broker.scheduler.JobSchedulerStore;
-import org.apache.activemq.command.ActiveMQDestination;
-import org.apache.activemq.command.ActiveMQQueue;
-import org.apache.activemq.command.ActiveMQTopic;
-import org.apache.activemq.command.LocalTransactionId;
-import org.apache.activemq.command.ProducerId;
-import org.apache.activemq.command.TransactionId;
-import org.apache.activemq.command.XATransactionId;
+import org.apache.activemq.broker.*;
+import org.apache.activemq.command.*;
import org.apache.activemq.filter.AnyDestination;
import org.apache.activemq.filter.DestinationMap;
import org.apache.activemq.filter.DestinationMapEntry;
-import org.apache.activemq.store.MessageStore;
-import org.apache.activemq.store.PersistenceAdapter;
-import org.apache.activemq.store.SharedFileLocker;
-import org.apache.activemq.store.TopicMessageStore;
-import org.apache.activemq.store.TransactionIdTransformer;
-import org.apache.activemq.store.TransactionIdTransformerAware;
-import org.apache.activemq.store.TransactionStore;
-import org.apache.activemq.store.kahadb.scheduler.JobSchedulerStoreImpl;
+import org.apache.activemq.store.*;
import org.apache.activemq.usage.SystemUsage;
import org.apache.activemq.util.IOExceptionSupport;
import org.apache.activemq.util.IOHelper;
@@ -62,6 +30,13 @@ import org.apache.activemq.util.ServiceStopper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.transaction.xa.Xid;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.*;
+
/**
* An implementation of {@link org.apache.activemq.store.PersistenceAdapter} that supports
* distribution of destinations across multiple kahaDB persistence adapters
@@ -75,7 +50,6 @@ public class MultiKahaDBPersistenceAdapter extends LockableServiceSupport implem
final int LOCAL_FORMAT_ID_MAGIC = Integer.valueOf(System.getProperty("org.apache.activemq.store.kahadb.MultiKahaDBTransactionStore.localXaFormatId", "61616"));
final class DelegateDestinationMap extends DestinationMap {
- @Override
public void setEntries(List<DestinationMapEntry> entries) {
super.setEntries(entries);
}
@@ -278,7 +252,7 @@ public class MultiKahaDBPersistenceAdapter extends LockableServiceSupport implem
}
if (adapter instanceof PersistenceAdapter) {
adapter.removeQueueMessageStore(destination);
- removeMessageStore(adapter, destination);
+ removeMessageStore((PersistenceAdapter)adapter, destination);
destinationMap.removeAll(destination);
}
}
@@ -293,7 +267,7 @@ public class MultiKahaDBPersistenceAdapter extends LockableServiceSupport implem
}
if (adapter instanceof PersistenceAdapter) {
adapter.removeTopicMessageStore(destination);
- removeMessageStore(adapter, destination);
+ removeMessageStore((PersistenceAdapter)adapter, destination);
destinationMap.removeAll(destination);
}
}
@@ -479,7 +453,6 @@ public class MultiKahaDBPersistenceAdapter extends LockableServiceSupport implem
}
}
- @Override
public BrokerService getBrokerService() {
return brokerService;
}
@@ -530,9 +503,4 @@ public class MultiKahaDBPersistenceAdapter extends LockableServiceSupport implem
locker.configure(this);
return locker;
}
-
- @Override
- public JobSchedulerStore createJobSchedulerStore() throws IOException, UnsupportedOperationException {
- return new JobSchedulerStoreImpl();
- }
}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/MultiKahaDBTransactionStore.java
----------------------------------------------------------------------
diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/MultiKahaDBTransactionStore.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/MultiKahaDBTransactionStore.java
index 8840a1d..c7ece83 100644
--- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/MultiKahaDBTransactionStore.java
+++ b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/MultiKahaDBTransactionStore.java
@@ -31,24 +31,16 @@ import org.apache.activemq.command.MessageAck;
import org.apache.activemq.command.MessageId;
import org.apache.activemq.command.TransactionId;
import org.apache.activemq.command.XATransactionId;
-import org.apache.activemq.store.AbstractMessageStore;
-import org.apache.activemq.store.ListenableFuture;
-import org.apache.activemq.store.MessageStore;
-import org.apache.activemq.store.PersistenceAdapter;
-import org.apache.activemq.store.ProxyMessageStore;
-import org.apache.activemq.store.ProxyTopicMessageStore;
-import org.apache.activemq.store.TopicMessageStore;
-import org.apache.activemq.store.TransactionRecoveryListener;
-import org.apache.activemq.store.TransactionStore;
+import org.apache.activemq.store.*;
import org.apache.activemq.store.kahadb.data.KahaCommitCommand;
import org.apache.activemq.store.kahadb.data.KahaEntryType;
import org.apache.activemq.store.kahadb.data.KahaPrepareCommand;
import org.apache.activemq.store.kahadb.data.KahaTraceCommand;
+import org.apache.activemq.util.IOHelper;
import org.apache.activemq.store.kahadb.disk.journal.Journal;
import org.apache.activemq.store.kahadb.disk.journal.Location;
import org.apache.activemq.util.DataByteArrayInputStream;
import org.apache.activemq.util.DataByteArrayOutputStream;
-import org.apache.activemq.util.IOHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -194,7 +186,6 @@ public class MultiKahaDBTransactionStore implements TransactionStore {
return inflightTransactions.remove(txid);
}
- @Override
public void prepare(TransactionId txid) throws IOException {
Tx tx = getTx(txid);
for (TransactionStore store : tx.getStores()) {
@@ -202,7 +193,6 @@ public class MultiKahaDBTransactionStore implements TransactionStore {
}
}
- @Override
public void commit(TransactionId txid, boolean wasPrepared, Runnable preCommit, Runnable postCommit)
throws IOException {
@@ -257,7 +247,6 @@ public class MultiKahaDBTransactionStore implements TransactionStore {
return location;
}
- @Override
public void rollback(TransactionId txid) throws IOException {
Tx tx = removeTx(txid);
if (tx != null) {
@@ -267,7 +256,6 @@ public class MultiKahaDBTransactionStore implements TransactionStore {
}
}
- @Override
public void start() throws Exception {
journal = new Journal() {
@Override
@@ -301,7 +289,6 @@ public class MultiKahaDBTransactionStore implements TransactionStore {
return new File(multiKahaDBPersistenceAdapter.getDirectory(), "txStore");
}
- @Override
public void stop() throws Exception {
journal.close();
journal = null;
@@ -347,7 +334,6 @@ public class MultiKahaDBTransactionStore implements TransactionStore {
}
- @Override
public synchronized void recover(final TransactionRecoveryListener listener) throws IOException {
for (final PersistenceAdapter adapter : multiKahaDBPersistenceAdapter.adapters) {
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/TempKahaDBStore.java
----------------------------------------------------------------------
diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/TempKahaDBStore.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/TempKahaDBStore.java
index 45e35c6..66ae496 100644
--- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/TempKahaDBStore.java
+++ b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/TempKahaDBStore.java
@@ -22,13 +22,12 @@ import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Set;
+import java.util.Map.Entry;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.broker.BrokerServiceAware;
import org.apache.activemq.broker.ConnectionContext;
-import org.apache.activemq.broker.scheduler.JobSchedulerStore;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTempQueue;
@@ -52,35 +51,31 @@ import org.apache.activemq.store.TransactionRecoveryListener;
import org.apache.activemq.store.TransactionStore;
import org.apache.activemq.store.kahadb.data.KahaAddMessageCommand;
import org.apache.activemq.store.kahadb.data.KahaDestination;
-import org.apache.activemq.store.kahadb.data.KahaDestination.DestinationType;
import org.apache.activemq.store.kahadb.data.KahaLocation;
import org.apache.activemq.store.kahadb.data.KahaRemoveDestinationCommand;
import org.apache.activemq.store.kahadb.data.KahaRemoveMessageCommand;
import org.apache.activemq.store.kahadb.data.KahaSubscriptionCommand;
-import org.apache.activemq.store.kahadb.disk.journal.Location;
-import org.apache.activemq.store.kahadb.disk.page.Transaction;
+import org.apache.activemq.store.kahadb.data.KahaDestination.DestinationType;
import org.apache.activemq.usage.MemoryUsage;
import org.apache.activemq.usage.SystemUsage;
import org.apache.activemq.util.ByteSequence;
import org.apache.activemq.wireformat.WireFormat;
+import org.apache.activemq.store.kahadb.disk.journal.Location;
+import org.apache.activemq.store.kahadb.disk.page.Transaction;
public class TempKahaDBStore extends TempMessageDatabase implements PersistenceAdapter, BrokerServiceAware {
private final WireFormat wireFormat = new OpenWireFormat();
private BrokerService brokerService;
- @Override
public void setBrokerName(String brokerName) {
}
- @Override
public void setUsageManager(SystemUsage usageManager) {
}
- @Override
public TransactionStore createTransactionStore() throws IOException {
return new TransactionStore(){
-
- @Override
+
public void commit(TransactionId txid, boolean wasPrepared, Runnable preCommit,Runnable postCommit) throws IOException {
if (preCommit != null) {
preCommit.run();
@@ -90,21 +85,18 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
postCommit.run();
}
}
- @Override
public void prepare(TransactionId txid) throws IOException {
- processPrepare(txid);
+ processPrepare(txid);
}
- @Override
public void rollback(TransactionId txid) throws IOException {
- processRollback(txid);
+ processRollback(txid);
}
- @Override
public void recover(TransactionRecoveryListener listener) throws IOException {
for (Map.Entry<TransactionId, ArrayList<Operation>> entry : preparedTransactions.entrySet()) {
XATransactionId xid = (XATransactionId)entry.getKey();
ArrayList<Message> messageList = new ArrayList<Message>();
ArrayList<MessageAck> ackList = new ArrayList<MessageAck>();
-
+
for (Operation op : entry.getValue()) {
if( op.getClass() == AddOpperation.class ) {
AddOpperation addOp = (AddOpperation)op;
@@ -116,7 +108,7 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
ackList.add(ack);
}
}
-
+
Message[] addedMessages = new Message[messageList.size()];
MessageAck[] acks = new MessageAck[ackList.size()];
messageList.toArray(addedMessages);
@@ -124,10 +116,8 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
listener.recover(xid, addedMessages, acks);
}
}
- @Override
public void start() throws Exception {
}
- @Override
public void stop() throws Exception {
}
};
@@ -146,15 +136,13 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
return destination;
}
- @Override
public void addMessage(ConnectionContext context, Message message) throws IOException {
KahaAddMessageCommand command = new KahaAddMessageCommand();
command.setDestination(dest);
command.setMessageId(message.getMessageId().toProducerKey());
processAdd(command, message.getTransactionId(), wireFormat.marshal(message));
}
-
- @Override
+
public void removeMessage(ConnectionContext context, MessageAck ack) throws IOException {
KahaRemoveMessageCommand command = new KahaRemoveMessageCommand();
command.setDestination(dest);
@@ -162,23 +150,20 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
processRemove(command, ack.getTransactionId());
}
- @Override
public void removeAllMessages(ConnectionContext context) throws IOException {
KahaRemoveDestinationCommand command = new KahaRemoveDestinationCommand();
command.setDestination(dest);
process(command);
}
- @Override
public Message getMessage(MessageId identity) throws IOException {
final String key = identity.toProducerKey();
-
+
// Hopefully one day the page file supports concurrent read operations... but for now we must
// externally synchronize...
ByteSequence data;
synchronized(indexMutex) {
data = pageFile.tx().execute(new Transaction.CallableClosure<ByteSequence, IOException>(){
- @Override
public ByteSequence execute(Transaction tx) throws IOException {
StoredDestination sd = getStoredDestination(dest, tx);
Long sequence = sd.messageIdIndex.get(tx, key);
@@ -192,16 +177,14 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
if( data == null ) {
return null;
}
-
+
Message msg = (Message)wireFormat.unmarshal( data );
- return msg;
+ return msg;
}
-
- @Override
+
public int getMessageCount() throws IOException {
synchronized(indexMutex) {
return pageFile.tx().execute(new Transaction.CallableClosure<Integer, IOException>(){
- @Override
public Integer execute(Transaction tx) throws IOException {
// Iterate through all index entries to get a count of messages in the destination.
StoredDestination sd = getStoredDestination(dest, tx);
@@ -216,11 +199,9 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
}
}
- @Override
public void recover(final MessageRecoveryListener listener) throws Exception {
synchronized(indexMutex) {
pageFile.tx().execute(new Transaction.Closure<Exception>(){
- @Override
public void execute(Transaction tx) throws Exception {
StoredDestination sd = getStoredDestination(dest, tx);
for (Iterator<Entry<Long, MessageRecord>> iterator = sd.orderIndex.iterator(tx); iterator.hasNext();) {
@@ -233,12 +214,10 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
}
long cursorPos=0;
-
- @Override
+
public void recoverNextMessages(final int maxReturned, final MessageRecoveryListener listener) throws Exception {
synchronized(indexMutex) {
pageFile.tx().execute(new Transaction.Closure<Exception>(){
- @Override
public void execute(Transaction tx) throws Exception {
StoredDestination sd = getStoredDestination(dest, tx);
Entry<Long, MessageRecord> entry=null;
@@ -259,22 +238,20 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
}
}
- @Override
public void resetBatching() {
cursorPos=0;
}
-
+
@Override
public void setBatch(MessageId identity) throws IOException {
final String key = identity.toProducerKey();
-
+
// Hopefully one day the page file supports concurrent read operations... but for now we must
// externally synchronize...
Long location;
synchronized(indexMutex) {
location = pageFile.tx().execute(new Transaction.CallableClosure<Long, IOException>(){
- @Override
public Long execute(Transaction tx) throws IOException {
StoredDestination sd = getStoredDestination(dest, tx);
return sd.messageIdIndex.get(tx, key);
@@ -284,7 +261,7 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
if( location!=null ) {
cursorPos=location+1;
}
-
+
}
@Override
@@ -296,15 +273,14 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
@Override
public void stop() throws Exception {
}
-
+
}
-
+
class KahaDBTopicMessageStore extends KahaDBMessageStore implements TopicMessageStore {
public KahaDBTopicMessageStore(ActiveMQTopic destination) {
super(destination);
}
-
- @Override
+
public void acknowledge(ConnectionContext context, String clientId, String subscriptionName,
MessageId messageId, MessageAck ack) throws IOException {
KahaRemoveMessageCommand command = new KahaRemoveMessageCommand();
@@ -318,7 +294,6 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
processRemove(command, null);
}
- @Override
public void addSubscription(SubscriptionInfo subscriptionInfo, boolean retroactive) throws IOException {
String subscriptionKey = subscriptionKey(subscriptionInfo.getClientId(), subscriptionInfo.getSubscriptionName());
KahaSubscriptionCommand command = new KahaSubscriptionCommand();
@@ -330,7 +305,6 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
process(command);
}
- @Override
public void deleteSubscription(String clientId, String subscriptionName) throws IOException {
KahaSubscriptionCommand command = new KahaSubscriptionCommand();
command.setDestination(dest);
@@ -338,13 +312,11 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
process(command);
}
- @Override
public SubscriptionInfo[] getAllSubscriptions() throws IOException {
-
+
final ArrayList<SubscriptionInfo> subscriptions = new ArrayList<SubscriptionInfo>();
synchronized(indexMutex) {
pageFile.tx().execute(new Transaction.Closure<IOException>(){
- @Override
public void execute(Transaction tx) throws IOException {
StoredDestination sd = getStoredDestination(dest, tx);
for (Iterator<Entry<String, KahaSubscriptionCommand>> iterator = sd.subscriptions.iterator(tx); iterator.hasNext();) {
@@ -356,18 +328,16 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
}
});
}
-
+
SubscriptionInfo[]rc=new SubscriptionInfo[subscriptions.size()];
subscriptions.toArray(rc);
return rc;
}
- @Override
public SubscriptionInfo lookupSubscription(String clientId, String subscriptionName) throws IOException {
final String subscriptionKey = subscriptionKey(clientId, subscriptionName);
synchronized(indexMutex) {
return pageFile.tx().execute(new Transaction.CallableClosure<SubscriptionInfo, IOException>(){
- @Override
public SubscriptionInfo execute(Transaction tx) throws IOException {
StoredDestination sd = getStoredDestination(dest, tx);
KahaSubscriptionCommand command = sd.subscriptions.get(tx, subscriptionKey);
@@ -379,13 +349,11 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
});
}
}
-
- @Override
+
public int getMessageCount(String clientId, String subscriptionName) throws IOException {
final String subscriptionKey = subscriptionKey(clientId, subscriptionName);
synchronized(indexMutex) {
return pageFile.tx().execute(new Transaction.CallableClosure<Integer, IOException>(){
- @Override
public Integer execute(Transaction tx) throws IOException {
StoredDestination sd = getStoredDestination(dest, tx);
Long cursorPos = sd.subscriptionAcks.get(tx, subscriptionKey);
@@ -394,7 +362,7 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
return 0;
}
cursorPos += 1;
-
+
int counter = 0;
for (Iterator<Entry<Long, MessageRecord>> iterator = sd.orderIndex.iterator(tx, cursorPos); iterator.hasNext();) {
iterator.next();
@@ -403,20 +371,18 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
return counter;
}
});
- }
+ }
}
- @Override
public void recoverSubscription(String clientId, String subscriptionName, final MessageRecoveryListener listener) throws Exception {
final String subscriptionKey = subscriptionKey(clientId, subscriptionName);
synchronized(indexMutex) {
pageFile.tx().execute(new Transaction.Closure<Exception>(){
- @Override
public void execute(Transaction tx) throws Exception {
StoredDestination sd = getStoredDestination(dest, tx);
Long cursorPos = sd.subscriptionAcks.get(tx, subscriptionKey);
cursorPos += 1;
-
+
for (Iterator<Entry<Long, MessageRecord>> iterator = sd.orderIndex.iterator(tx, cursorPos); iterator.hasNext();) {
Entry<Long, MessageRecord> entry = iterator.next();
listener.recoverMessage( (Message) wireFormat.unmarshal(entry.getValue().data ) );
@@ -426,12 +392,10 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
}
}
- @Override
public void recoverNextMessages(String clientId, String subscriptionName, final int maxReturned, final MessageRecoveryListener listener) throws Exception {
final String subscriptionKey = subscriptionKey(clientId, subscriptionName);
synchronized(indexMutex) {
pageFile.tx().execute(new Transaction.Closure<Exception>(){
- @Override
public void execute(Transaction tx) throws Exception {
StoredDestination sd = getStoredDestination(dest, tx);
Long cursorPos = sd.subscriptionCursors.get(subscriptionKey);
@@ -439,7 +403,7 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
cursorPos = sd.subscriptionAcks.get(tx, subscriptionKey);
cursorPos += 1;
}
-
+
Entry<Long, MessageRecord> entry=null;
int counter = 0;
for (Iterator<Entry<Long, MessageRecord>> iterator = sd.orderIndex.iterator(tx, cursorPos); iterator.hasNext();) {
@@ -458,13 +422,11 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
}
}
- @Override
public void resetBatching(String clientId, String subscriptionName) {
try {
final String subscriptionKey = subscriptionKey(clientId, subscriptionName);
synchronized(indexMutex) {
pageFile.tx().execute(new Transaction.Closure<IOException>(){
- @Override
public void execute(Transaction tx) throws IOException {
StoredDestination sd = getStoredDestination(dest, tx);
sd.subscriptionCursors.remove(subscriptionKey);
@@ -480,13 +442,11 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
String subscriptionKey(String clientId, String subscriptionName){
return clientId+":"+subscriptionName;
}
-
- @Override
+
public MessageStore createQueueMessageStore(ActiveMQQueue destination) throws IOException {
return new KahaDBMessageStore(destination);
}
- @Override
public TopicMessageStore createTopicMessageStore(ActiveMQTopic destination) throws IOException {
return new KahaDBTopicMessageStore(destination);
}
@@ -497,7 +457,6 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
*
* @param destination Destination to forget
*/
- @Override
public void removeQueueMessageStore(ActiveMQQueue destination) {
}
@@ -507,22 +466,18 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
*
* @param destination Destination to forget
*/
- @Override
public void removeTopicMessageStore(ActiveMQTopic destination) {
}
- @Override
public void deleteAllMessages() throws IOException {
}
-
-
- @Override
+
+
public Set<ActiveMQDestination> getDestinations() {
try {
final HashSet<ActiveMQDestination> rc = new HashSet<ActiveMQDestination>();
synchronized(indexMutex) {
pageFile.tx().execute(new Transaction.Closure<IOException>(){
- @Override
public void execute(Transaction tx) throws IOException {
for (Iterator<Entry<String, StoredDestination>> iterator = destinations.iterator(tx); iterator.hasNext();) {
Entry<String, StoredDestination> entry = iterator.next();
@@ -536,13 +491,11 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
throw new RuntimeException(e);
}
}
-
- @Override
+
public long getLastMessageBrokerSequenceId() throws IOException {
return 0;
}
-
- @Override
+
public long size() {
if ( !started.get() ) {
return 0;
@@ -554,36 +507,32 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
}
}
- @Override
public void beginTransaction(ConnectionContext context) throws IOException {
throw new IOException("Not yet implemented.");
}
- @Override
public void commitTransaction(ConnectionContext context) throws IOException {
throw new IOException("Not yet implemented.");
}
- @Override
public void rollbackTransaction(ConnectionContext context) throws IOException {
throw new IOException("Not yet implemented.");
}
-
- @Override
+
public void checkpoint(boolean sync) throws IOException {
- }
+ }
///////////////////////////////////////////////////////////////////
// Internal conversion methods.
///////////////////////////////////////////////////////////////////
+
-
-
+
KahaLocation convert(Location location) {
KahaLocation rc = new KahaLocation();
rc.setLogId(location.getDataFileId());
rc.setOffset(location.getOffset());
return rc;
}
-
+
KahaDestination convert(ActiveMQDestination dest) {
KahaDestination rc = new KahaDestination();
rc.setName(dest.getPhysicalName());
@@ -612,7 +561,7 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
}
int type = Integer.parseInt(dest.substring(0, p));
String name = dest.substring(p+1);
-
+
switch( KahaDestination.DestinationType.valueOf(type) ) {
case QUEUE:
return new ActiveMQQueue(name);
@@ -622,12 +571,11 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
return new ActiveMQTempQueue(name);
case TEMP_TOPIC:
return new ActiveMQTempTopic(name);
- default:
+ default:
throw new IllegalArgumentException("Not in the valid destination format");
}
}
-
- @Override
+
public long getLastProducerSequenceId(ProducerId id) {
return -1;
}
@@ -644,8 +592,4 @@ public class TempKahaDBStore extends TempMessageDatabase implements PersistenceA
}
super.load();
}
- @Override
- public JobSchedulerStore createJobSchedulerStore() throws IOException, UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/Visitor.java
----------------------------------------------------------------------
diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/Visitor.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/Visitor.java
index 43fc152..be4f2ff 100644
--- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/Visitor.java
+++ b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/Visitor.java
@@ -20,16 +20,11 @@ import java.io.IOException;
import org.apache.activemq.store.kahadb.data.KahaAckMessageFileMapCommand;
import org.apache.activemq.store.kahadb.data.KahaAddMessageCommand;
-import org.apache.activemq.store.kahadb.data.KahaAddScheduledJobCommand;
import org.apache.activemq.store.kahadb.data.KahaCommitCommand;
-import org.apache.activemq.store.kahadb.data.KahaDestroySchedulerCommand;
import org.apache.activemq.store.kahadb.data.KahaPrepareCommand;
import org.apache.activemq.store.kahadb.data.KahaProducerAuditCommand;
import org.apache.activemq.store.kahadb.data.KahaRemoveDestinationCommand;
import org.apache.activemq.store.kahadb.data.KahaRemoveMessageCommand;
-import org.apache.activemq.store.kahadb.data.KahaRemoveScheduledJobCommand;
-import org.apache.activemq.store.kahadb.data.KahaRemoveScheduledJobsCommand;
-import org.apache.activemq.store.kahadb.data.KahaRescheduleJobCommand;
import org.apache.activemq.store.kahadb.data.KahaRollbackCommand;
import org.apache.activemq.store.kahadb.data.KahaSubscriptionCommand;
import org.apache.activemq.store.kahadb.data.KahaTraceCommand;
@@ -67,21 +62,6 @@ public class Visitor {
public void visit(KahaAckMessageFileMapCommand kahaProducerAuditCommand) throws IOException {
}
- public void visit(KahaAddScheduledJobCommand kahaAddScheduledJobCommand) throws IOException {
- }
-
- public void visit(KahaRescheduleJobCommand KahaRescheduleJobCommand) throws IOException {
- }
-
- public void visit(KahaRemoveScheduledJobCommand kahaRemoveScheduledJobCommand) throws IOException {
- }
-
- public void visit(KahaRemoveScheduledJobsCommand kahaRemoveScheduledJobsCommand) throws IOException {
- }
-
- public void visit(KahaDestroySchedulerCommand KahaDestroySchedulerCommand) throws IOException {
- }
-
public void visit(KahaUpdateMessageCommand kahaUpdateMessageCommand) throws IOException {
}
}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobImpl.java
----------------------------------------------------------------------
diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobImpl.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobImpl.java
index 217bc1f..86b9fa3 100644
--- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobImpl.java
+++ b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobImpl.java
@@ -25,8 +25,8 @@ public class JobImpl implements Job {
private final JobLocation jobLocation;
private final byte[] payload;
- protected JobImpl(JobLocation location, ByteSequence bs) {
- this.jobLocation = location;
+ protected JobImpl(JobLocation location,ByteSequence bs) {
+ this.jobLocation=location;
this.payload = new byte[bs.getLength()];
System.arraycopy(bs.getData(), bs.getOffset(), this.payload, 0, bs.getLength());
}
@@ -38,22 +38,22 @@ public class JobImpl implements Job {
@Override
public byte[] getPayload() {
- return this.payload;
+ return this.payload;
}
@Override
public long getPeriod() {
- return this.jobLocation.getPeriod();
+ return this.jobLocation.getPeriod();
}
@Override
public int getRepeat() {
- return this.jobLocation.getRepeat();
+ return this.jobLocation.getRepeat();
}
@Override
public long getStart() {
- return this.jobLocation.getStartTime();
+ return this.jobLocation.getStartTime();
}
@Override
@@ -76,13 +76,4 @@ public class JobImpl implements Job {
return JobSupport.getDateTime(getStart());
}
- @Override
- public int getExecutionCount() {
- return this.jobLocation.getRescheduledCount();
- }
-
- @Override
- public String toString() {
- return "Job: " + getJobId();
- }
}
http://git-wip-us.apache.org/repos/asf/activemq/blob/3424e04f/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobLocation.java
----------------------------------------------------------------------
diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobLocation.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobLocation.java
index cb66145..13cf376 100644
--- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobLocation.java
+++ b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/scheduler/JobLocation.java
@@ -36,8 +36,6 @@ class JobLocation {
private long period;
private String cronEntry;
private final Location location;
- private int rescheduledCount;
- private Location lastUpdate;
public JobLocation(Location location) {
this.location = location;
@@ -54,12 +52,8 @@ class JobLocation {
this.delay = in.readLong();
this.nextTime = in.readLong();
this.period = in.readLong();
- this.cronEntry = in.readUTF();
+ this.cronEntry=in.readUTF();
this.location.readExternal(in);
- if (in.readBoolean()) {
- this.lastUpdate = new Location();
- this.lastUpdate.readExternal(in);
- }
}
public void writeExternal(DataOutput out) throws IOException {
@@ -69,17 +63,11 @@ class JobLocation {
out.writeLong(this.delay);
out.writeLong(this.nextTime);
out.writeLong(this.period);
- if (this.cronEntry == null) {
- this.cronEntry = "";
+ if (this.cronEntry==null) {
+ this.cronEntry="";
}
out.writeUTF(this.cronEntry);
this.location.writeExternal(out);
- if (lastUpdate != null) {
- out.writeBoolean(true);
- this.lastUpdate.writeExternal(out);
- } else {
- out.writeBoolean(false);
- }
}
/**
@@ -135,8 +123,7 @@ class JobLocation {
}
/**
- * @param nextTime
- * the nextTime to set
+ * @param nextTime the nextTime to set
*/
public synchronized void setNextTime(long nextTime) {
this.nextTime = nextTime;
@@ -165,8 +152,7 @@ class JobLocation {
}
/**
- * @param cronEntry
- * the cronEntry to set
+ * @param cronEntry the cronEntry to set
*/
public synchronized void setCronEntry(String cronEntry) {
this.cronEntry = cronEntry;
@@ -187,8 +173,7 @@ class JobLocation {
}
/**
- * @param delay
- * the delay to set
+ * @param delay the delay to set
*/
public void setDelay(long delay) {
this.delay = delay;
@@ -201,55 +186,15 @@ class JobLocation {
return this.location;
}
- /**
- * @returns the location in the journal of the last update issued for this
- * Job.
- */
- public Location getLastUpdate() {
- return this.lastUpdate;
- }
-
- /**
- * Sets the location of the last update command written to the journal for
- * this Job. The update commands set the next execution time for this job.
- * We need to keep track of only the latest update as it's the only one we
- * really need to recover the correct state from the journal.
- *
- * @param location
- * The location in the journal of the last update command.
- */
- public void setLastUpdate(Location location) {
- this.lastUpdate = location;
- }
-
- /**
- * @return the number of time this job has been rescheduled.
- */
- public int getRescheduledCount() {
- return rescheduledCount;
- }
-
- /**
- * Sets the number of time this job has been rescheduled. A newly added job will return
- * zero and increment this value each time a scheduled message is dispatched to its
- * target destination and the job is rescheduled for another cycle.
- *
- * @param executionCount
- * the new execution count to assign the JobLocation.
- */
- public void setRescheduledCount(int rescheduledCount) {
- this.rescheduledCount = rescheduledCount;
- }
-
@Override
public String toString() {
- return "Job [id=" + jobId + ", startTime=" + new Date(startTime) + ", delay=" + delay + ", period=" + period + ", repeat=" + repeat + ", nextTime="
- + new Date(nextTime) + ", executionCount = " + (rescheduledCount + 1) + "]";
+ return "Job [id=" + jobId + ", startTime=" + new Date(startTime)
+ + ", delay=" + delay + ", period=" + period + ", repeat="
+ + repeat + ", nextTime=" + new Date(nextTime) + "]";
}
static class JobLocationMarshaller extends VariableMarshaller<List<JobLocation>> {
static final JobLocationMarshaller INSTANCE = new JobLocationMarshaller();
-
@Override
public List<JobLocation> readPayload(DataInput dataIn) throws IOException {
List<JobLocation> result = new ArrayList<JobLocation>();
@@ -283,7 +228,6 @@ class JobLocation {
result = prime * result + (int) (period ^ (period >>> 32));
result = prime * result + repeat;
result = prime * result + (int) (startTime ^ (startTime >>> 32));
- result = prime * result + (rescheduledCount ^ (rescheduledCount >>> 32));
return result;
}
@@ -342,9 +286,6 @@ class JobLocation {
if (startTime != other.startTime) {
return false;
}
- if (rescheduledCount != other.rescheduledCount) {
- return false;
- }
return true;
}