Exclusively use Map-based in-memory stores for primary storage

This patch introduces map-based volatile stores, most of which were revived
from git history with minimal changes.  The DB storage system is now only
used in a temporary storage when replaying a snapshot containing the `dbScript`
field.

Note that this change removes the transactional nature of in-memory storage
operations as well as the `READ COMMITTED` transaction isolation previously
available to some stores (proven in necessary changes to
`StorageTransactionTest`).  This means some stores will permit dirty reads
when they previously did not.  `TaskStore` has always had this non-transactional
behavior by default, as the DB task store was never deemed suitable for
production.  Nonetheless, this non-transactional behavior should be considered
safe as the scheduler fails over on a storage operation failure, and relies on
the persistent log storage for transaction atomicity.

Reviewed at https://reviews.apache.org/r/62869/


Project: http://git-wip-us.apache.org/repos/asf/aurora/repo
Commit: http://git-wip-us.apache.org/repos/asf/aurora/commit/f2755e1c
Tree: http://git-wip-us.apache.org/repos/asf/aurora/tree/f2755e1c
Diff: http://git-wip-us.apache.org/repos/asf/aurora/diff/f2755e1c

Branch: refs/heads/master
Commit: f2755e1cdd67f3c1516726c21d6e8f13059a5a01
Parents: 38476ab
Author: Bill Farner <[email protected]>
Authored: Tue Oct 24 23:34:09 2017 -0700
Committer: Bill Farner <[email protected]>
Committed: Tue Oct 24 23:34:09 2017 -0700

----------------------------------------------------------------------
 RELEASE-NOTES.md                                |   12 +
 .../thrift/org/apache/aurora/gen/storage.thrift |    3 +-
 docs/reference/scheduler-configuration.md       |   20 -
 .../upstart/aurora-scheduler-kerberos.conf      |    1 -
 examples/vagrant/upstart/aurora-scheduler.conf  |    2 -
 .../aurora/benchmark/SchedulingBenchmarks.java  |    4 +-
 .../aurora/benchmark/SnapshotBenchmarks.java    |   13 +-
 .../benchmark/StateManagerBenchmarks.java       |    5 +-
 .../aurora/benchmark/StatusUpdateBenchmark.java |    4 +-
 .../aurora/benchmark/TaskStoreBenchmarks.java   |   23 +-
 .../aurora/benchmark/ThriftApiBenchmarks.java   |    5 +-
 .../aurora/benchmark/UpdateStoreBenchmarks.java |    8 +-
 .../aurora/scheduler/app/SchedulerMain.java     |   10 +-
 .../aurora/scheduler/config/CliOptions.java     |    4 -
 .../scheduler/http/JettyServerModule.java       |    1 -
 .../scheduler/storage/JobUpdateStore.java       |   16 +
 .../aurora/scheduler/storage/Storage.java       |   21 +-
 .../apache/aurora/scheduler/storage/Util.java   |   45 +
 .../storage/backup/TemporaryStorage.java        |   22 +-
 .../scheduler/storage/db/DbJobUpdateStore.java  |   16 +-
 .../aurora/scheduler/storage/db/DbModule.java   |   72 +-
 .../aurora/scheduler/storage/db/DbStorage.java  |   13 +-
 .../aurora/scheduler/storage/db/DbUtil.java     |   12 -
 .../scheduler/storage/log/LogStorageModule.java |   20 +-
 .../storage/log/SnapshotStoreImpl.java          |  208 +---
 .../storage/log/WriteAheadStorage.java          |    6 -
 .../storage/mem/InMemStoresModule.java          |   65 --
 .../storage/mem/MemAttributeStore.java          |   82 ++
 .../storage/mem/MemJobUpdateStore.java          |  396 +++++++
 .../scheduler/storage/mem/MemLockStore.java     |   72 ++
 .../scheduler/storage/mem/MemQuotaStore.java    |   56 +
 .../storage/mem/MemSchedulerStore.java          |   38 +
 .../scheduler/storage/mem/MemStorage.java       |  103 ++
 .../scheduler/storage/mem/MemStorageModule.java |  107 ++
 .../aurora/scheduler/storage/mem/Util.java      |   47 -
 .../updater/JobUpdateControllerImpl.java        |   12 +-
 .../aurora/scheduler/app/SchedulerIT.java       |    2 +-
 .../scheduler/app/local/LocalSchedulerMain.java |   11 -
 .../scheduler/config/CommandLineTest.java       |   19 -
 .../cron/quartz/AuroraCronJobTest.java          |    8 +-
 .../aurora/scheduler/cron/quartz/CronIT.java    |    4 +-
 .../cron/quartz/CronJobManagerImplTest.java     |    4 +-
 .../aurora/scheduler/http/MaintenanceTest.java  |    4 +-
 .../scheduling/TaskSchedulerImplTest.java       |    4 +-
 .../scheduler/state/LockManagerImplTest.java    |    4 +-
 .../scheduler/state/StateManagerImplTest.java   |    4 +-
 .../scheduler/stats/ResourceCounterTest.java    |    4 +-
 .../storage/AbstractAttributeStoreTest.java     |  176 +++
 .../storage/AbstractJobUpdateStoreTest.java     | 1046 ++++++++++++++++++
 .../storage/AbstractLockStoreTest.java          |  200 ++++
 .../storage/AbstractQuotaStoreTest.java         |  111 ++
 .../storage/AbstractSchedulerStoreTest.java     |   54 +
 .../scheduler/storage/backup/RecoveryTest.java  |    8 +-
 .../storage/db/AttributeStoreTest.java          |   24 +
 .../scheduler/storage/db/CronJobStoreTest.java  |   39 +
 .../storage/db/DbAttributeStoreTest.java        |  175 ---
 .../storage/db/DbCronJobStoreTest.java          |   39 -
 .../storage/db/DbJobUpdateStoreTest.java        | 1046 ------------------
 .../scheduler/storage/db/DbLockStoreTest.java   |  199 ----
 .../scheduler/storage/db/DbQuotaStoreTest.java  |  110 --
 .../storage/db/DbSchedulerStoreTest.java        |   53 -
 .../scheduler/storage/db/DbTaskStoreTest.java   |   39 -
 .../storage/db/JobUpdateStoreTest.java          |   25 +
 .../scheduler/storage/db/LockStoreTest.java     |   24 +
 .../scheduler/storage/db/QuotaStoreTest.java    |   24 +
 .../storage/db/SchedulerStoreTest.java          |   24 +
 .../scheduler/storage/db/TaskStoreTest.java     |   39 +
 .../storage/log/SnapshotStoreImplIT.java        |  179 ++-
 .../storage/mem/InMemTaskStoreTest.java         |   73 --
 .../storage/mem/MemAttributeStoreTest.java      |   24 +
 .../storage/mem/MemCronJobStoreTest.java        |    7 +-
 .../storage/mem/MemJobUpdateStoreTest.java      |   38 +
 .../scheduler/storage/mem/MemLockStoreTest.java |   24 +
 .../storage/mem/MemQuotaStoreTest.java          |   24 +
 .../scheduler/storage/mem/MemStorageTest.java   |  173 +++
 .../scheduler/storage/mem/MemTaskStoreTest.java |   68 ++
 .../storage/mem/StorageTransactionTest.java     |   22 +-
 .../aurora/scheduler/thrift/ThriftIT.java       |    4 +-
 .../aurora/scheduler/updater/JobUpdaterIT.java  |    4 +-
 79 files changed, 3290 insertions(+), 2417 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/RELEASE-NOTES.md
----------------------------------------------------------------------
diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index 76bf868..bc11e3b 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -20,6 +20,7 @@
 - Added scheduler command line argument `-hold_offers_forever`, suitable for 
use in clusters where
   Aurora is the only framework.  This setting disables other options such as 
`-min_offer_hold_time`,
   and allows the scheduler to more efficiently cache scheduling attempts.
+- The schduler no longer uses an internal H2 database for storage.
 
 ### Deprecations and removals:
 
@@ -31,6 +32,17 @@
 - Removed the Job environment validation from the command line client. 
Validation was moved to the
   the scheduler side through the `allowed_job_environments` option. By default 
allowing any of
   `devel`, `test`, `production`, and any value matching the regular expression 
`staging[0-9]*`.
+- Removed scheduler command line arguments related to the internal H2 
database, which is no longer
+  used:
+  - `-use_beta_db_task_store`
+  - `-enable_db_metrics`
+  - `-slow_query_log_threshold`
+  - `-db_row_gc_interval`
+  - `-db_lock_timeout`
+  - `-db_max_active_connection_count`
+  - `-db_max_idle_connection_count`
+  - `-snapshot_hydrate_stores`
+  - `-enable_h2_console`
 
 0.18.0
 ======

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/api/src/main/thrift/org/apache/aurora/gen/storage.thrift
----------------------------------------------------------------------
diff --git a/api/src/main/thrift/org/apache/aurora/gen/storage.thrift 
b/api/src/main/thrift/org/apache/aurora/gen/storage.thrift
index 9ee9eff..ccb5825 100644
--- a/api/src/main/thrift/org/apache/aurora/gen/storage.thrift
+++ b/api/src/main/thrift/org/apache/aurora/gen/storage.thrift
@@ -145,8 +145,7 @@ struct Snapshot {
   9: set<api.Lock> locks
   10: set<StoredJobUpdateDetails> jobUpdateDetails
   11: list<string> dbScript
-  // Indicates if experimental DB store for tasks and cron jobs was enabled 
when snapshot was cut.
-  12: bool experimentalTaskStore
+  //12: removed
 }
 
 // A message header that calls out the number of expected FrameChunks to 
follow to form a complete

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/docs/reference/scheduler-configuration.md
----------------------------------------------------------------------
diff --git a/docs/reference/scheduler-configuration.md 
b/docs/reference/scheduler-configuration.md
index 44ba389..d17541f 100644
--- a/docs/reference/scheduler-configuration.md
+++ b/docs/reference/scheduler-configuration.md
@@ -16,10 +16,6 @@ Required flags:
        Directory to store backups under. Will be created if it does not exist.
 -cluster_name [not null]
        Name to identify the cluster being served.
--db_max_active_connection_count [must be > 0]
-       Max number of connections to use with database via MyBatis
--db_max_idle_connection_count [must be > 0]
-       Max number of idle connections to the database via MyBatis
 -framework_authentication_file
        Properties file which contains framework credentials to authenticate 
with Mesosmaster. Must contain the properties 'aurora_authentication_principal' 
and 'aurora_authentication_secret'.
 -ip
@@ -72,10 +68,6 @@ Optional flags:
        TimeZone to use for cron predictions.
 -custom_executor_config [file must exist, file must be readable]
        Path to custom executor settings configuration file.
--db_lock_timeout (default (1, mins))
-       H2 table lock timeout
--db_row_gc_interval (default (2, hrs))
-       Interval on which to scan the database for unused row references.
 -default_docker_parameters (default {})
        Default docker parameters for any job that does not explicitly declare 
