Repository: aurora Updated Branches: refs/heads/master 9dd80a439 -> eec985d94
Move all command line argument declarations to modules or SchedulerMain. Reviewed at https://reviews.apache.org/r/41711/ Project: http://git-wip-us.apache.org/repos/asf/aurora/repo Commit: http://git-wip-us.apache.org/repos/asf/aurora/commit/eec985d9 Tree: http://git-wip-us.apache.org/repos/asf/aurora/tree/eec985d9 Diff: http://git-wip-us.apache.org/repos/asf/aurora/diff/eec985d9 Branch: refs/heads/master Commit: eec985d948f02f46637d87cd4d212eb2a70ef8d0 Parents: 9dd80a4 Author: Bill Farner <[email protected]> Authored: Mon Dec 28 11:58:16 2015 -0800 Committer: Bill Farner <[email protected]> Committed: Mon Dec 28 11:58:16 2015 -0800 ---------------------------------------------------------------------- .../aurora/common/logging/RootLogConfig.java | 43 ------------- .../apache/aurora/scheduler/app/AppModule.java | 42 +++++++++++++ .../aurora/scheduler/app/SchedulerMain.java | 35 ++++++++++- .../apache/aurora/scheduler/base/JobKeys.java | 7 +-- .../aurora/scheduler/base/TaskTestUtil.java | 4 ++ .../scheduler/base/UserProvidedStrings.java | 44 ++++++++++++++ .../configuration/ConfigurationManager.java | 63 ++++++-------------- .../configuration/SanitizedConfiguration.java | 7 ++- .../aurora/scheduler/cron/SanitizedCronJob.java | 10 ++-- .../scheduler/cron/quartz/AuroraCronJob.java | 5 +- .../scheduler/cron/quartz/CronLifecycle.java | 11 +++- .../storage/mem/InMemStoresModule.java | 13 ++++ .../scheduler/storage/mem/MemTaskStore.java | 26 +++++--- .../scheduler/thrift/ReadOnlySchedulerImpl.java | 5 ++ .../thrift/SchedulerThriftInterface.java | 44 +++++--------- .../aurora/scheduler/thrift/Thresholds.java | 45 ++++++++++++++ .../configuration/ConfigurationManagerTest.java | 14 ++++- .../cron/quartz/AuroraCronJobTest.java | 2 + .../aurora/scheduler/cron/quartz/CronIT.java | 6 +- .../cron/quartz/CronJobManagerImplTest.java | 2 + .../scheduler/cron/quartz/QuartzTestUtil.java | 3 + .../thrift/ReadOnlySchedulerImplTest.java | 5 +- .../thrift/SchedulerThriftInterfaceTest.java | 55 +++++++++-------- .../aurora/scheduler/thrift/ThriftIT.java | 4 ++ 24 files changed, 328 insertions(+), 167 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/aurora/blob/eec985d9/commons/src/main/java/org/apache/aurora/common/logging/RootLogConfig.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/aurora/common/logging/RootLogConfig.java b/commons/src/main/java/org/apache/aurora/common/logging/RootLogConfig.java index 7f010fd..26dd0aa 100644 --- a/commons/src/main/java/org/apache/aurora/common/logging/RootLogConfig.java +++ b/commons/src/main/java/org/apache/aurora/common/logging/RootLogConfig.java @@ -13,7 +13,6 @@ */ package org.apache.aurora.common.logging; -import java.util.HashMap; import java.util.Map; import java.util.logging.ConsoleHandler; import java.util.logging.Handler; @@ -25,9 +24,6 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; -import org.apache.aurora.common.args.Arg; -import org.apache.aurora.common.args.CmdLine; - /** * A configuration class for the root java.util.logging Logger. * @@ -58,30 +54,6 @@ public class RootLogConfig { } } - @CmdLine(name = "logtostderr", help = "Log messages to stderr instead of logfiles.") - private static Arg<Boolean> LOGTOSTDERR = Arg.create(false); - - @CmdLine(name = "alsologtostderr", - help = "Log messages to stderr, in addition to log files. Ignored when --logtostderr") - private static Arg<Boolean> ALSOLOGTOSTDERR = Arg.create(false); - - @CmdLine(name = "vlog", - help = "The value is one of the constants in java.util.logging.Level. " - + "Shows all messages with level equal or higher " - + "than the value of this flag.") - private static Arg<LogLevel> VLOG = Arg.create(LogLevel.INFO); - - @CmdLine(name = "vmodule", - help = "Per-class verbose level. The argument has to contain a comma-separated list " - + "of <class_name>=<log_level>. <class_name> is the full-qualified name of a " - + "class, <log_level> is one of the constants in java.util.logging.Level. " - + "<log_level> overrides any value given by --vlog.") - private static Arg<Map<Class<?>, LogLevel>> VMODULE = - Arg.<Map<Class<?>, LogLevel>>create(new HashMap<Class<?>, LogLevel>()); - - @CmdLine(name = "use_glog_formatter", help = "True to use the glog formatter exclusively.") - private static Arg<Boolean> USE_GLOG_FORMATTER = Arg.create(true); - /** * Represents a logging configuration for java.util.logging. */ @@ -246,21 +218,6 @@ public class RootLogConfig { return new Builder(); } - /** - * Creates a logging configuration using flags - * - * @return The logging configuration specified via command line flags. - */ - public static Configuration configurationFromFlags() { - return builder() - .logToStderr(LOGTOSTDERR.get()) - .alsoLogToStderr(ALSOLOGTOSTDERR.get()) - .useGLogFormatter(USE_GLOG_FORMATTER.get()) - .vlog(VLOG.get()) - .vmodule(VMODULE.get()) - .build(); - } - private static void configure(Configuration configuration) { // Edit the properties of the root logger. Logger rootLogger = Logger.getLogger(configuration.rootLoggerName); http://git-wip-us.apache.org/repos/asf/aurora/blob/eec985d9/src/main/java/org/apache/aurora/scheduler/app/AppModule.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/app/AppModule.java b/src/main/java/org/apache/aurora/scheduler/app/AppModule.java index 967e10d..a25fa41 100644 --- a/src/main/java/org/apache/aurora/scheduler/app/AppModule.java +++ b/src/main/java/org/apache/aurora/scheduler/app/AppModule.java @@ -13,18 +13,27 @@ */ package org.apache.aurora.scheduler.app; +import java.util.Set; + import javax.inject.Singleton; +import com.google.common.collect.ImmutableSet; import com.google.inject.AbstractModule; import org.apache.aurora.GuiceUtils; +import org.apache.aurora.common.args.Arg; +import org.apache.aurora.common.args.CmdLine; +import org.apache.aurora.common.args.constraints.Positive; import org.apache.aurora.common.inject.TimedInterceptor; import org.apache.aurora.common.stats.Stats; import org.apache.aurora.common.stats.StatsProvider; import org.apache.aurora.common.util.Clock; +import org.apache.aurora.gen.Container; +import org.apache.aurora.gen.Container._Fields; import org.apache.aurora.scheduler.SchedulerModule; import org.apache.aurora.scheduler.SchedulerServicesModule; import org.apache.aurora.scheduler.async.AsyncModule; +import org.apache.aurora.scheduler.configuration.ConfigurationManager; import org.apache.aurora.scheduler.events.PubsubEventModule; import org.apache.aurora.scheduler.filter.SchedulingFilterImpl; import org.apache.aurora.scheduler.http.JettyServerModule; @@ -39,6 +48,7 @@ import org.apache.aurora.scheduler.scheduling.SchedulingModule; import org.apache.aurora.scheduler.sla.SlaModule; import org.apache.aurora.scheduler.state.StateModule; import org.apache.aurora.scheduler.stats.AsyncStatsModule; +import org.apache.aurora.scheduler.thrift.Thresholds; import org.apache.aurora.scheduler.updater.UpdaterModule; import org.apache.mesos.Scheduler; @@ -46,8 +56,40 @@ import org.apache.mesos.Scheduler; * Binding module for the aurora scheduler application. */ public class AppModule extends AbstractModule { + private static final int DEFAULT_MAX_TASKS_PER_JOB = 4000; + + @Positive + @CmdLine(name = "max_tasks_per_job", help = "Maximum number of allowed tasks in a single job.") + public static final Arg<Integer> MAX_TASKS_PER_JOB = Arg.create(DEFAULT_MAX_TASKS_PER_JOB); + + private static final int DEFAULT_MAX_UPDATE_INSTANCE_FAILURES = + DEFAULT_MAX_TASKS_PER_JOB * 5; + + @Positive + @CmdLine(name = "max_update_instance_failures", help = "Upper limit on the number of " + + "failures allowed during a job update. This helps cap potentially unbounded entries into " + + "storage.") + public static final Arg<Integer> MAX_UPDATE_INSTANCE_FAILURES = Arg.create( + DEFAULT_MAX_UPDATE_INSTANCE_FAILURES); + + @CmdLine(name = "allowed_container_types", + help = "Container types that are allowed to be used by jobs.") + private static final Arg<Set<_Fields>> ALLOWED_CONTAINER_TYPES = + Arg.create(ImmutableSet.of(Container._Fields.MESOS)); + + @CmdLine(name = "allow_docker_parameters", + help = "Allow to pass docker container parameters in the job.") + private static final Arg<Boolean> ENABLE_DOCKER_PARAMETERS = Arg.create(false); + @Override protected void configure() { + bind(ConfigurationManager.class).toInstance( + new ConfigurationManager( + ImmutableSet.copyOf(ALLOWED_CONTAINER_TYPES.get()), + ENABLE_DOCKER_PARAMETERS.get())); + bind(Thresholds.class) + .toInstance(new Thresholds(MAX_TASKS_PER_JOB.get(), MAX_UPDATE_INSTANCE_FAILURES.get())); + // Enable intercepted method timings and context classloader repair. TimedInterceptor.bind(binder()); GuiceUtils.bindJNIContextClassLoader(binder(), Scheduler.class); http://git-wip-us.apache.org/repos/asf/aurora/blob/eec985d9/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 e8bf6bc..3822d6e 100644 --- a/src/main/java/org/apache/aurora/scheduler/app/SchedulerMain.java +++ b/src/main/java/org/apache/aurora/scheduler/app/SchedulerMain.java @@ -15,7 +15,9 @@ package org.apache.aurora.scheduler.app; import java.net.InetSocketAddress; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicLong; @@ -45,6 +47,7 @@ import org.apache.aurora.common.args.constraints.NotEmpty; import org.apache.aurora.common.args.constraints.NotNull; import org.apache.aurora.common.inject.Bindings; import org.apache.aurora.common.logging.RootLogConfig; +import org.apache.aurora.common.logging.RootLogConfig.LogLevel; import org.apache.aurora.common.stats.Stats; import org.apache.aurora.common.zookeeper.Group; import org.apache.aurora.common.zookeeper.SingletonService; @@ -77,6 +80,30 @@ import static org.apache.aurora.common.logging.RootLogConfig.Configuration; public class SchedulerMain { private static final Logger LOG = Logger.getLogger(SchedulerMain.class.getName()); + @CmdLine(name = "logtostderr", help = "Log messages to stderr instead of logfiles.") + private static final Arg<Boolean> LOGTOSTDERR = Arg.create(false); + + @CmdLine(name = "alsologtostderr", + help = "Log messages to stderr, in addition to log files. Ignored when --logtostderr") + private static final Arg<Boolean> ALSOLOGTOSTDERR = Arg.create(false); + + @CmdLine(name = "vlog", + help = "The value is one of the constants in java.util.logging.Level. " + + "Shows all messages with level equal or higher " + + "than the value of this flag.") + private static final Arg<LogLevel> VLOG = Arg.create(LogLevel.INFO); + + @CmdLine(name = "vmodule", + help = "Per-class verbose level. The argument has to contain a comma-separated list " + + "of <class_name>=<log_level>. <class_name> is the full-qualified name of a " + + "class, <log_level> is one of the constants in java.util.logging.Level. " + + "<log_level> overrides any value given by --vlog.") + private static final Arg<Map<Class<?>, LogLevel>> VMODULE = + Arg.<Map<Class<?>, LogLevel>>create(new HashMap<>()); + + @CmdLine(name = "use_glog_formatter", help = "True to use the glog formatter exclusively.") + private static final Arg<Boolean> USE_GLOG_FORMATTER = Arg.create(true); + @NotNull @CmdLine(name = "cluster_name", help = "Name to identify the cluster being served.") private static final Arg<String> CLUSTER_NAME = Arg.create(); @@ -119,7 +146,13 @@ public class SchedulerMain { startupServices.awaitHealthy(); // Setup log4j to match our jul glog config in order to pick up zookeeper logging. - Configuration logConfiguration = RootLogConfig.configurationFromFlags(); + Configuration logConfiguration = RootLogConfig.builder() + .logToStderr(LOGTOSTDERR.get()) + .alsoLogToStderr(ALSOLOGTOSTDERR.get()) + .useGLogFormatter(USE_GLOG_FORMATTER.get()) + .vlog(VLOG.get()) + .vmodule(VMODULE.get()) + .build(); logConfiguration.apply(); Log4jConfigurator.configureConsole(logConfiguration); http://git-wip-us.apache.org/repos/asf/aurora/blob/eec985d9/src/main/java/org/apache/aurora/scheduler/base/JobKeys.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/base/JobKeys.java b/src/main/java/org/apache/aurora/scheduler/base/JobKeys.java index 0ffec91..8f5bf58 100644 --- a/src/main/java/org/apache/aurora/scheduler/base/JobKeys.java +++ b/src/main/java/org/apache/aurora/scheduler/base/JobKeys.java @@ -24,7 +24,6 @@ import com.google.common.collect.ImmutableSet; import org.apache.aurora.gen.JobKey; import org.apache.aurora.gen.TaskQuery; -import org.apache.aurora.scheduler.configuration.ConfigurationManager; import org.apache.aurora.scheduler.storage.entities.IJobConfiguration; import org.apache.aurora.scheduler.storage.entities.IJobKey; @@ -50,9 +49,9 @@ public final class JobKeys { */ public static boolean isValid(@Nullable IJobKey jobKey) { return jobKey != null - && ConfigurationManager.isGoodIdentifier(jobKey.getRole()) - && ConfigurationManager.isGoodIdentifier(jobKey.getEnvironment()) - && ConfigurationManager.isGoodIdentifier(jobKey.getName()); + && UserProvidedStrings.isGoodIdentifier(jobKey.getRole()) + && UserProvidedStrings.isGoodIdentifier(jobKey.getEnvironment()) + && UserProvidedStrings.isGoodIdentifier(jobKey.getName()); } /** http://git-wip-us.apache.org/repos/asf/aurora/blob/eec985d9/src/main/java/org/apache/aurora/scheduler/base/TaskTestUtil.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/base/TaskTestUtil.java b/src/main/java/org/apache/aurora/scheduler/base/TaskTestUtil.java index 2cdb2f2..7c249b3 100644 --- a/src/main/java/org/apache/aurora/scheduler/base/TaskTestUtil.java +++ b/src/main/java/org/apache/aurora/scheduler/base/TaskTestUtil.java @@ -20,6 +20,7 @@ import com.google.common.collect.ImmutableSet; import org.apache.aurora.gen.AssignedTask; import org.apache.aurora.gen.Constraint; import org.apache.aurora.gen.Container; +import org.apache.aurora.gen.Container._Fields; import org.apache.aurora.gen.DockerContainer; import org.apache.aurora.gen.DockerParameter; import org.apache.aurora.gen.ExecutorConfig; @@ -33,6 +34,7 @@ import org.apache.aurora.gen.TaskConstraint; import org.apache.aurora.gen.TaskEvent; import org.apache.aurora.gen.ValueConstraint; import org.apache.aurora.scheduler.TierInfo; +import org.apache.aurora.scheduler.configuration.ConfigurationManager; import org.apache.aurora.scheduler.storage.entities.IJobKey; import org.apache.aurora.scheduler.storage.entities.IScheduledTask; import org.apache.aurora.scheduler.storage.entities.ITaskConfig; @@ -47,6 +49,8 @@ public final class TaskTestUtil { public static final IJobKey JOB = JobKeys.from("role", "env", "job"); public static final TierInfo REVOCABLE_TIER = new TierInfo(true); + public static final ConfigurationManager CONFIGURATION_MANAGER = + new ConfigurationManager(ImmutableSet.of(_Fields.MESOS), false); private TaskTestUtil() { // Utility class. http://git-wip-us.apache.org/repos/asf/aurora/blob/eec985d9/src/main/java/org/apache/aurora/scheduler/base/UserProvidedStrings.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/base/UserProvidedStrings.java b/src/main/java/org/apache/aurora/scheduler/base/UserProvidedStrings.java new file mode 100644 index 0000000..80fc790 --- /dev/null +++ b/src/main/java/org/apache/aurora/scheduler/base/UserProvidedStrings.java @@ -0,0 +1,44 @@ +/** + * 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.base; + +import java.util.regex.Pattern; + +import javax.annotation.Nullable; + +import static org.apache.aurora.gen.apiConstants.GOOD_IDENTIFIER_PATTERN_JVM; + +/** + * Utility class for validation of strings provided by end-users. + */ +public final class UserProvidedStrings { + private static final Pattern GOOD_IDENTIFIER = Pattern.compile(GOOD_IDENTIFIER_PATTERN_JVM); + private static final int MAX_IDENTIFIER_LENGTH = 255; + + private UserProvidedStrings() { + // Utility class. + } + + /** + * Verifies that an identifier is an acceptable name component. + * + * @param identifier Identifier to check. + * @return false if the identifier is null or invalid. + */ + public static boolean isGoodIdentifier(@Nullable String identifier) { + return identifier != null + && GOOD_IDENTIFIER.matcher(identifier).matches() + && identifier.length() <= MAX_IDENTIFIER_LENGTH; + } +} http://git-wip-us.apache.org/repos/asf/aurora/blob/eec985d9/src/main/java/org/apache/aurora/scheduler/configuration/ConfigurationManager.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/configuration/ConfigurationManager.java b/src/main/java/org/apache/aurora/scheduler/configuration/ConfigurationManager.java index 3a2056a..6a5f9c5 100644 --- a/src/main/java/org/apache/aurora/scheduler/configuration/ConfigurationManager.java +++ b/src/main/java/org/apache/aurora/scheduler/configuration/ConfigurationManager.java @@ -13,9 +13,7 @@ */ package org.apache.aurora.scheduler.configuration; -import java.util.List; import java.util.Objects; -import java.util.regex.Pattern; import javax.annotation.Nullable; @@ -27,14 +25,13 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; -import org.apache.aurora.common.args.Arg; -import org.apache.aurora.common.args.CmdLine; import org.apache.aurora.gen.Container; import org.apache.aurora.gen.JobConfiguration; import org.apache.aurora.gen.TaskConfig; import org.apache.aurora.gen.TaskConfig._Fields; import org.apache.aurora.gen.TaskConstraint; import org.apache.aurora.scheduler.base.JobKeys; +import org.apache.aurora.scheduler.base.UserProvidedStrings; import org.apache.aurora.scheduler.storage.entities.IConstraint; import org.apache.aurora.scheduler.storage.entities.IContainer; import org.apache.aurora.scheduler.storage.entities.IIdentity; @@ -43,31 +40,16 @@ import org.apache.aurora.scheduler.storage.entities.ITaskConfig; import org.apache.aurora.scheduler.storage.entities.ITaskConstraint; import org.apache.aurora.scheduler.storage.entities.IValueConstraint; -import static org.apache.aurora.gen.apiConstants.GOOD_IDENTIFIER_PATTERN_JVM; - /** * Manages translation from a string-mapped configuration to a concrete configuration type, and * defaults for optional values. * * TODO(William Farner): Add input validation to all fields (strings not empty, positive ints, etc). */ -public final class ConfigurationManager { - - @CmdLine(name = "allowed_container_types", - help = "Container types that are allowed to be used by jobs.") - private static final Arg<List<Container._Fields>> ALLOWED_CONTAINER_TYPES = - Arg.create(ImmutableList.of(Container._Fields.MESOS)); - - @CmdLine(name = "allow_docker_parameters", - help = "Allow to pass docker container parameters in the job.") - private static final Arg<Boolean> ENABLE_DOCKER_PARAMETERS = Arg.create(false); +public class ConfigurationManager { public static final String DEDICATED_ATTRIBUTE = "dedicated"; - private static final Pattern GOOD_IDENTIFIER = Pattern.compile(GOOD_IDENTIFIER_PATTERN_JVM); - - private static final int MAX_IDENTIFIER_LENGTH = 255; - private interface Validator<T> { void validate(T value) throws TaskDescriptionException; } @@ -114,20 +96,15 @@ public final class ConfigurationManager { new RequiredFieldValidator<>(_Fields.RAM_MB, new GreaterThan(0.0, "ram_mb")), new RequiredFieldValidator<>(_Fields.DISK_MB, new GreaterThan(0.0, "disk_mb"))); - private ConfigurationManager() { - // Utility class. - } + private final ImmutableSet<Container._Fields> allowedContainerTypes; + private final boolean allowDockerParameters; - /** - * Verifies that an identifier is an acceptable name component. - * - * @param identifier Identifier to check. - * @return false if the identifier is null or invalid. - */ - public static boolean isGoodIdentifier(@Nullable String identifier) { - return identifier != null - && GOOD_IDENTIFIER.matcher(identifier).matches() - && identifier.length() <= MAX_IDENTIFIER_LENGTH; + public ConfigurationManager( + ImmutableSet<Container._Fields> allowedContainerTypes, + boolean allowDockerParameters) { + + this.allowedContainerTypes = Objects.requireNonNull(allowedContainerTypes); + this.allowDockerParameters = allowDockerParameters; } private static void requireNonNull(Object value, String error) throws TaskDescriptionException { @@ -141,12 +118,12 @@ public final class ConfigurationManager { requireNonNull(jobOwner.getRole(), "No job role specified!"); requireNonNull(jobOwner.getUser(), "No job user specified!"); - if (!isGoodIdentifier(jobOwner.getRole())) { + if (!UserProvidedStrings.isGoodIdentifier(jobOwner.getRole())) { throw new TaskDescriptionException( "Job role contains illegal characters: " + jobOwner.getRole()); } - if (!isGoodIdentifier(jobOwner.getUser())) { + if (!UserProvidedStrings.isGoodIdentifier(jobOwner.getUser())) { throw new TaskDescriptionException( "Job user contains illegal characters: " + jobOwner.getUser()); } @@ -178,7 +155,7 @@ public final class ConfigurationManager { * @return A deep copy of {@code job} that has been populated. * @throws TaskDescriptionException If the job configuration is invalid. */ - public static IJobConfiguration validateAndPopulate(IJobConfiguration job) + public IJobConfiguration validateAndPopulate(IJobConfiguration job) throws TaskDescriptionException { Objects.requireNonNull(job); @@ -227,9 +204,7 @@ public final class ConfigurationManager { * @return A reference to the modified {@code config} (for chaining). * @throws TaskDescriptionException If the task is invalid. */ - public static ITaskConfig validateAndPopulate(ITaskConfig config) - throws TaskDescriptionException { - + public ITaskConfig validateAndPopulate(ITaskConfig config) throws TaskDescriptionException { TaskConfig builder = config.newBuilder(); if (!builder.isSetRequestedPorts()) { @@ -238,17 +213,17 @@ public final class ConfigurationManager { maybeFillLinks(builder); - if (!isGoodIdentifier(config.getJobName())) { + if (!UserProvidedStrings.isGoodIdentifier(config.getJobName())) { throw new TaskDescriptionException( "Job name contains illegal characters: " + config.getJobName()); } - if (!isGoodIdentifier(config.getEnvironment())) { + if (!UserProvidedStrings.isGoodIdentifier(config.getEnvironment())) { throw new TaskDescriptionException( "Environment contains illegal characters: " + config.getEnvironment()); } - if (config.isSetTier() && !isGoodIdentifier(config.getTier())) { + if (config.isSetTier() && !UserProvidedStrings.isGoodIdentifier(config.getTier())) { throw new TaskDescriptionException("Tier contains illegal characters: " + config.getTier()); } @@ -311,7 +286,7 @@ public final class ConfigurationManager { } if (containerConfig.getDocker().isSetParameters() && !containerConfig.getDocker().getParameters().isEmpty() - && !ENABLE_DOCKER_PARAMETERS.get()) { + && !allowDockerParameters) { throw new TaskDescriptionException("Docker parameters not allowed."); } } @@ -322,7 +297,7 @@ public final class ConfigurationManager { if (!containerType.isPresent()) { throw new TaskDescriptionException("A job must have a container type."); } - if (!ALLOWED_CONTAINER_TYPES.get().contains(containerType.get())) { + if (!allowedContainerTypes.contains(containerType.get())) { throw new TaskDescriptionException( "The container type " + containerType.get().toString() + " is not allowed"); } http://git-wip-us.apache.org/repos/asf/aurora/blob/eec985d9/src/main/java/org/apache/aurora/scheduler/configuration/SanitizedConfiguration.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/configuration/SanitizedConfiguration.java b/src/main/java/org/apache/aurora/scheduler/configuration/SanitizedConfiguration.java index 05981b9..264cb7c 100644 --- a/src/main/java/org/apache/aurora/scheduler/configuration/SanitizedConfiguration.java +++ b/src/main/java/org/apache/aurora/scheduler/configuration/SanitizedConfiguration.java @@ -53,10 +53,11 @@ public final class SanitizedConfiguration { * @return A wrapper containing the sanitized configuration. * @throws TaskDescriptionException If the configuration is invalid. */ - public static SanitizedConfiguration fromUnsanitized(IJobConfiguration unsanitized) - throws TaskDescriptionException { + public static SanitizedConfiguration fromUnsanitized( + ConfigurationManager configurationManager, + IJobConfiguration unsanitized) throws TaskDescriptionException { - return new SanitizedConfiguration(ConfigurationManager.validateAndPopulate(unsanitized)); + return new SanitizedConfiguration(configurationManager.validateAndPopulate(unsanitized)); } public IJobConfiguration getJobConfig() { http://git-wip-us.apache.org/repos/asf/aurora/blob/eec985d9/src/main/java/org/apache/aurora/scheduler/cron/SanitizedCronJob.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/cron/SanitizedCronJob.java b/src/main/java/org/apache/aurora/scheduler/cron/SanitizedCronJob.java index dd8c9cd..87970f6 100644 --- a/src/main/java/org/apache/aurora/scheduler/cron/SanitizedCronJob.java +++ b/src/main/java/org/apache/aurora/scheduler/cron/SanitizedCronJob.java @@ -39,10 +39,10 @@ public final class SanitizedCronJob { private final SanitizedConfiguration config; private final CrontabEntry crontabEntry; - private SanitizedCronJob(IJobConfiguration unsanitized) + private SanitizedCronJob(ConfigurationManager configurationManager, IJobConfiguration unsanitized) throws CronException, ConfigurationManager.TaskDescriptionException { - this(SanitizedConfiguration.fromUnsanitized(unsanitized)); + this(SanitizedConfiguration.fromUnsanitized(configurationManager, unsanitized)); } private SanitizedCronJob(SanitizedConfiguration config) throws CronException { @@ -94,10 +94,12 @@ public final class SanitizedCronJob { * @throws ConfigurationManager.TaskDescriptionException If validation fails with a non * cron-specific error. */ - public static SanitizedCronJob fromUnsanitized(IJobConfiguration unsanitized) + public static SanitizedCronJob fromUnsanitized( + ConfigurationManager configurationManager, + IJobConfiguration unsanitized) throws CronException, ConfigurationManager.TaskDescriptionException { - return new SanitizedCronJob(unsanitized); + return new SanitizedCronJob(configurationManager, unsanitized); } /** http://git-wip-us.apache.org/repos/asf/aurora/blob/eec985d9/src/main/java/org/apache/aurora/scheduler/cron/quartz/AuroraCronJob.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/cron/quartz/AuroraCronJob.java b/src/main/java/org/apache/aurora/scheduler/cron/quartz/AuroraCronJob.java index f355bc1..a33f63a 100644 --- a/src/main/java/org/apache/aurora/scheduler/cron/quartz/AuroraCronJob.java +++ b/src/main/java/org/apache/aurora/scheduler/cron/quartz/AuroraCronJob.java @@ -73,16 +73,19 @@ class AuroraCronJob implements Job { @VisibleForTesting static final Optional<String> KILL_AUDIT_MESSAGE = Optional.of("Killed by cronScheduler"); + private final ConfigurationManager configurationManager; private final Storage storage; private final StateManager stateManager; private final BackoffHelper delayedStartBackoff; @Inject AuroraCronJob( + ConfigurationManager configurationManager, Config config, Storage storage, StateManager stateManager) { + this.configurationManager = requireNonNull(configurationManager); this.storage = requireNonNull(storage); this.stateManager = requireNonNull(stateManager); this.delayedStartBackoff = requireNonNull(config.getDelayedStartBackoff()); @@ -126,7 +129,7 @@ class AuroraCronJob implements Job { SanitizedCronJob cronJob; try { - cronJob = SanitizedCronJob.fromUnsanitized(config.get()); + cronJob = SanitizedCronJob.fromUnsanitized(configurationManager, config.get()); } catch (ConfigurationManager.TaskDescriptionException | CronException e) { LOG.warning(String.format( "Invalid cron job for %s in storage - failed to parse with %s", key, e)); http://git-wip-us.apache.org/repos/asf/aurora/blob/eec985d9/src/main/java/org/apache/aurora/scheduler/cron/quartz/CronLifecycle.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/cron/quartz/CronLifecycle.java b/src/main/java/org/apache/aurora/scheduler/cron/quartz/CronLifecycle.java index 527197c..dba47eb 100644 --- a/src/main/java/org/apache/aurora/scheduler/cron/quartz/CronLifecycle.java +++ b/src/main/java/org/apache/aurora/scheduler/cron/quartz/CronLifecycle.java @@ -43,12 +43,19 @@ class CronLifecycle extends AbstractIdleService { private static final AtomicInteger LOADED_FLAG = Stats.exportInt("cron_jobs_loaded"); private static final AtomicLong LAUNCH_FAILURES = Stats.exportLong("cron_job_launch_failures"); + private final ConfigurationManager configurationManager; private final Scheduler scheduler; private final CronJobManagerImpl cronJobManager; private final Storage storage; @Inject - CronLifecycle(Scheduler scheduler, CronJobManagerImpl cronJobManager, Storage storage) { + CronLifecycle( + ConfigurationManager configurationManager, + Scheduler scheduler, + CronJobManagerImpl cronJobManager, + Storage storage) { + + this.configurationManager = requireNonNull(configurationManager); this.scheduler = requireNonNull(scheduler); this.cronJobManager = requireNonNull(cronJobManager); this.storage = requireNonNull(storage); @@ -62,7 +69,7 @@ class CronLifecycle extends AbstractIdleService { for (IJobConfiguration job : Storage.Util.fetchCronJobs(storage)) { try { - SanitizedCronJob cronJob = SanitizedCronJob.fromUnsanitized(job); + SanitizedCronJob cronJob = SanitizedCronJob.fromUnsanitized(configurationManager, job); cronJobManager.scheduleJob( cronJob.getCrontabEntry(), cronJob.getSanitizedConfig().getJobConfig().getKey()); http://git-wip-us.apache.org/repos/asf/aurora/blob/eec985d9/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 index f964853..1b491f9 100644 --- a/src/main/java/org/apache/aurora/scheduler/storage/mem/InMemStoresModule.java +++ b/src/main/java/org/apache/aurora/scheduler/storage/mem/InMemStoresModule.java @@ -17,10 +17,16 @@ import javax.inject.Singleton; import com.google.inject.Key; import com.google.inject.PrivateModule; +import com.google.inject.TypeLiteral; +import org.apache.aurora.common.args.Arg; +import org.apache.aurora.common.args.CmdLine; 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.mem.MemTaskStore.SlowQueryThreshold; import static java.util.Objects.requireNonNull; @@ -30,6 +36,11 @@ import static java.util.Objects.requireNonNull; * NOTE: These stores are being phased out in favor of database-backed stores. */ public final class InMemStoresModule extends PrivateModule { + @CmdLine(name = "slow_query_log_threshold", + help = "Log all queries that take at least this long to execute.") + private static final Arg<Amount<Long, Time>> SLOW_QUERY_LOG_THRESHOLD = + Arg.create(Amount.of(25L, Time.MILLISECONDS)); + private final KeyFactory keyFactory; public InMemStoresModule(KeyFactory keyFactory) { @@ -46,6 +57,8 @@ public final class InMemStoresModule extends PrivateModule { @Override protected void configure() { + bind(new TypeLiteral<Amount<Long, Time>>() { }).annotatedWith(SlowQueryThreshold.class) + .toInstance(SLOW_QUERY_LOG_THRESHOLD.get()); bindStore(TaskStore.Mutable.class, MemTaskStore.class); expose(TaskStore.Mutable.class); bindStore(CronJobStore.Mutable.class, MemCronJobStore.class); http://git-wip-us.apache.org/repos/asf/aurora/blob/eec985d9/src/main/java/org/apache/aurora/scheduler/storage/mem/MemTaskStore.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/storage/mem/MemTaskStore.java b/src/main/java/org/apache/aurora/scheduler/storage/mem/MemTaskStore.java index 01448ae..93f6efb 100644 --- a/src/main/java/org/apache/aurora/scheduler/storage/mem/MemTaskStore.java +++ b/src/main/java/org/apache/aurora/scheduler/storage/mem/MemTaskStore.java @@ -13,6 +13,10 @@ */ package org.apache.aurora.scheduler.storage.mem; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; import java.util.List; import java.util.Map; import java.util.Set; @@ -21,6 +25,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.inject.Inject; +import javax.inject.Qualifier; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; @@ -39,8 +44,6 @@ import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; -import org.apache.aurora.common.args.Arg; -import org.apache.aurora.common.args.CmdLine; import org.apache.aurora.common.base.MorePreconditions; import org.apache.aurora.common.inject.TimedInterceptor.Timed; import org.apache.aurora.common.quantity.Amount; @@ -65,12 +68,15 @@ class MemTaskStore implements TaskStore.Mutable { private static final Logger LOG = Logger.getLogger(MemTaskStore.class.getName()); - @CmdLine(name = "slow_query_log_threshold", - help = "Log all queries that take at least this long to execute.") - private static final Arg<Amount<Long, Time>> SLOW_QUERY_LOG_THRESHOLD = - Arg.create(Amount.of(25L, Time.MILLISECONDS)); + /** + * When true, enable snapshot deflation. + */ + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.METHOD, ElementType.PARAMETER}) + @Qualifier + public @interface SlowQueryThreshold { } - private final long slowQueryThresholdNanos = SLOW_QUERY_LOG_THRESHOLD.get().as(Time.NANOSECONDS); + private final long slowQueryThresholdNanos; private static final Function<Query.Builder, Optional<Set<IJobKey>>> QUERY_TO_JOB_KEY = JobKeys::from; @@ -98,7 +104,10 @@ class MemTaskStore implements TaskStore.Mutable { private final AtomicLong taskQueriesAll; @Inject - MemTaskStore(StatsProvider statsProvider) { + MemTaskStore( + StatsProvider statsProvider, + @SlowQueryThreshold Amount<Long, Time> slowQueryThreshold) { + secondaryIndices = ImmutableList.of( new SecondaryIndex<>( Tasks::getJob, @@ -110,6 +119,7 @@ class MemTaskStore implements TaskStore.Mutable { QUERY_TO_SLAVE_HOST, statsProvider, "host")); + slowQueryThresholdNanos = slowQueryThreshold.as(Time.NANOSECONDS); taskQueriesById = statsProvider.makeCounter("task_queries_by_id"); taskQueriesAll = statsProvider.makeCounter("task_queries_all"); } http://git-wip-us.apache.org/repos/asf/aurora/blob/eec985d9/src/main/java/org/apache/aurora/scheduler/thrift/ReadOnlySchedulerImpl.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/thrift/ReadOnlySchedulerImpl.java b/src/main/java/org/apache/aurora/scheduler/thrift/ReadOnlySchedulerImpl.java index 7235902..90cddd0 100644 --- a/src/main/java/org/apache/aurora/scheduler/thrift/ReadOnlySchedulerImpl.java +++ b/src/main/java/org/apache/aurora/scheduler/thrift/ReadOnlySchedulerImpl.java @@ -75,6 +75,7 @@ import org.apache.aurora.scheduler.base.Jobs; import org.apache.aurora.scheduler.base.Query; import org.apache.aurora.scheduler.base.TaskGroupKey; import org.apache.aurora.scheduler.base.Tasks; +import org.apache.aurora.scheduler.configuration.ConfigurationManager; import org.apache.aurora.scheduler.configuration.ConfigurationManager.TaskDescriptionException; import org.apache.aurora.scheduler.configuration.SanitizedConfiguration; import org.apache.aurora.scheduler.cron.CronPredictor; @@ -113,6 +114,7 @@ class ReadOnlySchedulerImpl implements ReadOnlyScheduler.Iface { .setConfig(input.getKey().newBuilder()) .setInstances(IRange.toBuildersSet(convertRanges(toRanges(input.getValue())))); + private final ConfigurationManager configurationManager; private final Storage storage; private final NearestFit nearestFit; private final CronPredictor cronPredictor; @@ -121,12 +123,14 @@ class ReadOnlySchedulerImpl implements ReadOnlyScheduler.Iface { @Inject ReadOnlySchedulerImpl( + ConfigurationManager configurationManager, Storage storage, NearestFit nearestFit, CronPredictor cronPredictor, QuotaManager quotaManager, LockManager lockManager) { + this.configurationManager = requireNonNull(configurationManager); this.storage = requireNonNull(storage); this.nearestFit = requireNonNull(nearestFit); this.cronPredictor = requireNonNull(cronPredictor); @@ -140,6 +144,7 @@ class ReadOnlySchedulerImpl implements ReadOnlyScheduler.Iface { try { ITaskConfig populatedTaskConfig = SanitizedConfiguration.fromUnsanitized( + configurationManager, IJobConfiguration.build(description)).getJobConfig().getTaskConfig(); return ok(Result.populateJobResult( new PopulateJobResult().setTaskConfig(populatedTaskConfig.newBuilder()))); http://git-wip-us.apache.org/repos/asf/aurora/blob/eec985d9/src/main/java/org/apache/aurora/scheduler/thrift/SchedulerThriftInterface.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/thrift/SchedulerThriftInterface.java b/src/main/java/org/apache/aurora/scheduler/thrift/SchedulerThriftInterface.java index fd5e2f2..0afe924 100644 --- a/src/main/java/org/apache/aurora/scheduler/thrift/SchedulerThriftInterface.java +++ b/src/main/java/org/apache/aurora/scheduler/thrift/SchedulerThriftInterface.java @@ -34,9 +34,6 @@ import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; import com.google.common.collect.Range; -import org.apache.aurora.common.args.Arg; -import org.apache.aurora.common.args.CmdLine; -import org.apache.aurora.common.args.constraints.Positive; import org.apache.aurora.gen.AcquireLockResult; import org.apache.aurora.gen.AddInstancesConfig; import org.apache.aurora.gen.ConfigRewrite; @@ -149,20 +146,6 @@ import static org.apache.aurora.scheduler.thrift.Responses.ok; */ @DecoratedThrift class SchedulerThriftInterface implements AnnotatedAuroraAdmin { - private static final int DEFAULT_MAX_TASKS_PER_JOB = 4000; - private static final int DEFAULT_MAX_UPDATE_INSTANCE_FAILURES = - DEFAULT_MAX_TASKS_PER_JOB * 5; - - @Positive - @CmdLine(name = "max_tasks_per_job", help = "Maximum number of allowed tasks in a single job.") - public static final Arg<Integer> MAX_TASKS_PER_JOB = Arg.create(DEFAULT_MAX_TASKS_PER_JOB); - - @Positive - @CmdLine(name = "max_update_instance_failures", help = "Upper limit on the number of " - + "failures allowed during a job update. This helps cap potentially unbounded entries into " - + "storage.") - public static final Arg<Integer> MAX_UPDATE_INSTANCE_FAILURES = Arg.create( - DEFAULT_MAX_UPDATE_INSTANCE_FAILURES); // This number is derived from the maximum file name length limit on most UNIX systems, less // the number of characters we've observed being added by mesos for the executor ID, prefix, and @@ -172,6 +155,8 @@ class SchedulerThriftInterface implements AnnotatedAuroraAdmin { private static final Logger LOG = Logger.getLogger(SchedulerThriftInterface.class.getName()); + private final ConfigurationManager configurationManager; + private final Thresholds thresholds; private final NonVolatileStorage storage; private final LockManager lockManager; private final StorageBackup backup; @@ -188,6 +173,8 @@ class SchedulerThriftInterface implements AnnotatedAuroraAdmin { @Inject SchedulerThriftInterface( + ConfigurationManager configurationManager, + Thresholds thresholds, NonVolatileStorage storage, LockManager lockManager, StorageBackup backup, @@ -202,6 +189,8 @@ class SchedulerThriftInterface implements AnnotatedAuroraAdmin { ReadOnlyScheduler.Iface readOnlyScheduler, AuditMessages auditMessages) { + this.configurationManager = requireNonNull(configurationManager); + this.thresholds = requireNonNull(thresholds); this.storage = requireNonNull(storage); this.lockManager = requireNonNull(lockManager); this.backup = requireNonNull(backup); @@ -221,7 +210,9 @@ class SchedulerThriftInterface implements AnnotatedAuroraAdmin { public Response createJob(JobConfiguration mutableJob, @Nullable Lock mutableLock) { SanitizedConfiguration sanitized; try { - sanitized = SanitizedConfiguration.fromUnsanitized(IJobConfiguration.build(mutableJob)); + sanitized = SanitizedConfiguration.fromUnsanitized( + configurationManager, + IJobConfiguration.build(mutableJob)); } catch (TaskDescriptionException e) { return error(INVALID_REQUEST, e); } @@ -287,7 +278,7 @@ class SchedulerThriftInterface implements AnnotatedAuroraAdmin { SanitizedConfiguration sanitized; try { - sanitized = SanitizedConfiguration.fromUnsanitized(job); + sanitized = SanitizedConfiguration.fromUnsanitized(configurationManager, job); } catch (TaskDescriptionException e) { return error(INVALID_REQUEST, e); } @@ -653,7 +644,7 @@ class SchedulerThriftInterface implements AnnotatedAuroraAdmin { IJobConfiguration rewrittenJob; Optional<String> error = Optional.absent(); try { - rewrittenJob = ConfigurationManager.validateAndPopulate(jobRewrite.getRewrittenJob()); + rewrittenJob = configurationManager.validateAndPopulate(jobRewrite.getRewrittenJob()); } catch (TaskDescriptionException e) { // We could add an error here, but this is probably a hint of something wrong in // the client that's causing a bad configuration to be applied. @@ -742,8 +733,7 @@ class SchedulerThriftInterface implements AnnotatedAuroraAdmin { ITaskConfig task; try { - task = ConfigurationManager.validateAndPopulate( - ITaskConfig.build(config.getTaskConfig())); + task = configurationManager.validateAndPopulate(ITaskConfig.build(config.getTaskConfig())); } catch (TaskDescriptionException e) { return error(INVALID_REQUEST, e); } @@ -834,10 +824,9 @@ class SchedulerThriftInterface implements AnnotatedAuroraAdmin { int totalInstances, QuotaCheckResult quotaCheck) throws TaskValidationException { - if (totalInstances <= 0 || totalInstances > MAX_TASKS_PER_JOB.get()) { + if (totalInstances <= 0 || totalInstances > thresholds.getMaxTasksPerJob()) { throw new TaskValidationException(String.format( - "Instance count must be between 1 and %d inclusive.", - MAX_TASKS_PER_JOB.get())); + "Instance count must be between 1 and %d inclusive.", thresholds.getMaxTasksPerJob())); } // TODO(maximk): This is a short-term hack to stop the bleeding from @@ -900,7 +889,7 @@ class SchedulerThriftInterface implements AnnotatedAuroraAdmin { } if (settings.getMaxPerInstanceFailures() * mutableRequest.getInstanceCount() - > MAX_UPDATE_INSTANCE_FAILURES.get()) { + > thresholds.getMaxUpdateInstanceFailures()) { return invalidRequest(TOO_MANY_POTENTIAL_FAILED_INSTANCES); } @@ -915,9 +904,8 @@ class SchedulerThriftInterface implements AnnotatedAuroraAdmin { IJobUpdateRequest request; try { request = IJobUpdateRequest.build(new JobUpdateRequest(mutableRequest).setTaskConfig( - ConfigurationManager.validateAndPopulate( + configurationManager.validateAndPopulate( ITaskConfig.build(mutableRequest.getTaskConfig())).newBuilder())); - } catch (TaskDescriptionException e) { return error(INVALID_REQUEST, e); } http://git-wip-us.apache.org/repos/asf/aurora/blob/eec985d9/src/main/java/org/apache/aurora/scheduler/thrift/Thresholds.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/thrift/Thresholds.java b/src/main/java/org/apache/aurora/scheduler/thrift/Thresholds.java new file mode 100644 index 0000000..02132fe --- /dev/null +++ b/src/main/java/org/apache/aurora/scheduler/thrift/Thresholds.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.thrift; + +import com.google.common.base.MoreObjects; + +/** + * Input value thresholds for creating entities via the API. + */ +public class Thresholds { + private final int maxTasksPerJob; + private final int maxUpdateInstanceFailures; + + public Thresholds(int maxTasksPerJob, int maxUpdateInstanceFailures) { + this.maxTasksPerJob = maxTasksPerJob; + this.maxUpdateInstanceFailures = maxUpdateInstanceFailures; + } + + public int getMaxTasksPerJob() { + return maxTasksPerJob; + } + + public int getMaxUpdateInstanceFailures() { + return maxUpdateInstanceFailures; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("maxTasksPerJob", maxTasksPerJob) + .add("maxUpdateInstanceFailures", maxUpdateInstanceFailures) + .toString(); + } +} http://git-wip-us.apache.org/repos/asf/aurora/blob/eec985d9/src/test/java/org/apache/aurora/scheduler/configuration/ConfigurationManagerTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/aurora/scheduler/configuration/ConfigurationManagerTest.java b/src/test/java/org/apache/aurora/scheduler/configuration/ConfigurationManagerTest.java index c6a4ac5..4286795 100644 --- a/src/test/java/org/apache/aurora/scheduler/configuration/ConfigurationManagerTest.java +++ b/src/test/java/org/apache/aurora/scheduler/configuration/ConfigurationManagerTest.java @@ -30,12 +30,13 @@ import org.apache.aurora.gen.TaskConstraint; import org.apache.aurora.gen.ValueConstraint; import org.apache.aurora.scheduler.configuration.ConfigurationManager.TaskDescriptionException; import org.apache.aurora.scheduler.storage.entities.ITaskConfig; +import org.junit.Before; import org.junit.Test; import static org.apache.aurora.gen.test.testConstants.INVALID_IDENTIFIERS; import static org.apache.aurora.gen.test.testConstants.VALID_IDENTIFIERS; +import static org.apache.aurora.scheduler.base.UserProvidedStrings.isGoodIdentifier; import static org.apache.aurora.scheduler.configuration.ConfigurationManager.DEDICATED_ATTRIBUTE; -import static org.apache.aurora.scheduler.configuration.ConfigurationManager.isGoodIdentifier; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -93,6 +94,13 @@ public class ConfigurationManagerTest { .setContainer(Container.docker(new DockerContainer("testimage")))) .newBuilder(); + private ConfigurationManager configurationManager; + + @Before + public void setUp() { + configurationManager = new ConfigurationManager(ImmutableSet.of(), false); + } + @Test public void testIsGoodIdentifier() { for (String identifier : VALID_IDENTIFIERS) { @@ -108,7 +116,7 @@ public class ConfigurationManagerTest { TaskConfig taskConfig = CONFIG_WITH_CONTAINER.deepCopy(); taskConfig.getContainer().getDocker().setImage(null); - ConfigurationManager.validateAndPopulate(ITaskConfig.build(taskConfig)); + configurationManager.validateAndPopulate(ITaskConfig.build(taskConfig)); } @Test(expected = TaskDescriptionException.class) @@ -118,6 +126,6 @@ public class ConfigurationManagerTest { .setEnvironment("env") .setTier("pr/d")); - ConfigurationManager.validateAndPopulate(config); + configurationManager.validateAndPopulate(config); } } http://git-wip-us.apache.org/repos/asf/aurora/blob/eec985d9/src/test/java/org/apache/aurora/scheduler/cron/quartz/AuroraCronJobTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/aurora/scheduler/cron/quartz/AuroraCronJobTest.java b/src/test/java/org/apache/aurora/scheduler/cron/quartz/AuroraCronJobTest.java index 5dd4aba..5c64ff2 100644 --- a/src/test/java/org/apache/aurora/scheduler/cron/quartz/AuroraCronJobTest.java +++ b/src/test/java/org/apache/aurora/scheduler/cron/quartz/AuroraCronJobTest.java @@ -23,6 +23,7 @@ import org.apache.aurora.gen.AssignedTask; import org.apache.aurora.gen.CronCollisionPolicy; import org.apache.aurora.gen.ScheduleStatus; import org.apache.aurora.gen.ScheduledTask; +import org.apache.aurora.scheduler.base.TaskTestUtil; import org.apache.aurora.scheduler.state.StateChangeResult; import org.apache.aurora.scheduler.state.StateManager; import org.apache.aurora.scheduler.storage.Storage; @@ -56,6 +57,7 @@ public class AuroraCronJobTest extends EasyMockTest { backoffHelper = createMock(BackoffHelper.class); auroraCronJob = new AuroraCronJob( + TaskTestUtil.CONFIGURATION_MANAGER, new AuroraCronJob.Config(backoffHelper), storage, stateManager); } http://git-wip-us.apache.org/repos/asf/aurora/blob/eec985d9/src/test/java/org/apache/aurora/scheduler/cron/quartz/CronIT.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/aurora/scheduler/cron/quartz/CronIT.java b/src/test/java/org/apache/aurora/scheduler/cron/quartz/CronIT.java index 17d12c3..3ce78e3 100644 --- a/src/test/java/org/apache/aurora/scheduler/cron/quartz/CronIT.java +++ b/src/test/java/org/apache/aurora/scheduler/cron/quartz/CronIT.java @@ -30,6 +30,7 @@ import org.apache.aurora.gen.MesosContainer; import org.apache.aurora.gen.TaskConfig; import org.apache.aurora.scheduler.base.JobKeys; import org.apache.aurora.scheduler.base.TaskTestUtil; +import org.apache.aurora.scheduler.configuration.ConfigurationManager; import org.apache.aurora.scheduler.cron.CronJobManager; import org.apache.aurora.scheduler.cron.CrontabEntry; import org.apache.aurora.scheduler.cron.SanitizedCronJob; @@ -90,6 +91,7 @@ public class CronIT extends EasyMockTest { }), new AbstractModule() { @Override protected void configure() { + bind(ConfigurationManager.class).toInstance(TaskTestUtil.CONFIGURATION_MANAGER); bind(Clock.class).toInstance(Clock.SYSTEM_CLOCK); bind(StateManager.class).toInstance(stateManager); bind(Storage.class).toInstance(storage); @@ -176,7 +178,9 @@ public class CronIT extends EasyMockTest { boot(); - cronJobManager.createJob(SanitizedCronJob.fromUnsanitized(CRON_JOB)); + cronJobManager.createJob(SanitizedCronJob.fromUnsanitized( + TaskTestUtil.CONFIGURATION_MANAGER, + CRON_JOB)); cronJobManager.startJobNow(JOB_KEY); firstExecutionTriggered.await(); cronJobManager.startJobNow(JOB_KEY); http://git-wip-us.apache.org/repos/asf/aurora/blob/eec985d9/src/test/java/org/apache/aurora/scheduler/cron/quartz/CronJobManagerImplTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/aurora/scheduler/cron/quartz/CronJobManagerImplTest.java b/src/test/java/org/apache/aurora/scheduler/cron/quartz/CronJobManagerImplTest.java index 716e0a1..81440f5 100644 --- a/src/test/java/org/apache/aurora/scheduler/cron/quartz/CronJobManagerImplTest.java +++ b/src/test/java/org/apache/aurora/scheduler/cron/quartz/CronJobManagerImplTest.java @@ -24,6 +24,7 @@ import com.google.common.collect.ImmutableSet; import org.apache.aurora.common.testing.easymock.EasyMockTest; import org.apache.aurora.gen.CronCollisionPolicy; +import org.apache.aurora.scheduler.base.TaskTestUtil; import org.apache.aurora.scheduler.cron.CronException; import org.apache.aurora.scheduler.cron.CronJobManager; import org.apache.aurora.scheduler.cron.CrontabEntry; @@ -162,6 +163,7 @@ public class CronJobManagerImplTest extends EasyMockTest { @Test public void testNoRunOverlap() throws Exception { SanitizedCronJob runOverlapJob = SanitizedCronJob.fromUnsanitized( + TaskTestUtil.CONFIGURATION_MANAGER, IJobConfiguration.build(QuartzTestUtil.JOB.newBuilder() .setCronCollisionPolicy(CronCollisionPolicy.RUN_OVERLAP))); http://git-wip-us.apache.org/repos/asf/aurora/blob/eec985d9/src/test/java/org/apache/aurora/scheduler/cron/quartz/QuartzTestUtil.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/aurora/scheduler/cron/quartz/QuartzTestUtil.java b/src/test/java/org/apache/aurora/scheduler/cron/quartz/QuartzTestUtil.java index 13cb73d..f062497 100644 --- a/src/test/java/org/apache/aurora/scheduler/cron/quartz/QuartzTestUtil.java +++ b/src/test/java/org/apache/aurora/scheduler/cron/quartz/QuartzTestUtil.java @@ -23,6 +23,7 @@ import org.apache.aurora.gen.JobConfiguration; import org.apache.aurora.gen.Metadata; import org.apache.aurora.gen.TaskConfig; import org.apache.aurora.scheduler.base.JobKeys; +import org.apache.aurora.scheduler.base.TaskTestUtil; import org.apache.aurora.scheduler.configuration.ConfigurationManager; import org.apache.aurora.scheduler.cron.CronException; import org.apache.aurora.scheduler.cron.SanitizedCronJob; @@ -63,6 +64,7 @@ final class QuartzTestUtil { static SanitizedCronJob makeSanitizedCronJob(CronCollisionPolicy collisionPolicy) { try { return SanitizedCronJob.fromUnsanitized( + TaskTestUtil.CONFIGURATION_MANAGER, IJobConfiguration.build(JOB.newBuilder().setCronCollisionPolicy(collisionPolicy))); } catch (CronException | ConfigurationManager.TaskDescriptionException e) { throw Throwables.propagate(e); @@ -75,6 +77,7 @@ final class QuartzTestUtil { static SanitizedCronJob makeUpdatedJob() throws Exception { return SanitizedCronJob.fromUnsanitized( + TaskTestUtil.CONFIGURATION_MANAGER, IJobConfiguration.build(JOB.newBuilder().setCronSchedule("* * 1 * *"))); } } http://git-wip-us.apache.org/repos/asf/aurora/blob/eec985d9/src/test/java/org/apache/aurora/scheduler/thrift/ReadOnlySchedulerImplTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/aurora/scheduler/thrift/ReadOnlySchedulerImplTest.java b/src/test/java/org/apache/aurora/scheduler/thrift/ReadOnlySchedulerImplTest.java index 011b79a..b785d8b 100644 --- a/src/test/java/org/apache/aurora/scheduler/thrift/ReadOnlySchedulerImplTest.java +++ b/src/test/java/org/apache/aurora/scheduler/thrift/ReadOnlySchedulerImplTest.java @@ -65,6 +65,7 @@ import org.apache.aurora.scheduler.base.JobKeys; import org.apache.aurora.scheduler.base.Query; import org.apache.aurora.scheduler.base.Query.Builder; import org.apache.aurora.scheduler.base.TaskGroupKey; +import org.apache.aurora.scheduler.base.TaskTestUtil; import org.apache.aurora.scheduler.base.Tasks; import org.apache.aurora.scheduler.configuration.SanitizedConfiguration; import org.apache.aurora.scheduler.cron.CronPredictor; @@ -136,6 +137,7 @@ public class ReadOnlySchedulerImplTest extends EasyMockTest { lockManager = createMock(LockManager.class); thrift = new ReadOnlySchedulerImpl( + TaskTestUtil.CONFIGURATION_MANAGER, storageUtil.storage, nearestFit, cronPredictor, @@ -302,7 +304,8 @@ public class ReadOnlySchedulerImplTest extends EasyMockTest { @Test public void testPopulateJobConfig() throws Exception { IJobConfiguration job = IJobConfiguration.build(makeJob()); - SanitizedConfiguration sanitized = SanitizedConfiguration.fromUnsanitized(job); + SanitizedConfiguration sanitized = + SanitizedConfiguration.fromUnsanitized(TaskTestUtil.CONFIGURATION_MANAGER, job); control.replay(); Response response = assertOkResponse(thrift.populateJobConfig(job.newBuilder())); http://git-wip-us.apache.org/repos/asf/aurora/blob/eec985d9/src/test/java/org/apache/aurora/scheduler/thrift/SchedulerThriftInterfaceTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/aurora/scheduler/thrift/SchedulerThriftInterfaceTest.java b/src/test/java/org/apache/aurora/scheduler/thrift/SchedulerThriftInterfaceTest.java index 129851c..d12b56e 100644 --- a/src/test/java/org/apache/aurora/scheduler/thrift/SchedulerThriftInterfaceTest.java +++ b/src/test/java/org/apache/aurora/scheduler/thrift/SchedulerThriftInterfaceTest.java @@ -74,7 +74,8 @@ import org.apache.aurora.gen.ValueConstraint; import org.apache.aurora.scheduler.TaskIdGenerator; import org.apache.aurora.scheduler.base.JobKeys; import org.apache.aurora.scheduler.base.Query; -import org.apache.aurora.scheduler.configuration.ConfigurationManager; +import org.apache.aurora.scheduler.base.TaskTestUtil; +import org.apache.aurora.scheduler.configuration.ConfigurationManager.TaskDescriptionException; import org.apache.aurora.scheduler.configuration.SanitizedConfiguration; import org.apache.aurora.scheduler.cron.CronException; import org.apache.aurora.scheduler.cron.CronJobManager; @@ -142,7 +143,6 @@ import static org.apache.aurora.scheduler.thrift.Fixtures.nonProductionTask; import static org.apache.aurora.scheduler.thrift.Fixtures.okResponse; import static org.apache.aurora.scheduler.thrift.Fixtures.productionTask; import static org.apache.aurora.scheduler.thrift.Fixtures.response; -import static org.apache.aurora.scheduler.thrift.SchedulerThriftInterface.MAX_TASKS_PER_JOB; import static org.apache.aurora.scheduler.thrift.SchedulerThriftInterface.MAX_TASK_ID_LENGTH; import static org.apache.aurora.scheduler.thrift.SchedulerThriftInterface.NOOP_JOB_UPDATE_MESSAGE; import static org.apache.aurora.scheduler.thrift.SchedulerThriftInterface.NO_CRON; @@ -163,6 +163,7 @@ public class SchedulerThriftInterfaceTest extends EasyMockTest { private static final String AUDIT_MESSAGE = "message"; private static final AuditData AUDIT = new AuditData(USER, Optional.of(AUDIT_MESSAGE)); + private static final Thresholds THRESHOLDS = new Thresholds(1000, 2000); private StorageTestUtil storageUtil; private LockManager lockManager; @@ -198,6 +199,8 @@ public class SchedulerThriftInterfaceTest extends EasyMockTest { thrift = getResponseProxy( new SchedulerThriftInterface( + TaskTestUtil.CONFIGURATION_MANAGER, + THRESHOLDS, storageUtil.storage, lockManager, backup, @@ -233,6 +236,18 @@ public class SchedulerThriftInterfaceTest extends EasyMockTest { }); } + private static SanitizedConfiguration fromUnsanitized(IJobConfiguration job) + throws TaskDescriptionException { + + return SanitizedConfiguration.fromUnsanitized(TaskTestUtil.CONFIGURATION_MANAGER, job); + } + + private static IJobConfiguration validateAndPopulate(IJobConfiguration job) + throws TaskDescriptionException { + + return TaskTestUtil.CONFIGURATION_MANAGER.validateAndPopulate(job); + } + @Test public void testCreateJobNoLock() throws Exception { // Validate key is populated during sanitizing. @@ -240,7 +255,7 @@ public class SchedulerThriftInterfaceTest extends EasyMockTest { jobConfig.getTaskConfig().unsetJob(); IJobConfiguration job = IJobConfiguration.build(makeProdJob()); - SanitizedConfiguration sanitized = SanitizedConfiguration.fromUnsanitized(job); + SanitizedConfiguration sanitized = fromUnsanitized(job); lockManager.validateIfLocked(LOCK_KEY, java.util.Optional.empty()); storageUtil.expectTaskFetch(Query.jobScoped(JOB_KEY).active()); expectNoCronJob(); @@ -261,7 +276,7 @@ public class SchedulerThriftInterfaceTest extends EasyMockTest { @Test public void testCreateJobWithLock() throws Exception { IJobConfiguration job = IJobConfiguration.build(makeProdJob()); - SanitizedConfiguration sanitized = SanitizedConfiguration.fromUnsanitized(job); + SanitizedConfiguration sanitized = fromUnsanitized(job); lockManager.validateIfLocked(LOCK_KEY, java.util.Optional.of(LOCK)); storageUtil.expectTaskFetch(Query.jobScoped(JOB_KEY).active()); expectNoCronJob(); @@ -337,7 +352,7 @@ public class SchedulerThriftInterfaceTest extends EasyMockTest { @Test public void testCreateJobFailsInstanceCheck() throws Exception { IJobConfiguration job = IJobConfiguration.build( - makeJob(defaultTask(true), MAX_TASKS_PER_JOB.get() + 1)); + makeJob(defaultTask(true), THRESHOLDS.getMaxTasksPerJob() + 1)); lockManager.validateIfLocked(LOCK_KEY, java.util.Optional.empty()); storageUtil.expectTaskFetch(Query.jobScoped(JOB_KEY).active()); @@ -355,7 +370,7 @@ public class SchedulerThriftInterfaceTest extends EasyMockTest { @Test public void testCreateJobFailsTaskIdLength() throws Exception { IJobConfiguration job = IJobConfiguration.build(makeJob()); - SanitizedConfiguration sanitized = SanitizedConfiguration.fromUnsanitized(job); + SanitizedConfiguration sanitized = fromUnsanitized(job); lockManager.validateIfLocked(LOCK_KEY, java.util.Optional.empty()); storageUtil.expectTaskFetch(Query.jobScoped(JOB_KEY).active()); expectNoCronJob(); @@ -375,7 +390,7 @@ public class SchedulerThriftInterfaceTest extends EasyMockTest { @Test public void testCreateJobFailsQuotaCheck() throws Exception { IJobConfiguration job = IJobConfiguration.build(makeProdJob()); - SanitizedConfiguration sanitized = SanitizedConfiguration.fromUnsanitized(job); + SanitizedConfiguration sanitized = fromUnsanitized(job); lockManager.validateIfLocked(LOCK_KEY, java.util.Optional.empty()); storageUtil.expectTaskFetch(Query.jobScoped(JOB_KEY).active()); expectNoCronJob(); @@ -829,8 +844,7 @@ public class SchedulerThriftInterfaceTest extends EasyMockTest { @Test public void testReplaceCronTemplate() throws Exception { lockManager.validateIfLocked(LOCK_KEY, java.util.Optional.empty()); - SanitizedConfiguration sanitized = - SanitizedConfiguration.fromUnsanitized(IJobConfiguration.build(CRON_JOB)); + SanitizedConfiguration sanitized = fromUnsanitized(IJobConfiguration.build(CRON_JOB)); expect(taskIdGenerator.generate(sanitized.getJobConfig().getTaskConfig(), 1)) .andReturn(TASK_ID); @@ -856,8 +870,7 @@ public class SchedulerThriftInterfaceTest extends EasyMockTest { @Test public void testReplaceCronTemplateDoesNotExist() throws Exception { lockManager.validateIfLocked(LOCK_KEY, java.util.Optional.empty()); - SanitizedConfiguration sanitized = - SanitizedConfiguration.fromUnsanitized(IJobConfiguration.build(CRON_JOB)); + SanitizedConfiguration sanitized = fromUnsanitized(IJobConfiguration.build(CRON_JOB)); expect(taskIdGenerator.generate(sanitized.getJobConfig().getTaskConfig(), 1)) .andReturn(TASK_ID); @@ -888,8 +901,7 @@ public class SchedulerThriftInterfaceTest extends EasyMockTest { @Test public void testScheduleCronCreatesJob() throws Exception { lockManager.validateIfLocked(LOCK_KEY, java.util.Optional.empty()); - SanitizedConfiguration sanitized = - SanitizedConfiguration.fromUnsanitized(IJobConfiguration.build(CRON_JOB)); + SanitizedConfiguration sanitized = fromUnsanitized(IJobConfiguration.build(CRON_JOB)); expect(taskIdGenerator.generate(sanitized.getJobConfig().getTaskConfig(), 1)) .andReturn(TASK_ID); @@ -905,8 +917,7 @@ public class SchedulerThriftInterfaceTest extends EasyMockTest { @Test public void testScheduleCronFailsCreationDueToExistingNonCron() throws Exception { lockManager.validateIfLocked(LOCK_KEY, java.util.Optional.empty()); - SanitizedConfiguration sanitized = - SanitizedConfiguration.fromUnsanitized(IJobConfiguration.build(CRON_JOB)); + SanitizedConfiguration sanitized = fromUnsanitized(IJobConfiguration.build(CRON_JOB)); expect(taskIdGenerator.generate(sanitized.getJobConfig().getTaskConfig(), 1)) .andReturn(TASK_ID); @@ -923,8 +934,7 @@ public class SchedulerThriftInterfaceTest extends EasyMockTest { @Test public void testScheduleCronUpdatesJob() throws Exception { lockManager.validateIfLocked(LOCK_KEY, java.util.Optional.empty()); - SanitizedConfiguration sanitized = - SanitizedConfiguration.fromUnsanitized(IJobConfiguration.build(CRON_JOB)); + SanitizedConfiguration sanitized = fromUnsanitized(IJobConfiguration.build(CRON_JOB)); expect(taskIdGenerator.generate(sanitized.getJobConfig().getTaskConfig(), 1)) .andReturn(TASK_ID); @@ -969,8 +979,7 @@ public class SchedulerThriftInterfaceTest extends EasyMockTest { @Test public void testScheduleCronFailsQuotaCheck() throws Exception { lockManager.validateIfLocked(LOCK_KEY, java.util.Optional.empty()); - SanitizedConfiguration sanitized = - SanitizedConfiguration.fromUnsanitized(IJobConfiguration.build(CRON_JOB)); + SanitizedConfiguration sanitized = fromUnsanitized(IJobConfiguration.build(CRON_JOB)); expect(taskIdGenerator.generate(sanitized.getJobConfig().getTaskConfig(), 1)) .andReturn(TASK_ID); @@ -1185,8 +1194,7 @@ public class SchedulerThriftInterfaceTest extends EasyMockTest { newJob.getTaskConfig().setExecutorConfig(new ExecutorConfig("aurora", "rewritten")); expect(storageUtil.jobStore.fetchJob(IJobKey.build(oldJob.getKey()))) .andReturn(Optional.of(IJobConfiguration.build(oldJob))); - storageUtil.jobStore.saveAcceptedJob( - ConfigurationManager.validateAndPopulate(IJobConfiguration.build(newJob))); + storageUtil.jobStore.saveAcceptedJob(validateAndPopulate(IJobConfiguration.build(newJob))); control.replay(); @@ -1634,8 +1642,7 @@ public class SchedulerThriftInterfaceTest extends EasyMockTest { JobUpdateRequest updateRequest = buildServiceJobUpdateRequest(); updateRequest.getSettings() - .setMaxPerInstanceFailures(SchedulerThriftInterface.MAX_UPDATE_INSTANCE_FAILURES.get() - + 10); + .setMaxPerInstanceFailures(THRESHOLDS.getMaxUpdateInstanceFailures() + 10); assertEquals( invalidResponse(SchedulerThriftInterface.TOO_MANY_POTENTIAL_FAILED_INSTANCES), @@ -1790,7 +1797,7 @@ public class SchedulerThriftInterfaceTest extends EasyMockTest { @Test public void testStartUpdateFailsInstanceCountCheck() throws Exception { JobUpdateRequest request = buildServiceJobUpdateRequest(populatedTask()); - request.setInstanceCount(4001); + request.setInstanceCount(THRESHOLDS.getMaxTasksPerJob() + 1); expectGetRemoteUser(); expectNoCronJob(); expect(uuidGenerator.createNew()).andReturn(UU_ID); http://git-wip-us.apache.org/repos/asf/aurora/blob/eec985d9/src/test/java/org/apache/aurora/scheduler/thrift/ThriftIT.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/aurora/scheduler/thrift/ThriftIT.java b/src/test/java/org/apache/aurora/scheduler/thrift/ThriftIT.java index 72b5c30..860d960 100644 --- a/src/test/java/org/apache/aurora/scheduler/thrift/ThriftIT.java +++ b/src/test/java/org/apache/aurora/scheduler/thrift/ThriftIT.java @@ -26,6 +26,8 @@ import org.apache.aurora.gen.AuroraAdmin; import org.apache.aurora.gen.ResourceAggregate; import org.apache.aurora.gen.ServerInfo; import org.apache.aurora.scheduler.TaskIdGenerator; +import org.apache.aurora.scheduler.base.TaskTestUtil; +import org.apache.aurora.scheduler.configuration.ConfigurationManager; import org.apache.aurora.scheduler.cron.CronJobManager; import org.apache.aurora.scheduler.cron.CronPredictor; import org.apache.aurora.scheduler.quota.QuotaManager; @@ -86,6 +88,8 @@ public class ThriftIT extends EasyMockTest { bindMock(TaskIdGenerator.class); bindMock(UUIDGenerator.class); bindMock(JobUpdateController.class); + bind(ConfigurationManager.class).toInstance(TaskTestUtil.CONFIGURATION_MANAGER); + bind(Thresholds.class).toInstance(new Thresholds(1000, 2000)); storageTestUtil = new StorageTestUtil(ThriftIT.this); bind(Storage.class).toInstance(storageTestUtil.storage); bind(NonVolatileStorage.class).toInstance(storageTestUtil.storage);