parameters.
 -dlog_max_entry_size (default (512, KB))
@@ -86,10 +78,6 @@ Optional flags:
        Specifies the frequency at which snapshots of local storage are taken 
and written to the log.
 -enable_cors_for
        List of domains for which CORS support should be enabled.
--enable_db_metrics (default true)
-       Whether to use MyBatis interceptor to measure the timing of intercepted 
Statements.
--enable_h2_console (default false)
-       Enable H2 DB management console.
 -enable_mesos_fetcher (default false)
        Allow jobs to pass URIs to the Mesos Fetcher. Note that enabling this 
feature could pose a privilege escalation threat.
 -enable_preemptor (default true)
@@ -228,12 +216,6 @@ Optional flags:
        Metric categories collected for production tasks.
 -sla_stat_refresh_interval (default (1, mins))
        The SLA stat refresh interval.
--slow_query_log_threshold (default (25, ms))
-       Log all queries that take at least this long to execute.
--slow_query_log_threshold (default (25, ms))
-       Log all queries that take at least this long to execute.
--snapshot_hydrate_stores (default [locks, hosts, quota, job_updates])
-       Which H2-backed stores to fully hydrate on the Snapshot.
 -stat_retention_period (default (1, hrs))
        Time for a stat to be retained in memory before expiring.
 -stat_sampling_interval (default (1, secs))
@@ -254,8 +236,6 @@ Optional flags:
        Additional Guice modules for intercepting Thrift method calls.
 -transient_task_state_timeout (default (5, mins))
        The amount of time after which to treat a task stuck in a transient 
state as LOST.
--use_beta_db_task_store (default false)
-       Whether to use the experimental database-backed task store.
 -viz_job_url_prefix (default )
        URL prefix for job container stats.
 -zk_chroot_path

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/examples/vagrant/upstart/aurora-scheduler-kerberos.conf
----------------------------------------------------------------------
diff --git a/examples/vagrant/upstart/aurora-scheduler-kerberos.conf 
b/examples/vagrant/upstart/aurora-scheduler-kerberos.conf
index 04e3d31..26b0241 100644
--- a/examples/vagrant/upstart/aurora-scheduler-kerberos.conf
+++ b/examples/vagrant/upstart/aurora-scheduler-kerberos.conf
@@ -52,6 +52,5 @@ exec bin/aurora-scheduler \
   -http_authentication_mechanism=NEGOTIATE \
   
-kerberos_server_keytab=/home/vagrant/krb5-1.13.1/build/testdir/HTTP-aurora.local.keytab
 \
   -kerberos_server_principal=HTTP/[email protected] \
-  -enable_h2_console=true \
   
-tier_config=/home/vagrant/aurora/src/main/resources/org/apache/aurora/scheduler/tiers.json
 \
   -offer_filter_duration=0secs

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/examples/vagrant/upstart/aurora-scheduler.conf
----------------------------------------------------------------------
diff --git a/examples/vagrant/upstart/aurora-scheduler.conf 
b/examples/vagrant/upstart/aurora-scheduler.conf
index 63fcc87..5ca3cae 100644
--- a/examples/vagrant/upstart/aurora-scheduler.conf
+++ b/examples/vagrant/upstart/aurora-scheduler.conf
@@ -44,9 +44,7 @@ exec bin/aurora-scheduler \
   -thermos_executor_flags="--announcer-ensemble localhost:2181 
--announcer-zookeeper-auth-config 
/home/vagrant/aurora/examples/vagrant/config/announcer-auth.json 
--mesos-containerizer-path=/usr/libexec/mesos/mesos-containerizer" \
   -allowed_container_types=MESOS,DOCKER \
   -http_authentication_mechanism=BASIC \
-  -use_beta_db_task_store=true \
   -shiro_ini_path=etc/shiro.example.ini \
-  -enable_h2_console=true \
   
-tier_config=/home/vagrant/aurora/src/main/resources/org/apache/aurora/scheduler/tiers.json
 \
   -mesos_role=aurora-role \
   -populate_discovery_info=true \

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/jmh/java/org/apache/aurora/benchmark/SchedulingBenchmarks.java
----------------------------------------------------------------------
diff --git a/src/jmh/java/org/apache/aurora/benchmark/SchedulingBenchmarks.java 
b/src/jmh/java/org/apache/aurora/benchmark/SchedulingBenchmarks.java
index 5a9099b..e0ec793 100644
--- a/src/jmh/java/org/apache/aurora/benchmark/SchedulingBenchmarks.java
+++ b/src/jmh/java/org/apache/aurora/benchmark/SchedulingBenchmarks.java
@@ -69,10 +69,10 @@ import 
org.apache.aurora.scheduler.scheduling.TaskScheduler.TaskSchedulerImpl.Re
 import org.apache.aurora.scheduler.state.StateModule;
 import org.apache.aurora.scheduler.storage.Storage;
 import org.apache.aurora.scheduler.storage.Storage.MutateWork.NoResult;
-import org.apache.aurora.scheduler.storage.db.DbUtil;
 import org.apache.aurora.scheduler.storage.entities.IHostAttributes;
 import org.apache.aurora.scheduler.storage.entities.IScheduledTask;
 import org.apache.aurora.scheduler.storage.entities.IServerInfo;
+import org.apache.aurora.scheduler.storage.mem.MemStorageModule;
 import org.apache.aurora.scheduler.updater.UpdateAgentReserver;
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -116,7 +116,7 @@ public class SchedulingBenchmarks {
      */
     @Setup(Level.Trial)
     public void setUpBenchmark() {
-      storage = DbUtil.createFlaggedStorage();
+      storage = MemStorageModule.newEmptyStorage();
       eventBus = new EventBus();
       final FakeClock clock = new FakeClock();
       clock.setNowMillis(System.currentTimeMillis());

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/jmh/java/org/apache/aurora/benchmark/SnapshotBenchmarks.java
----------------------------------------------------------------------
diff --git a/src/jmh/java/org/apache/aurora/benchmark/SnapshotBenchmarks.java 
b/src/jmh/java/org/apache/aurora/benchmark/SnapshotBenchmarks.java
index ae59f3d..755582d 100644
--- a/src/jmh/java/org/apache/aurora/benchmark/SnapshotBenchmarks.java
+++ b/src/jmh/java/org/apache/aurora/benchmark/SnapshotBenchmarks.java
@@ -17,22 +17,18 @@ import java.util.concurrent.TimeUnit;
 
 import javax.inject.Singleton;
 
-import com.google.common.base.Optional;
 import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Key;
-import com.google.inject.TypeLiteral;
 
 import org.apache.aurora.benchmark.fakes.FakeStatsProvider;
-import org.apache.aurora.common.inject.Bindings;
 import org.apache.aurora.common.stats.StatsProvider;
 import org.apache.aurora.common.util.Clock;
 import org.apache.aurora.gen.storage.Snapshot;
 import org.apache.aurora.scheduler.storage.Storage;
-import org.apache.aurora.scheduler.storage.db.DbModule;
 import org.apache.aurora.scheduler.storage.log.SnapshotStoreImpl;
-import 
org.apache.aurora.scheduler.storage.log.SnapshotStoreImpl.ExperimentalTaskStore;
+import org.apache.aurora.scheduler.storage.mem.MemStorageModule;
 import org.apache.thrift.TException;
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -85,7 +81,6 @@ public class SnapshotBenchmarks {
     }
 
     private SnapshotStoreImpl getSnapshotStore() {
-      Bindings.KeyFactory keyFactory = 
Bindings.annotatedKeyFactory(Storage.Volatile.class);
       Injector injector = Guice.createInjector(
           new AbstractModule() {
             @Override
@@ -93,13 +88,9 @@ public class SnapshotBenchmarks {
               bind(Clock.class).toInstance(Clock.SYSTEM_CLOCK);
               bind(StatsProvider.class).toInstance(new FakeStatsProvider());
               bind(SnapshotStoreImpl.class).in(Singleton.class);
-              bind(new TypeLiteral<Boolean>() { 
}).annotatedWith(ExperimentalTaskStore.class)
-                  .toInstance(true);
             }
           },
-          DbModule.testModuleWithWorkQueue(
-              keyFactory,
-              Optional.of(new DbModule.TaskStoreModule(keyFactory))));
+          new MemStorageModule());
 
       storage = injector.getInstance(Key.get(Storage.class, 
Storage.Volatile.class));
       storage.prepare();

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/jmh/java/org/apache/aurora/benchmark/StateManagerBenchmarks.java
----------------------------------------------------------------------
diff --git 
a/src/jmh/java/org/apache/aurora/benchmark/StateManagerBenchmarks.java 
b/src/jmh/java/org/apache/aurora/benchmark/StateManagerBenchmarks.java
index c293a9f..539393f 100644
--- a/src/jmh/java/org/apache/aurora/benchmark/StateManagerBenchmarks.java
+++ b/src/jmh/java/org/apache/aurora/benchmark/StateManagerBenchmarks.java
@@ -26,7 +26,6 @@ import com.google.inject.Injector;
 import org.apache.aurora.benchmark.fakes.FakeDriver;
 import org.apache.aurora.benchmark.fakes.FakeEventSink;
 import org.apache.aurora.benchmark.fakes.FakeRescheduleCalculator;
-import org.apache.aurora.common.inject.Bindings;
 import org.apache.aurora.common.stats.StatsProvider;
 import org.apache.aurora.common.util.Clock;
 import org.apache.aurora.gen.ScheduleStatus;
@@ -39,9 +38,9 @@ import org.apache.aurora.scheduler.state.StateManager;
 import org.apache.aurora.scheduler.state.StateManagerImpl;
 import org.apache.aurora.scheduler.storage.Storage;
 import org.apache.aurora.scheduler.storage.TaskStore;
-import org.apache.aurora.scheduler.storage.db.DbModule;
 import org.apache.aurora.scheduler.storage.entities.IScheduledTask;
 import org.apache.aurora.scheduler.storage.entities.ITaskConfig;
+import org.apache.aurora.scheduler.storage.mem.MemStorageModule;
 import org.apache.aurora.scheduler.testing.FakeStatsProvider;
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -185,7 +184,7 @@ public class StateManagerBenchmarks {
             bind(StatsProvider.class).toInstance(new FakeStatsProvider());
           }
         },
-        DbModule.productionModule(Bindings.KeyFactory.PLAIN, new 
DbModule.Options()),
+        new MemStorageModule(),
         // This is needed for storage
         new AsyncModule(new AsyncModule.Options())
     );

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/jmh/java/org/apache/aurora/benchmark/StatusUpdateBenchmark.java
----------------------------------------------------------------------
diff --git 
a/src/jmh/java/org/apache/aurora/benchmark/StatusUpdateBenchmark.java 
b/src/jmh/java/org/apache/aurora/benchmark/StatusUpdateBenchmark.java
index 45c2ab9..0c31c4a 100644
--- a/src/jmh/java/org/apache/aurora/benchmark/StatusUpdateBenchmark.java
+++ b/src/jmh/java/org/apache/aurora/benchmark/StatusUpdateBenchmark.java
@@ -75,9 +75,9 @@ import 
org.apache.aurora.scheduler.scheduling.RescheduleCalculator;
 import org.apache.aurora.scheduler.state.StateModule;
 import org.apache.aurora.scheduler.storage.Storage;
 import org.apache.aurora.scheduler.storage.Storage.MutateWork.NoResult;
-import org.apache.aurora.scheduler.storage.db.DbUtil;
 import org.apache.aurora.scheduler.storage.entities.IScheduledTask;
 import org.apache.aurora.scheduler.storage.entities.IServerInfo;
+import org.apache.aurora.scheduler.storage.mem.MemStorageModule;
 import org.apache.mesos.Scheduler;
 import org.apache.mesos.v1.Protos;
 import org.openjdk.jmh.annotations.Benchmark;
@@ -177,7 +177,7 @@ public class StatusUpdateBenchmark {
   @Setup(Level.Trial)
   public void setUpBenchmark() {
     eventBus = new EventBus();
-    storage = new SlowStorageWrapper(DbUtil.createStorage());
+    storage = new SlowStorageWrapper(MemStorageModule.newEmptyStorage());
 
     Injector injector = Guice.createInjector(
         new StateModule(new CliOptions()),

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/jmh/java/org/apache/aurora/benchmark/TaskStoreBenchmarks.java
----------------------------------------------------------------------
diff --git a/src/jmh/java/org/apache/aurora/benchmark/TaskStoreBenchmarks.java 
b/src/jmh/java/org/apache/aurora/benchmark/TaskStoreBenchmarks.java
index f5e44df..6f2f9f4 100644
--- a/src/jmh/java/org/apache/aurora/benchmark/TaskStoreBenchmarks.java
+++ b/src/jmh/java/org/apache/aurora/benchmark/TaskStoreBenchmarks.java
@@ -16,7 +16,7 @@ package org.apache.aurora.benchmark;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
-import com.google.common.base.Optional;
+import com.google.common.collect.Iterables;
 import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
 import com.google.inject.util.Modules;
@@ -27,10 +27,9 @@ import org.apache.aurora.common.util.testing.FakeClock;
 import org.apache.aurora.scheduler.base.Query;
 import org.apache.aurora.scheduler.storage.Storage;
 import org.apache.aurora.scheduler.storage.TaskStore;
-import org.apache.aurora.scheduler.storage.db.DbModule;
 import org.apache.aurora.scheduler.storage.db.DbUtil;
 import org.apache.aurora.scheduler.storage.entities.IScheduledTask;
-import org.apache.aurora.scheduler.storage.mem.InMemStoresModule;
+import org.apache.aurora.scheduler.storage.mem.MemStorageModule;
 import org.apache.aurora.scheduler.testing.FakeStatsProvider;
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -46,8 +45,6 @@ import org.openjdk.jmh.annotations.State;
 import org.openjdk.jmh.annotations.TearDown;
 import org.openjdk.jmh.annotations.Warmup;
 
-import static org.apache.aurora.common.inject.Bindings.KeyFactory.PLAIN;
-
 public class TaskStoreBenchmarks {
 
   @BenchmarkMode(Mode.Throughput)
@@ -85,9 +82,7 @@ public class TaskStoreBenchmarks {
     public void setUp() {
       storage = Guice.createInjector(
           Modules.combine(
-              DbModule.testModuleWithWorkQueue(
-                  PLAIN,
-                  Optional.of(new InMemStoresModule(new DbModule.Options(), 
PLAIN))),
+              new MemStorageModule(),
               new AbstractModule() {
                 @Override
                 protected void configure() {
@@ -110,8 +105,10 @@ public class TaskStoreBenchmarks {
     }
 
     @Benchmark
-    public Iterable<IScheduledTask> run() {
-      return storage.read(store -> 
store.getTaskStore().fetchTasks(Query.unscoped()));
+    public int run() {
+      // Iterate through results in case the result is lazily computed.
+      return Iterables.size(
+          storage.read(store -> 
store.getTaskStore().fetchTasks(Query.unscoped())));
     }
   }
 
@@ -133,8 +130,10 @@ public class TaskStoreBenchmarks {
     }
 
     @Benchmark
-    public Iterable<IScheduledTask> run() {
-      return storage.read(store -> 
store.getTaskStore().fetchTasks(Query.unscoped()));
+    public int run() {
+      // Iterate through results in case the result is lazily computed.
+      return Iterables.size(
+          storage.read(store -> 
store.getTaskStore().fetchTasks(Query.unscoped())));
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/jmh/java/org/apache/aurora/benchmark/ThriftApiBenchmarks.java
----------------------------------------------------------------------
diff --git a/src/jmh/java/org/apache/aurora/benchmark/ThriftApiBenchmarks.java 
b/src/jmh/java/org/apache/aurora/benchmark/ThriftApiBenchmarks.java
index 7b40506..7ccdb11 100644
--- a/src/jmh/java/org/apache/aurora/benchmark/ThriftApiBenchmarks.java
+++ b/src/jmh/java/org/apache/aurora/benchmark/ThriftApiBenchmarks.java
@@ -24,7 +24,6 @@ import com.google.inject.Guice;
 import com.google.inject.Injector;
 
 import org.apache.aurora.benchmark.fakes.FakeStatsProvider;
-import org.apache.aurora.common.inject.Bindings;
 import org.apache.aurora.common.stats.StatsProvider;
 import org.apache.aurora.common.util.Clock;
 import org.apache.aurora.gen.ReadOnlyScheduler;
@@ -38,8 +37,8 @@ import org.apache.aurora.scheduler.cron.CronPredictor;
 import org.apache.aurora.scheduler.quota.QuotaManager;
 import org.apache.aurora.scheduler.state.LockManager;
 import org.apache.aurora.scheduler.storage.Storage;
-import org.apache.aurora.scheduler.storage.db.DbModule;
 import org.apache.aurora.scheduler.storage.entities.IScheduledTask;
+import org.apache.aurora.scheduler.storage.mem.MemStorageModule;
 import org.apache.aurora.scheduler.thrift.ThriftModule;
 import org.apache.thrift.TException;
 import org.openjdk.jmh.annotations.Benchmark;
@@ -155,7 +154,7 @@ public class ThriftApiBenchmarks {
           }
         },
         new AsyncModule(new AsyncModule.Options()),
-        DbModule.productionModule(Bindings.KeyFactory.PLAIN, new 
DbModule.Options()),
+        new MemStorageModule(),
         new ThriftModule.ReadOnly());
   }
 

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/jmh/java/org/apache/aurora/benchmark/UpdateStoreBenchmarks.java
----------------------------------------------------------------------
diff --git 
a/src/jmh/java/org/apache/aurora/benchmark/UpdateStoreBenchmarks.java 
b/src/jmh/java/org/apache/aurora/benchmark/UpdateStoreBenchmarks.java
index cac02a5..992e950 100644
--- a/src/jmh/java/org/apache/aurora/benchmark/UpdateStoreBenchmarks.java
+++ b/src/jmh/java/org/apache/aurora/benchmark/UpdateStoreBenchmarks.java
@@ -20,9 +20,9 @@ import com.google.common.collect.Iterables;
 
 import org.apache.aurora.scheduler.storage.Storage;
 import org.apache.aurora.scheduler.storage.Storage.MutateWork.NoResult;
-import org.apache.aurora.scheduler.storage.db.DbUtil;
 import org.apache.aurora.scheduler.storage.entities.IJobUpdateDetails;
 import org.apache.aurora.scheduler.storage.entities.IJobUpdateKey;
+import org.apache.aurora.scheduler.storage.mem.MemStorageModule;
 import org.apache.thrift.TException;
 import org.openjdk.jmh.annotations.Benchmark;
 import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -54,7 +54,7 @@ public class UpdateStoreBenchmarks {
 
     @Setup(Level.Trial)
     public void setUp() {
-      storage = DbUtil.createStorage();
+      storage = MemStorageModule.newEmptyStorage();
     }
 
     @Setup(Level.Iteration)
@@ -94,7 +94,7 @@ public class UpdateStoreBenchmarks {
 
     @Setup(Level.Trial)
     public void setUp() {
-      storage = DbUtil.createStorage();
+      storage = MemStorageModule.newEmptyStorage();
     }
 
     @Setup(Level.Iteration)
@@ -134,7 +134,7 @@ public class UpdateStoreBenchmarks {
 
     @Setup(Level.Trial)
     public void setUp() {
-      storage = DbUtil.createStorage();
+      storage = MemStorageModule.newEmptyStorage();
     }
 
     @Setup(Level.Iteration)

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/app/SchedulerMain.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/app/SchedulerMain.java 
b/src/main/java/org/apache/aurora/scheduler/app/SchedulerMain.java
index dd0e480..7ffcf4f 100644
--- a/src/main/java/org/apache/aurora/scheduler/app/SchedulerMain.java
+++ b/src/main/java/org/apache/aurora/scheduler/app/SchedulerMain.java
@@ -60,12 +60,12 @@ import 
org.apache.aurora.scheduler.mesos.CommandLineDriverSettingsModule;
 import 
org.apache.aurora.scheduler.mesos.FrameworkInfoFactory.FrameworkInfoFactoryImpl.SchedulerProtocol;
 import org.apache.aurora.scheduler.mesos.LibMesosLoadingModule;
 import org.apache.aurora.scheduler.stats.StatsModule;
-import org.apache.aurora.scheduler.storage.Storage;
+import org.apache.aurora.scheduler.storage.Storage.Volatile;
 import org.apache.aurora.scheduler.storage.backup.BackupModule;
-import org.apache.aurora.scheduler.storage.db.DbModule;
 import org.apache.aurora.scheduler.storage.entities.IServerInfo;
 import org.apache.aurora.scheduler.storage.log.LogStorageModule;
 import org.apache.aurora.scheduler.storage.log.SnapshotStoreImpl;
+import org.apache.aurora.scheduler.storage.mem.MemStorageModule;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -189,9 +189,7 @@ public class SchedulerMain {
         new StatsModule(options.stats),
         new AppModule(options),
         new CronModule(options.cron),
-        new DbModule.MigrationManagerModule(),
-        
DbModule.productionModule(Bindings.annotatedKeyFactory(Storage.Volatile.class), 
options.db),
-        new DbModule.GarbageCollectorModule(options.db));
+        new MemStorageModule(Bindings.annotatedKeyFactory(Volatile.class)));
   }
 
   /**
@@ -277,7 +275,7 @@ public class SchedulerMain {
             new CommandLineDriverSettingsModule(options.driver, 
options.main.allowGpuResource),
             new LibMesosLoadingModule(options.main.driverImpl),
             new MesosLogStreamModule(options.mesosLog, 
FlaggedZooKeeperConfig.create(options.zk)),
-            new LogStorageModule(options.logStorage, 
options.db.useDbTaskStore),
+            new LogStorageModule(options.logStorage),
             new TierModule(options.tiers),
             new WebhookModule(options.webhook)
         )

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/config/CliOptions.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/config/CliOptions.java 
b/src/main/java/org/apache/aurora/scheduler/config/CliOptions.java
index 64733e5..d4537e3 100644
--- a/src/main/java/org/apache/aurora/scheduler/config/CliOptions.java
+++ b/src/main/java/org/apache/aurora/scheduler/config/CliOptions.java
@@ -29,7 +29,6 @@ import 
org.apache.aurora.scheduler.configuration.executor.ExecutorModule;
 import org.apache.aurora.scheduler.cron.quartz.CronModule;
 import org.apache.aurora.scheduler.discovery.FlaggedZooKeeperConfig;
 import org.apache.aurora.scheduler.events.WebhookModule;
-import org.apache.aurora.scheduler.http.H2ConsoleModule;
 import org.apache.aurora.scheduler.http.JettyServerModule;
 import org.apache.aurora.scheduler.http.api.ApiModule;
 import org.apache.aurora.scheduler.http.api.security.HttpSecurityModule;
@@ -48,7 +47,6 @@ import org.apache.aurora.scheduler.state.StateModule;
 import org.apache.aurora.scheduler.stats.AsyncStatsModule;
 import org.apache.aurora.scheduler.stats.StatsModule;
 import org.apache.aurora.scheduler.storage.backup.BackupModule;
-import org.apache.aurora.scheduler.storage.db.DbModule;
 import org.apache.aurora.scheduler.storage.log.LogStorageModule;
 import org.apache.aurora.scheduler.thrift.aop.AopModule;
 import org.apache.aurora.scheduler.updater.UpdaterModule;
@@ -65,7 +63,6 @@ public class CliOptions {
   public final FlaggedZooKeeperConfig.Options zk = new 
FlaggedZooKeeperConfig.Options();
   public final UpdaterModule.Options updater = new UpdaterModule.Options();
   public final StateModule.Options state = new StateModule.Options();
-  public final DbModule.Options db = new DbModule.Options();
   public final LogStorageModule.Options logStorage = new 
LogStorageModule.Options();
   public final BackupModule.Options backup = new BackupModule.Options();
   public final AopModule.Options aop = new AopModule.Options();
@@ -77,7 +74,6 @@ public class CliOptions {
   public final Kerberos5ShiroRealmModule.Options kerberos = new 
Kerberos5ShiroRealmModule.Options();
   public final IniShiroRealmModule.Options iniShiroRealm = new 
IniShiroRealmModule.Options();
   public final ApiModule.Options api = new ApiModule.Options();
-  public final H2ConsoleModule.Options h2Console = new 
H2ConsoleModule.Options();
   public final PreemptorModule.Options preemptor = new 
PreemptorModule.Options();
   public final MesosLogStreamModule.Options mesosLog = new 
MesosLogStreamModule.Options();
   public final SlaModule.Options sla = new SlaModule.Options();

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/http/JettyServerModule.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/aurora/scheduler/http/JettyServerModule.java 
b/src/main/java/org/apache/aurora/scheduler/http/JettyServerModule.java
index 47fd92f..b19bccd 100644
--- a/src/main/java/org/apache/aurora/scheduler/http/JettyServerModule.java
+++ b/src/main/java/org/apache/aurora/scheduler/http/JettyServerModule.java
@@ -195,7 +195,6 @@ public class JettyServerModule extends AbstractModule {
               parentInjector,
               Modules.combine(
                   new ApiModule(options.api),
-                  new H2ConsoleModule(options.h2Console),
                   new HttpSecurityModule(options),
                   new ThriftModule(),
                   new AopModule(options)));

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/storage/JobUpdateStore.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/aurora/scheduler/storage/JobUpdateStore.java 
b/src/main/java/org/apache/aurora/scheduler/storage/JobUpdateStore.java
index 254c9b7..5b57399 100644
--- a/src/main/java/org/apache/aurora/scheduler/storage/JobUpdateStore.java
+++ b/src/main/java/org/apache/aurora/scheduler/storage/JobUpdateStore.java
@@ -13,11 +13,13 @@
  */
 package org.apache.aurora.scheduler.storage;
 
+import java.util.EnumSet;
 import java.util.List;
 import java.util.Set;
 
 import com.google.common.base.Optional;
 
+import org.apache.aurora.gen.JobUpdateStatus;
 import org.apache.aurora.gen.storage.StoredJobUpdateDetails;
 import org.apache.aurora.scheduler.storage.entities.IJobInstanceUpdateEvent;
 import org.apache.aurora.scheduler.storage.entities.IJobUpdate;
@@ -28,11 +30,25 @@ import 
org.apache.aurora.scheduler.storage.entities.IJobUpdateKey;
 import org.apache.aurora.scheduler.storage.entities.IJobUpdateQuery;
 import org.apache.aurora.scheduler.storage.entities.IJobUpdateSummary;
 
+import static org.apache.aurora.gen.JobUpdateStatus.ABORTED;
+import static org.apache.aurora.gen.JobUpdateStatus.ERROR;
+import static org.apache.aurora.gen.JobUpdateStatus.FAILED;
+import static org.apache.aurora.gen.JobUpdateStatus.ROLLED_BACK;
+import static org.apache.aurora.gen.JobUpdateStatus.ROLLED_FORWARD;
+
 /**
  * Stores all job updates and defines methods for saving, updating and 
fetching job updates.
  */
 public interface JobUpdateStore {
 
+  EnumSet<JobUpdateStatus> TERMINAL_STATES = EnumSet.of(
+      ROLLED_FORWARD,
+      ROLLED_BACK,
+      ABORTED,
+      FAILED,
+      ERROR
+  );
+
   /**
    * Fetches a read-only view of job update summaries.
    *

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/storage/Storage.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/storage/Storage.java 
b/src/main/java/org/apache/aurora/scheduler/storage/Storage.java
index 6c67669..7e810ab 100644
--- a/src/main/java/org/apache/aurora/scheduler/storage/Storage.java
+++ b/src/main/java/org/apache/aurora/scheduler/storage/Storage.java
@@ -32,6 +32,10 @@ import 
org.apache.aurora.scheduler.storage.entities.IScheduledTask;
  */
 public interface Storage {
 
+  /**
+   * Provider for read-only stores.  Store implementations must be 
thread-safe, and should support
+   * concurrent reads where appropriate.
+   */
   interface StoreProvider {
     SchedulerStore getSchedulerStore();
     CronJobStore getCronJobStore();
@@ -42,6 +46,10 @@ public interface Storage {
     JobUpdateStore getJobUpdateStore();
   }
 
+  /**
+   * Provider for stores that permit mutations.  Store implementations need 
not support concurrent
+   * writes, as a global reentrant write lock is used to serialize write 
operations.
+   */
   interface MutableStoreProvider extends StoreProvider {
     SchedulerStore.Mutable getSchedulerStore();
     CronJobStore.Mutable getCronJobStore();
@@ -65,19 +73,6 @@ public interface Storage {
     QuotaStore.Mutable getQuotaStore();
     AttributeStore.Mutable getAttributeStore();
     JobUpdateStore.Mutable getJobUpdateStore();
-
-    /**
-     * Gets direct low level access to the underlying storage.
-     * <p>
-     * This grants a potentially dangerous direct access to the underlying 
storage and should
-     * only be used during storage initialization when unstructured bulk data 
manipulations
-     * are required.
-     * </p>
-     *
-     * @param <T> Direct access type.
-     * @return Direct read/write accessor to the storage.
-     */
-    <T> T getUnsafeStoreAccess();
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/storage/Util.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/storage/Util.java 
b/src/main/java/org/apache/aurora/scheduler/storage/Util.java
new file mode 100644
index 0000000..01c6a8a
--- /dev/null
+++ b/src/main/java/org/apache/aurora/scheduler/storage/Util.java
@@ -0,0 +1,45 @@
+/**
+ * Licensed 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.aurora.scheduler.storage;
+
+import org.apache.aurora.gen.JobUpdateAction;
+import org.apache.aurora.gen.JobUpdateStatus;
+
+public final class Util {
+
+  private Util() {
+    // Utility class.
+  }
+
+  /**
+   * Gets the gauge name for the running count of {@link JobUpdateAction}s.
+   *
+   * @param action Update action.
+   * @return Gauge name.
+   */
+  public static String jobUpdateActionStatName(JobUpdateAction action) {
+    return "update_instance_transition_" + action;
+  }
+
+  /**
+   * Gets the gauge name for the running count of {@link JobUpdateStatus}es.
+   *
+   * @param status Update status.
+   * @return Gauge name.
+   */
+  public static String jobUpdateStatusStatName(JobUpdateStatus status) {
+    return "update_transition_" + status;
+  }
+}

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/storage/backup/TemporaryStorage.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/aurora/scheduler/storage/backup/TemporaryStorage.java
 
b/src/main/java/org/apache/aurora/scheduler/storage/backup/TemporaryStorage.java
index bad05f5..3000796 100644
--- 
a/src/main/java/org/apache/aurora/scheduler/storage/backup/TemporaryStorage.java
+++ 
b/src/main/java/org/apache/aurora/scheduler/storage/backup/TemporaryStorage.java
@@ -17,7 +17,6 @@ import java.util.Set;
 
 import com.google.common.base.Function;
 import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableSet;
 import com.google.inject.Inject;
 
 import org.apache.aurora.common.util.BuildInfo;
@@ -28,11 +27,10 @@ import org.apache.aurora.scheduler.base.Tasks;
 import org.apache.aurora.scheduler.storage.SnapshotStore;
 import org.apache.aurora.scheduler.storage.Storage;
 import org.apache.aurora.scheduler.storage.Storage.MutateWork.NoResult;
-import org.apache.aurora.scheduler.storage.db.DbUtil;
-import org.apache.aurora.scheduler.storage.db.EnumBackfill;
 import org.apache.aurora.scheduler.storage.entities.IScheduledTask;
 import org.apache.aurora.scheduler.storage.log.SnapshotStoreImpl;
 import org.apache.aurora.scheduler.storage.log.ThriftBackfill;
+import org.apache.aurora.scheduler.storage.mem.MemStorageModule;
 
 import static java.util.Objects.requireNonNull;
 
@@ -72,17 +70,15 @@ interface TemporaryStorage {
   class TemporaryStorageFactory implements Function<Snapshot, 
TemporaryStorage> {
 
     private final ThriftBackfill thriftBackfill;
-    private final EnumBackfill enumBackfill;
 
     @Inject
-    TemporaryStorageFactory(ThriftBackfill thriftBackfill, EnumBackfill 
enumBackfill) {
+    TemporaryStorageFactory(ThriftBackfill thriftBackfill) {
       this.thriftBackfill = requireNonNull(thriftBackfill);
-      this.enumBackfill = requireNonNull(enumBackfill);
     }
 
     @Override
     public TemporaryStorage apply(Snapshot snapshot) {
-      final Storage storage = DbUtil.createFlaggedStorage();
+      final Storage storage = MemStorageModule.newEmptyStorage();
       final BuildInfo buildInfo = generateBuildInfo();
       FakeClock clock = new FakeClock();
       clock.setNowMillis(snapshot.getTimestamp());
@@ -90,17 +86,7 @@ interface TemporaryStorage {
           buildInfo,
           clock,
           storage,
-          // Safe to pass false here to default to the non-experimental task 
store
-          // during restore from backup procedure.
-          false /** useDbSnapshotForTaskStore */,
-          // Safe to pass empty set here because during backup restore we are 
not deciding which
-          // fields to write to the snapshot.
-          ImmutableSet.of() /** hydrateFields */,
-          // We can just pass an empty lambda for the MigrationManager as 
migration is a no-op
-          // when restoring from backup.
-          () -> { } /** migrationManager */,
-          thriftBackfill,
-          enumBackfill);
+          thriftBackfill);
       snapshotStore.applySnapshot(snapshot);
 
       return new TemporaryStorage() {

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/storage/db/DbJobUpdateStore.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/aurora/scheduler/storage/db/DbJobUpdateStore.java 
b/src/main/java/org/apache/aurora/scheduler/storage/db/DbJobUpdateStore.java
index df37fb7..af854da 100644
--- a/src/main/java/org/apache/aurora/scheduler/storage/db/DbJobUpdateStore.java
+++ b/src/main/java/org/apache/aurora/scheduler/storage/db/DbJobUpdateStore.java
@@ -19,7 +19,6 @@ import java.util.concurrent.atomic.AtomicLong;
 
 import javax.inject.Inject;
 
-import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Function;
 import com.google.common.base.Optional;
 import com.google.common.cache.CacheBuilder;
@@ -34,6 +33,7 @@ import org.apache.aurora.gen.JobUpdateAction;
 import org.apache.aurora.gen.JobUpdateStatus;
 import org.apache.aurora.gen.storage.StoredJobUpdateDetails;
 import org.apache.aurora.scheduler.storage.JobUpdateStore;
+import org.apache.aurora.scheduler.storage.Util;
 import org.apache.aurora.scheduler.storage.db.views.DbJobUpdate;
 import org.apache.aurora.scheduler.storage.db.views.DbJobUpdateInstructions;
 import org.apache.aurora.scheduler.storage.db.views.DbStoredJobUpdateDetails;
@@ -84,7 +84,7 @@ public class DbJobUpdateStore implements 
JobUpdateStore.Mutable {
         .build(new CacheLoader<JobUpdateStatus, AtomicLong>() {
           @Override
           public AtomicLong load(JobUpdateStatus status) {
-            return statsProvider.makeCounter(jobUpdateStatusStatName(status));
+            return 
statsProvider.makeCounter(Util.jobUpdateStatusStatName(status));
           }
         });
     for (JobUpdateStatus status : JobUpdateStatus.values()) {
@@ -94,7 +94,7 @@ public class DbJobUpdateStore implements 
JobUpdateStore.Mutable {
         .build(new CacheLoader<JobUpdateAction, AtomicLong>() {
           @Override
           public AtomicLong load(JobUpdateAction action) {
-            return statsProvider.makeCounter(jobUpdateActionStatName(action));
+            return 
statsProvider.makeCounter(Util.jobUpdateActionStatName(action));
           }
         });
     for (JobUpdateAction action : JobUpdateAction.values()) {
@@ -165,11 +165,6 @@ public class DbJobUpdateStore implements 
JobUpdateStore.Mutable {
     }
   }
 
-  @VisibleForTesting
-  static String jobUpdateStatusStatName(JobUpdateStatus status) {
-    return "update_transition_" + status;
-  }
-
   @Timed("job_update_store_save_event")
   @Override
   public void saveJobUpdateEvent(IJobUpdateKey key, IJobUpdateEvent event) {
@@ -177,11 +172,6 @@ public class DbJobUpdateStore implements 
JobUpdateStore.Mutable {
     jobUpdateEventStats.getUnchecked(event.getStatus()).incrementAndGet();
   }
 
-  @VisibleForTesting
-  static String jobUpdateActionStatName(JobUpdateAction action) {
-    return "update_instance_transition_" + action;
-  }
-
   @Timed("job_update_store_save_instance_event")
   @Override
   public void saveJobInstanceUpdateEvent(IJobUpdateKey key, 
IJobInstanceUpdateEvent event) {

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/storage/db/DbModule.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/storage/db/DbModule.java 
b/src/main/java/org/apache/aurora/scheduler/storage/db/DbModule.java
index fb3dadb..7bd37f7 100644
--- a/src/main/java/org/apache/aurora/scheduler/storage/db/DbModule.java
+++ b/src/main/java/org/apache/aurora/scheduler/storage/db/DbModule.java
@@ -23,7 +23,6 @@ import com.beust.jcommander.Parameter;
 import com.beust.jcommander.Parameters;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Joiner;
-import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.util.concurrent.AbstractScheduledService;
@@ -50,7 +49,6 @@ import org.apache.aurora.scheduler.storage.SchedulerStore;
 import org.apache.aurora.scheduler.storage.Storage;
 import org.apache.aurora.scheduler.storage.TaskStore;
 import org.apache.aurora.scheduler.storage.db.typehandlers.TypeHandlers;
-import org.apache.aurora.scheduler.storage.mem.InMemStoresModule;
 import org.apache.ibatis.migration.JavaMigrationLoader;
 import org.apache.ibatis.migration.MigrationLoader;
 import org.apache.ibatis.session.AutoMappingBehavior;
@@ -71,11 +69,6 @@ public final class DbModule extends PrivateModule {
 
   @Parameters(separators = "=")
   public static class Options {
-    @Parameter(names = "-use_beta_db_task_store",
-        description = "Whether to use the experimental database-backed task 
store.",
-        arity = 1)
-    public boolean useDbTaskStore = false;
-
     @Parameter(names = "-enable_db_metrics",
         description =
             "Whether to use MyBatis interceptor to measure the timing of 
intercepted Statements.",
@@ -121,19 +114,16 @@ public final class DbModule extends PrivateModule {
 
   private final Options options;
   private final KeyFactory keyFactory;
-  private final Module taskStoresModule;
   private final String jdbcSchema;
 
   private DbModule(
       Options options,
       KeyFactory keyFactory,
-      Module taskStoresModule,
       String dbName,
       Map<String, String> jdbcUriArgs) {
 
     this.options = requireNonNull(options);
     this.keyFactory = requireNonNull(keyFactory);
-    this.taskStoresModule = requireNonNull(taskStoresModule);
 
     Map<String, String> args = ImmutableMap.<String, String>builder()
         .putAll(jdbcUriArgs)
@@ -162,19 +152,16 @@ public final class DbModule extends PrivateModule {
     return new DbModule(
         options,
         keyFactory,
-        getTaskStoreModule(options, keyFactory),
         "aurora",
         ImmutableMap.of("DB_CLOSE_DELAY", "-1"));
   }
 
   @VisibleForTesting
-  public static Module testModule(KeyFactory keyFactory, Optional<Module> 
taskStoreModule) {
+  public static Module testModule(KeyFactory keyFactory) {
     DbModule.Options options = new DbModule.Options();
     return new DbModule(
         options,
         keyFactory,
-        taskStoreModule.isPresent()
-            ? taskStoreModule.get() : getTaskStoreModule(options, keyFactory),
         "testdb-" + UUID.randomUUID().toString(),
         // A non-zero close delay is used here to avoid eager database cleanup 
in tests that
         // make use of multiple threads.  Since all test databases are 
separately scoped by the
@@ -184,14 +171,14 @@ public final class DbModule extends PrivateModule {
   }
 
   /**
-   * Same as {@link #testModuleWithWorkQueue(KeyFactory, Optional)} but with 
default task store and
+   * Same as {@link #testModuleWithWorkQueue(KeyFactory)} but with default 
task store and
    * key factory.
    *
    * @return A new database module for testing.
    */
   @VisibleForTesting
   public static Module testModule() {
-    return testModule(KeyFactory.PLAIN, Optional.of(new 
TaskStoreModule(KeyFactory.PLAIN)));
+    return testModule(KeyFactory.PLAIN);
   }
 
   /**
@@ -199,14 +186,10 @@ public final class DbModule extends PrivateModule {
    * implementation bound within the key factory and provided module.
    *
    * @param keyFactory Key factory to use.
-   * @param taskStoreModule Module providing task store bindings.
    * @return A new database module for testing.
    */
   @VisibleForTesting
-  public static Module testModuleWithWorkQueue(
-      KeyFactory keyFactory,
-      Optional<Module> taskStoreModule) {
-
+  public static Module testModuleWithWorkQueue(KeyFactory keyFactory) {
     return Modules.combine(
         new AbstractModule() {
           @Override
@@ -222,27 +205,18 @@ public final class DbModule extends PrivateModule {
                 });
           }
         },
-        testModule(keyFactory, taskStoreModule)
+        testModule(keyFactory)
     );
   }
 
   /**
-   * Same as {@link #testModuleWithWorkQueue(KeyFactory, Optional)} but with 
default task store and
-   * key factory.
+   * Same as {@link #testModuleWithWorkQueue(KeyFactory)} but with default key 
factory.
    *
    * @return A new database module for testing.
    */
   @VisibleForTesting
   public static Module testModuleWithWorkQueue() {
-    return testModuleWithWorkQueue(
-        KeyFactory.PLAIN,
-        Optional.of(new TaskStoreModule(KeyFactory.PLAIN)));
-  }
-
-  private static Module getTaskStoreModule(Options options, KeyFactory 
keyFactory) {
-    return options.useDbTaskStore
-        ? new TaskStoreModule(keyFactory)
-        : new InMemStoresModule(options, keyFactory);
+    return testModuleWithWorkQueue(KeyFactory.PLAIN);
   }
 
   private <T> void bindStore(Class<T> binding, Class<? extends T> impl) {
@@ -308,7 +282,6 @@ public final class DbModule extends PrivateModule {
         expose(JobKeyMapper.class);
       }
     });
-    install(taskStoresModule);
     expose(keyFactory.create(CronJobStore.Mutable.class));
     expose(keyFactory.create(TaskStore.Mutable.class));
 
@@ -317,6 +290,8 @@ public final class DbModule extends PrivateModule {
     bindStore(QuotaStore.Mutable.class, DbQuotaStore.class);
     bindStore(SchedulerStore.Mutable.class, DbSchedulerStore.class);
     bindStore(JobUpdateStore.Mutable.class, DbJobUpdateStore.class);
+    bindStore(TaskStore.Mutable.class, DbTaskStore.class);
+    bindStore(CronJobStore.Mutable.class, DbCronJobStore.class);
 
     Key<Storage> storageKey = keyFactory.create(Storage.class);
     bind(storageKey).to(DbStorage.class);
@@ -335,35 +310,6 @@ public final class DbModule extends PrivateModule {
   }
 
   /**
-   * A module that binds a database task store.
-   * <p/>
-   * TODO(wfarner): Inline these bindings once there is only one task store 
implementation.
-   */
-  public static class TaskStoreModule extends PrivateModule {
-    private final KeyFactory keyFactory;
-
-    public TaskStoreModule(KeyFactory keyFactory) {
-      this.keyFactory = requireNonNull(keyFactory);
-    }
-
-    private <T> void bindStore(Class<T> binding, Class<? extends T> impl) {
-      bind(binding).to(impl);
-      bind(impl).in(Singleton.class);
-      Key<T> key = keyFactory.create(binding);
-      bind(key).to(impl);
-      expose(key);
-    }
-
-    @Override
-    protected void configure() {
-      bindStore(TaskStore.Mutable.class, DbTaskStore.class);
-      expose(TaskStore.Mutable.class);
-      bindStore(CronJobStore.Mutable.class, DbCronJobStore.class);
-      expose(DbCronJobStore.Mutable.class);
-    }
-  }
-
-  /**
    * Module that sets up a periodic database garbage-collection routine.
    */
   public static class GarbageCollectorModule extends AbstractModule {

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/storage/db/DbStorage.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/aurora/scheduler/storage/db/DbStorage.java 
b/src/main/java/org/apache/aurora/scheduler/storage/db/DbStorage.java
index 7904e38..aa7c03b 100644
--- a/src/main/java/org/apache/aurora/scheduler/storage/db/DbStorage.java
+++ b/src/main/java/org/apache/aurora/scheduler/storage/db/DbStorage.java
@@ -57,7 +57,7 @@ import static org.apache.ibatis.mapping.SqlCommandType.UPDATE;
  * <p>
  * Delegates read and write concurrency semantics to the underlying database.
  */
-class DbStorage extends AbstractIdleService implements Storage {
+public class DbStorage extends AbstractIdleService implements Storage {
 
   private final SqlSessionFactory sessionFactory;
   private final EnumBackfill enumBackfill;
@@ -129,16 +129,15 @@ class DbStorage extends AbstractIdleService implements 
Storage {
       public JobUpdateStore.Mutable getJobUpdateStore() {
         return jobUpdateStore;
       }
-
-      @Override
-      @SuppressWarnings("unchecked")
-      public <T> T getUnsafeStoreAccess() {
-        return (T) 
sessionFactory.getConfiguration().getEnvironment().getDataSource();
-      }
     };
     this.statsProvider = requireNonNull(statsProvider);
   }
 
+  @SuppressWarnings("unchecked")
+  public <T> T getUnsafeStoreAccess() {
+    return (T) 
sessionFactory.getConfiguration().getEnvironment().getDataSource();
+  }
+
   @Timed("db_storage_read_operation")
   @Override
   @Transactional

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/storage/db/DbUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/storage/db/DbUtil.java 
b/src/main/java/org/apache/aurora/scheduler/storage/db/DbUtil.java
index 942d180..443b473 100644
--- a/src/main/java/org/apache/aurora/scheduler/storage/db/DbUtil.java
+++ b/src/main/java/org/apache/aurora/scheduler/storage/db/DbUtil.java
@@ -13,7 +13,6 @@
  */
 package org.apache.aurora.scheduler.storage.db;
 
-import com.google.common.base.Optional;
 import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
@@ -25,7 +24,6 @@ import org.apache.aurora.common.util.testing.FakeClock;
 import org.apache.aurora.scheduler.storage.Storage;
 import org.apache.aurora.scheduler.testing.FakeStatsProvider;
 
-import static org.apache.aurora.common.inject.Bindings.KeyFactory.PLAIN;
 import static 
org.apache.aurora.scheduler.storage.db.DbModule.testModuleWithWorkQueue;
 
 /**
@@ -75,14 +73,4 @@ public final class DbUtil {
   public static Storage createStorage() {
     return 
createStorageInjector(testModuleWithWorkQueue()).getInstance(Storage.class);
   }
-
-  /**
-   * Creates a new, empty storage system with a task store defined by the 
command line flag.
-   *
-   * @return A new storage instance.
-   */
-  public static Storage createFlaggedStorage() {
-    return createStorageInjector(testModuleWithWorkQueue(PLAIN, 
Optional.absent()))
-        .getInstance(Storage.class);
-  }
 }

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/storage/log/LogStorageModule.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/aurora/scheduler/storage/log/LogStorageModule.java 
b/src/main/java/org/apache/aurora/scheduler/storage/log/LogStorageModule.java
index 63150d0..c8dc7ad 100644
--- 
a/src/main/java/org/apache/aurora/scheduler/storage/log/LogStorageModule.java
+++ 
b/src/main/java/org/apache/aurora/scheduler/storage/log/LogStorageModule.java
@@ -13,8 +13,6 @@
  */
 package org.apache.aurora.scheduler.storage.log;
 
-import java.util.Set;
-
 import javax.inject.Singleton;
 
 import com.beust.jcommander.Parameter;
@@ -36,8 +34,6 @@ import org.apache.aurora.scheduler.storage.Storage;
 import org.apache.aurora.scheduler.storage.Storage.NonVolatileStorage;
 import org.apache.aurora.scheduler.storage.log.LogManager.MaxEntrySize;
 import org.apache.aurora.scheduler.storage.log.LogStorage.Settings;
-import 
org.apache.aurora.scheduler.storage.log.SnapshotStoreImpl.ExperimentalTaskStore;
-import 
org.apache.aurora.scheduler.storage.log.SnapshotStoreImpl.HydrateSnapshotFields;
 
 import static 
org.apache.aurora.scheduler.storage.log.EntrySerializer.EntrySerializerImpl;
 import static 
org.apache.aurora.scheduler.storage.log.LogManager.LogEntryHashFunction;
@@ -65,18 +61,12 @@ public class LogStorageModule extends PrivateModule {
             "Specifies the maximum entry size to append to the log. Larger 
entries will be "
                 + "split across entry Frames.")
     public DataAmount maxLogEntrySize = new DataAmount(512, Data.KB);
-
-    @Parameter(names = "-snapshot_hydrate_stores",
-        description = "Which H2-backed stores to fully hydrate on the 
Snapshot.")
-    public Set<String> hydrateSnapshotFields = 
SnapshotStoreImpl.ALL_H2_STORE_FIELDS;
   }
 
   private final Options options;
-  private final boolean useDbTaskStore;
 
-  public LogStorageModule(Options options, boolean useDbTaskStore) {
+  public LogStorageModule(Options options) {
     this.options = options;
-    this.useDbTaskStore = useDbTaskStore;
   }
 
   @Override
@@ -84,24 +74,16 @@ public class LogStorageModule extends PrivateModule {
     bind(Settings.class)
         .toInstance(new Settings(options.shutdownGracePeriod, 
options.snapshotInterval));
 
-    bind(new TypeLiteral<Boolean>() { 
}).annotatedWith(ExperimentalTaskStore.class)
-        .toInstance(useDbTaskStore);
-
     bind(new TypeLiteral<Amount<Integer, Data>>() { 
}).annotatedWith(MaxEntrySize.class)
         .toInstance(options.maxLogEntrySize);
     bind(LogManager.class).in(Singleton.class);
     bind(LogStorage.class).in(Singleton.class);
 
-    bind(new TypeLiteral<Set<String>>() { 
}).annotatedWith(HydrateSnapshotFields.class)
-        .toInstance(options.hydrateSnapshotFields);
-
     install(CallOrderEnforcingStorage.wrappingModule(LogStorage.class));
     bind(DistributedSnapshotStore.class).to(LogStorage.class);
     expose(Storage.class);
     expose(NonVolatileStorage.class);
     expose(DistributedSnapshotStore.class);
-    expose(new TypeLiteral<Boolean>() { 
}).annotatedWith(ExperimentalTaskStore.class);
-    expose(new TypeLiteral<Set<String>>() { 
}).annotatedWith(HydrateSnapshotFields.class);
 
     bind(EntrySerializer.class).to(EntrySerializerImpl.class);
     // TODO(ksweeney): We don't need a cryptographic checksum here - assess 
performance of MD5

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/storage/log/SnapshotStoreImpl.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/aurora/scheduler/storage/log/SnapshotStoreImpl.java 
b/src/main/java/org/apache/aurora/scheduler/storage/log/SnapshotStoreImpl.java
index fdf9c33..3258879 100644
--- 
a/src/main/java/org/apache/aurora/scheduler/storage/log/SnapshotStoreImpl.java
+++ 
b/src/main/java/org/apache/aurora/scheduler/storage/log/SnapshotStoreImpl.java
@@ -13,13 +13,8 @@
  */
 package org.apache.aurora.scheduler.storage.log;
 
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
-import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.Arrays;
 import java.util.List;
@@ -27,7 +22,6 @@ import java.util.Map;
 import java.util.Set;
 
 import javax.inject.Inject;
-import javax.inject.Qualifier;
 import javax.sql.DataSource;
 
 import com.google.common.annotations.VisibleForTesting;
@@ -36,9 +30,10 @@ import com.google.common.base.Optional;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
-import com.google.common.collect.ImmutableList;
+import com.google.common.collect.FluentIterable;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
+import com.google.inject.Injector;
 
 import org.apache.aurora.common.inject.TimedInterceptor.Timed;
 import org.apache.aurora.common.stats.SlidingStats;
@@ -62,6 +57,9 @@ import org.apache.aurora.scheduler.storage.Storage;
 import org.apache.aurora.scheduler.storage.Storage.MutableStoreProvider;
 import org.apache.aurora.scheduler.storage.Storage.MutateWork.NoResult;
 import org.apache.aurora.scheduler.storage.Storage.Volatile;
+import org.apache.aurora.scheduler.storage.db.DbModule;
+import org.apache.aurora.scheduler.storage.db.DbStorage;
+import org.apache.aurora.scheduler.storage.db.DbUtil;
 import org.apache.aurora.scheduler.storage.db.EnumBackfill;
 import org.apache.aurora.scheduler.storage.db.MigrationManager;
 import org.apache.aurora.scheduler.storage.entities.IHostAttributes;
@@ -95,16 +93,6 @@ public class SnapshotStoreImpl implements 
SnapshotStore<Snapshot> {
    */
   private static final int DB_BATCH_SIZE = 20;
 
-  private static boolean hasDbSnapshot(Snapshot snapshot) {
-    return snapshot.isSetDbScript();
-  }
-
-  private boolean hasDbTaskStore(Snapshot snapshot) {
-    return useDbSnapshotForTaskStore
-        && hasDbSnapshot(snapshot)
-        && snapshot.isExperimentalTaskStore();
-  }
-
   private static final String DB_SCRIPT_FIELD = "dbscript";
   private static final String LOCK_FIELD = "locks";
   private static final String HOST_ATTRIBUTES_FIELD = "hosts";
@@ -114,15 +102,12 @@ public class SnapshotStoreImpl implements 
SnapshotStore<Snapshot> {
   private static final String JOB_UPDATE_FIELD = "job_updates";
   private static final String SCHEDULER_METADATA_FIELD = "scheduler_metadata";
 
-  /**
-   * Used by LogStorageModule to maintain legacy behavior for a change to 
snapshot format
-   * (and thus also backup processing) behavior. See AURORA-1861 for context.
-   */
-  public static final Set<String> ALL_H2_STORE_FIELDS = ImmutableSet.of(
-      LOCK_FIELD,
-      HOST_ATTRIBUTES_FIELD,
-      QUOTA_FIELD,
-      JOB_UPDATE_FIELD);
+  @VisibleForTesting
+  Set<String> snapshotFieldNames() {
+    return FluentIterable.from(snapshotFields)
+        .transform(SnapshotField::getName)
+        .toSet();
+  }
 
   private final Iterable<SnapshotField> snapshotFields = Arrays.asList(
       // Order is critical here. The DB snapshot should always be tried first 
to ensure
@@ -143,29 +128,21 @@ public class SnapshotStoreImpl implements 
SnapshotStore<Snapshot> {
 
         @Override
         public void saveToSnapshot(MutableStoreProvider store, Snapshot 
snapshot) {
-          LOG.info("Saving dbsnapshot");
-          // Note: we don't use mybatis mapped statements for performance 
reasons and to avoid
-          // mapping/unmapping hassle as snapshot commands should never be 
used upstream.
-          try (Connection c = ((DataSource) 
store.getUnsafeStoreAccess()).getConnection()) {
-            try (PreparedStatement ps = c.prepareStatement("SCRIPT")) {
-              try (ResultSet rs = ps.executeQuery()) {
-                ImmutableList.Builder<String> builder = 
ImmutableList.builder();
-                while (rs.next()) {
-                  String columnValue = rs.getString("SCRIPT");
-                  builder.add(columnValue + "\n");
-                }
-                snapshot.setDbScript(builder.build());
-              }
-            }
-          } catch (SQLException e) {
-            throw new RuntimeException(e);
-          }
+          // No-op.
         }
 
         @Override
         public void restoreFromSnapshot(MutableStoreProvider store, Snapshot 
snapshot) {
           if (snapshot.isSetDbScript()) {
-            try (Connection c = ((DataSource) 
store.getUnsafeStoreAccess()).getConnection()) {
+            LOG.info("Loading contents from legacy dbScript field");
+
+            Injector injector = 
DbUtil.createStorageInjector(DbModule.testModuleWithWorkQueue());
+
+            DbStorage tempStorage = injector.getInstance(DbStorage.class);
+            MigrationManager migrationManager = 
injector.getInstance(MigrationManager.class);
+            EnumBackfill enumBackfill = 
injector.getInstance(EnumBackfill.class);
+
+            try (Connection c = ((DataSource) 
tempStorage.getUnsafeStoreAccess()).getConnection()) {
               LOG.info("Dropping all tables");
               try (PreparedStatement drop = c.prepareStatement("DROP ALL 
OBJECTS")) {
                 drop.executeUpdate();
@@ -193,6 +170,10 @@ public class SnapshotStoreImpl implements 
SnapshotStore<Snapshot> {
             // This ensures any subsequently added enum values since the last 
snapshot exist in
             // the db.
             enumBackfill.backfill();
+
+            // Load the contents of the DB into the main storage.
+            Snapshot dbSnapshot = createSnapshot(tempStorage);
+            applySnapshot(dbSnapshot);
           }
         }
       },
@@ -206,21 +187,13 @@ public class SnapshotStoreImpl implements 
SnapshotStore<Snapshot> {
         // references to be valid on insertion.
         @Override
         public void saveToSnapshot(MutableStoreProvider store, Snapshot 
snapshot) {
-          if (hydrateSnapshotFields.contains(getName())) {
-            
snapshot.setLocks(ILock.toBuildersSet(store.getLockStore().fetchLocks()));
-          }
+          
snapshot.setLocks(ILock.toBuildersSet(store.getLockStore().fetchLocks()));
         }
 
         @Override
         public void restoreFromSnapshot(MutableStoreProvider store, Snapshot 
snapshot) {
-          if (hasDbSnapshot(snapshot)) {
-            LOG.info("Deferring lock restore to dbsnapshot");
-            return;
-          }
-
-          store.getLockStore().deleteLocks();
-
-          if (snapshot.isSetLocks()) {
+          if (snapshot.getLocksSize() > 0) {
+            store.getLockStore().deleteLocks();
             for (Lock lock : snapshot.getLocks()) {
               store.getLockStore().saveLock(ILock.build(lock));
             }
@@ -235,22 +208,14 @@ public class SnapshotStoreImpl implements 
SnapshotStore<Snapshot> {
 
         @Override
         public void saveToSnapshot(MutableStoreProvider store, Snapshot 
snapshot) {
-          if (hydrateSnapshotFields.contains(getName())) {
-            snapshot.setHostAttributes(
-                
IHostAttributes.toBuildersSet(store.getAttributeStore().getHostAttributes()));
-          }
+          snapshot.setHostAttributes(
+              
IHostAttributes.toBuildersSet(store.getAttributeStore().getHostAttributes()));
         }
 
         @Override
         public void restoreFromSnapshot(MutableStoreProvider store, Snapshot 
snapshot) {
-          if (hasDbSnapshot(snapshot)) {
-            LOG.info("Deferring attribute restore to dbsnapshot");
-            return;
-          }
-
-          store.getAttributeStore().deleteHostAttributes();
-
-          if (snapshot.isSetHostAttributes()) {
+          if (snapshot.getHostAttributesSize() > 0) {
+            store.getAttributeStore().deleteHostAttributes();
             for (HostAttributes attributes : snapshot.getHostAttributes()) {
               
store.getAttributeStore().saveHostAttributes(IHostAttributes.build(attributes));
             }
@@ -267,19 +232,12 @@ public class SnapshotStoreImpl implements 
SnapshotStore<Snapshot> {
         public void saveToSnapshot(MutableStoreProvider store, Snapshot 
snapshot) {
           snapshot.setTasks(
               
IScheduledTask.toBuildersSet(store.getTaskStore().fetchTasks(Query.unscoped())));
-          snapshot.setExperimentalTaskStore(useDbSnapshotForTaskStore);
         }
 
         @Override
         public void restoreFromSnapshot(MutableStoreProvider store, Snapshot 
snapshot) {
-          if (hasDbTaskStore(snapshot)) {
-            LOG.info("Deferring task restore to dbsnapshot");
-            return;
-          }
-
-          store.getUnsafeTaskStore().deleteAllTasks();
-
-          if (snapshot.isSetTasks()) {
+          if (snapshot.getTasksSize() > 0) {
+            store.getUnsafeTaskStore().deleteAllTasks();
             store.getUnsafeTaskStore()
                 .saveTasks(thriftBackfill.backfillTasks(snapshot.getTasks()));
           }
@@ -299,19 +257,12 @@ public class SnapshotStoreImpl implements 
SnapshotStore<Snapshot> {
             jobs.add(new StoredCronJob(config.newBuilder()));
           }
           snapshot.setCronJobs(jobs.build());
-          snapshot.setExperimentalTaskStore(useDbSnapshotForTaskStore);
         }
 
         @Override
         public void restoreFromSnapshot(MutableStoreProvider store, Snapshot 
snapshot) {
-          if (hasDbTaskStore(snapshot)) {
-            LOG.info("Deferring cron job restore to dbsnapshot");
-            return;
-          }
-
-          store.getCronJobStore().deleteJobs();
-
-          if (snapshot.isSetCronJobs()) {
+          if (snapshot.getCronJobsSize() > 0) {
+            store.getCronJobStore().deleteJobs();
             for (StoredCronJob job : snapshot.getCronJobs()) {
               store.getCronJobStore().saveAcceptedJob(
                   
thriftBackfill.backfillJobConfiguration(job.getJobConfiguration()));
@@ -332,11 +283,6 @@ public class SnapshotStoreImpl implements 
SnapshotStore<Snapshot> {
 
         @Override
         public void restoreFromSnapshot(MutableStoreProvider store, Snapshot 
snapshot) {
-          if (hasDbSnapshot(snapshot)) {
-            LOG.info("Deferring metadata restore to dbsnapshot");
-            return;
-          }
-
           if (snapshot.isSetSchedulerMetadata()
               && snapshot.getSchedulerMetadata().isSetFrameworkId()) {
             // No delete necessary here since this is a single value.
@@ -354,28 +300,20 @@ public class SnapshotStoreImpl implements 
SnapshotStore<Snapshot> {
 
         @Override
         public void saveToSnapshot(MutableStoreProvider store, Snapshot 
snapshot) {
-          if (hydrateSnapshotFields.contains(getName())) {
-            ImmutableSet.Builder<QuotaConfiguration> quotas = 
ImmutableSet.builder();
-            for (Map.Entry<String, IResourceAggregate> entry
-                : store.getQuotaStore().fetchQuotas().entrySet()) {
+          ImmutableSet.Builder<QuotaConfiguration> quotas = 
ImmutableSet.builder();
+          for (Map.Entry<String, IResourceAggregate> entry
+              : store.getQuotaStore().fetchQuotas().entrySet()) {
 
-              quotas.add(new QuotaConfiguration(entry.getKey(), 
entry.getValue().newBuilder()));
-            }
-
-            snapshot.setQuotaConfigurations(quotas.build());
+            quotas.add(new QuotaConfiguration(entry.getKey(), 
entry.getValue().newBuilder()));
           }
+
+          snapshot.setQuotaConfigurations(quotas.build());
         }
 
         @Override
         public void restoreFromSnapshot(MutableStoreProvider store, Snapshot 
snapshot) {
-          if (hasDbSnapshot(snapshot)) {
-            LOG.info("Deferring quota restore to dbsnapshot");
-            return;
-          }
-
-          store.getQuotaStore().deleteQuotas();
-
-          if (snapshot.isSetQuotaConfigurations()) {
+          if (snapshot.getQuotaConfigurationsSize() > 0) {
+            store.getQuotaStore().deleteQuotas();
             for (QuotaConfiguration quota : snapshot.getQuotaConfigurations()) 
{
               store.getQuotaStore()
                   .saveQuota(quota.getRole(), 
IResourceAggregate.build(quota.getQuota()));
@@ -391,22 +329,14 @@ public class SnapshotStoreImpl implements 
SnapshotStore<Snapshot> {
 
         @Override
         public void saveToSnapshot(MutableStoreProvider store, Snapshot 
snapshot) {
-          if (hydrateSnapshotFields.contains(getName())) {
-            
snapshot.setJobUpdateDetails(store.getJobUpdateStore().fetchAllJobUpdateDetails());
-          }
+          
snapshot.setJobUpdateDetails(store.getJobUpdateStore().fetchAllJobUpdateDetails());
         }
 
         @Override
         public void restoreFromSnapshot(MutableStoreProvider store, Snapshot 
snapshot) {
-          if (hasDbSnapshot(snapshot)) {
-            LOG.info("Deferring job update restore to dbsnapshot");
-            return;
-          }
-
-          JobUpdateStore.Mutable updateStore = store.getJobUpdateStore();
-          updateStore.deleteAllUpdatesAndEvents();
-
-          if (snapshot.isSetJobUpdateDetails()) {
+          if (snapshot.getJobUpdateDetailsSize() > 0) {
+            JobUpdateStore.Mutable updateStore = store.getJobUpdateStore();
+            updateStore.deleteAllUpdatesAndEvents();
             for (StoredJobUpdateDetails storedDetails : 
snapshot.getJobUpdateDetails()) {
               JobUpdateDetails details = storedDetails.getDetails();
               updateStore.saveJobUpdate(
@@ -437,55 +367,25 @@ public class SnapshotStoreImpl implements 
SnapshotStore<Snapshot> {
   private final BuildInfo buildInfo;
   private final Clock clock;
   private final Storage storage;
-  private final boolean useDbSnapshotForTaskStore;
-  private final Set<String> hydrateSnapshotFields;
-  private final MigrationManager migrationManager;
   private final ThriftBackfill thriftBackfill;
-  private final EnumBackfill enumBackfill;
-
-  /**
-   * Identifies if experimental task store is in use.
-   */
-  @Retention(RetentionPolicy.RUNTIME)
-  @Target({ ElementType.PARAMETER, ElementType.METHOD })
-  @Qualifier
-  public @interface ExperimentalTaskStore { }
-
-  /**
-   * Identifies a set of snapshot fields to be fully hydrated when creating 
the snapshot.
-   */
-  @Retention(RetentionPolicy.RUNTIME)
-  @Target({ ElementType.PARAMETER, ElementType.METHOD })
-  @Qualifier
-  public @interface HydrateSnapshotFields { }
 
   @Inject
   public SnapshotStoreImpl(
       BuildInfo buildInfo,
       Clock clock,
       @Volatile Storage storage,
-      @ExperimentalTaskStore boolean useDbSnapshotForTaskStore,
-      @HydrateSnapshotFields Set<String> hydrateSnapshotFields,
-      MigrationManager migrationManager,
-      ThriftBackfill thriftBackfill,
-      EnumBackfill enumBackfill) {
+      ThriftBackfill thriftBackfill) {
 
     this.buildInfo = requireNonNull(buildInfo);
     this.clock = requireNonNull(clock);
     this.storage = requireNonNull(storage);
-    this.useDbSnapshotForTaskStore = useDbSnapshotForTaskStore;
-    this.hydrateSnapshotFields = requireNonNull(hydrateSnapshotFields);
-    this.migrationManager = requireNonNull(migrationManager);
     this.thriftBackfill = requireNonNull(thriftBackfill);
-    this.enumBackfill = requireNonNull(enumBackfill);
   }
 
-  @Timed("snapshot_create")
-  @Override
-  public Snapshot createSnapshot() {
+  private Snapshot createSnapshot(Storage anyStorage) {
     // It's important to perform snapshot creation in a write lock to ensure 
all upstream callers
     // are correctly synchronized (e.g. during backup creation).
-    return storage.write(storeProvider -> {
+    return anyStorage.write(storeProvider -> {
       Snapshot snapshot = new Snapshot();
 
       // Capture timestamp to signify the beginning of a snapshot operation, 
apply after in case
@@ -505,6 +405,12 @@ public class SnapshotStoreImpl implements 
SnapshotStore<Snapshot> {
     });
   }
 
+  @Timed("snapshot_create")
+  @Override
+  public Snapshot createSnapshot() {
+    return createSnapshot(storage);
+  }
+
   @Timed("snapshot_apply")
   @Override
   public void applySnapshot(final Snapshot snapshot) {

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/storage/log/WriteAheadStorage.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/aurora/scheduler/storage/log/WriteAheadStorage.java 
b/src/main/java/org/apache/aurora/scheduler/storage/log/WriteAheadStorage.java
index 170f9ff..a5b58e8 100644
--- 
a/src/main/java/org/apache/aurora/scheduler/storage/log/WriteAheadStorage.java
+++ 
b/src/main/java/org/apache/aurora/scheduler/storage/log/WriteAheadStorage.java
@@ -358,12 +358,6 @@ class WriteAheadStorage implements
   }
 
   @Override
-  public <T> T getUnsafeStoreAccess() {
-    throw new UnsupportedOperationException(
-        "Unsupported since casual storage users should never be doing this.");
-  }
-
-  @Override
   public Optional<String> fetchFrameworkId() {
     return this.schedulerStore.fetchFrameworkId();
   }

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/storage/mem/InMemStoresModule.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/aurora/scheduler/storage/mem/InMemStoresModule.java 
b/src/main/java/org/apache/aurora/scheduler/storage/mem/InMemStoresModule.java
deleted file mode 100644
index 24296b6..0000000
--- 
a/src/main/java/org/apache/aurora/scheduler/storage/mem/InMemStoresModule.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * Licensed 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.aurora.scheduler.storage.mem;
-
-import javax.inject.Singleton;
-
-import com.google.inject.Key;
-import com.google.inject.PrivateModule;
-import com.google.inject.TypeLiteral;
-
-import org.apache.aurora.common.inject.Bindings.KeyFactory;
-import org.apache.aurora.common.quantity.Amount;
-import org.apache.aurora.common.quantity.Time;
-import org.apache.aurora.scheduler.storage.CronJobStore;
-import org.apache.aurora.scheduler.storage.TaskStore;
-import org.apache.aurora.scheduler.storage.db.DbModule;
-import org.apache.aurora.scheduler.storage.db.DbModule.Options;
-import org.apache.aurora.scheduler.storage.mem.MemTaskStore.SlowQueryThreshold;
-
-import static java.util.Objects.requireNonNull;
-
-/**
- * Binding module for in-memory stores.
- * <p>
- * NOTE: These stores are being phased out in favor of database-backed stores.
- */
-public final class InMemStoresModule extends PrivateModule {
-
-  private final Options options;
-  private final KeyFactory keyFactory;
-
-  public InMemStoresModule(DbModule.Options options, KeyFactory keyFactory) {
-    this.options = requireNonNull(options);
-    this.keyFactory = requireNonNull(keyFactory);
-  }
-
-  private <T> void bindStore(Class<T> binding, Class<? extends T> impl) {
-    bind(binding).to(impl);
-    bind(impl).in(Singleton.class);
-    Key<T> key = keyFactory.create(binding);
-    bind(key).to(impl);
-    expose(key);
-  }
-
-  @Override
-  protected void configure() {
-    bind(new TypeLiteral<Amount<Long, Time>>() { 
}).annotatedWith(SlowQueryThreshold.class)
-        .toInstance(options.slowQueryLogThreshold);
-    bindStore(TaskStore.Mutable.class, MemTaskStore.class);
-    expose(TaskStore.Mutable.class);
-    bindStore(CronJobStore.Mutable.class, MemCronJobStore.class);
-    expose(CronJobStore.Mutable.class);
-  }
-}

http://git-wip-us.apache.org/repos/asf/aurora/blob/f2755e1c/src/main/java/org/apache/aurora/scheduler/storage/mem/MemAttributeStore.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/aurora/scheduler/storage/mem/MemAttributeStore.java 
b/src/main/java/org/apache/aurora/scheduler/storage/mem/MemAttributeStore.java
new file mode 100644
index 0000000..483af19
--- /dev/null
+++ 
b/src/main/java/org/apache/aurora/scheduler/storage/mem/MemAttributeStore.java
@@ -0,0 +1,82 @@
+/**
+ * Licensed 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.aurora.scheduler.storage.mem;
+
+import java.util.Map;
+import java.util.Set;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+
+import org.apache.aurora.gen.Attribute;
+import org.apache.aurora.gen.HostAttributes;
+import org.apache.aurora.gen.MaintenanceMode;
+import org.apache.aurora.scheduler.storage.AttributeStore;
+import org.apache.aurora.scheduler.storage.entities.IHostAttributes;
+
+/**
+ * An in-memory attribute store.
+ */
+class MemAttributeStore implements AttributeStore.Mutable {
+  private final Map<String, IHostAttributes> hostAttributes = 
Maps.newConcurrentMap();
+
+  @Override
+  public void deleteHostAttributes() {
+    hostAttributes.clear();
+  }
+
+  @Override
+  public boolean saveHostAttributes(IHostAttributes attributes) {
+    Preconditions.checkArgument(
+        FluentIterable.from(attributes.getAttributes()).allMatch(a -> 
!a.getValues().isEmpty()));
+    Preconditions.checkArgument(attributes.isSetMode());
+
+    IHostAttributes previous = hostAttributes.put(
+        attributes.getHost(),
+        merge(attributes, 
Optional.fromNullable(hostAttributes.get(attributes.getHost()))));
+    return attributes.equals(previous);
+  }
+
+  private IHostAttributes merge(IHostAttributes newAttributes, 
Optional<IHostAttributes> previous) {
+    HostAttributes attributes = newAttributes.newBuilder();
+    if (!attributes.isSetMode()) {
+      // If the newly-saved value does not explicitly set the mode, use the 
previous value
+      // or the default.
+      MaintenanceMode mode;
+      if (previous.isPresent() && previous.get().isSetMode()) {
+        mode = previous.get().getMode();
+      } else {
+        mode = MaintenanceMode.NONE;
+      }
+      attributes.setMode(mode);
+    }
+    if (!attributes.isSetAttributes()) {
+      attributes.setAttributes(ImmutableSet.<Attribute>of());
+    }
+    return IHostAttributes.build(attributes);
+  }
+
+  @Override
+  public Optional<IHostAttributes> getHostAttributes(String host) {
+    return Optional.fromNullable(hostAttributes.get(host));
+  }
+
+  @Override
+  public Set<IHostAttributes> getHostAttributes() {
+    return ImmutableSet.copyOf(hostAttributes.values());
+  }
+}

Reply via email to