Repository: aurora Updated Branches: refs/heads/master fdb536af8 -> b417be38f
http://git-wip-us.apache.org/repos/asf/aurora/blob/b417be38/src/main/java/org/apache/aurora/scheduler/discovery/FlaggedZooKeeperConfig.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/discovery/FlaggedZooKeeperConfig.java b/src/main/java/org/apache/aurora/scheduler/discovery/FlaggedZooKeeperConfig.java index c3a524f..d5019bf 100644 --- a/src/main/java/org/apache/aurora/scheduler/discovery/FlaggedZooKeeperConfig.java +++ b/src/main/java/org/apache/aurora/scheduler/discovery/FlaggedZooKeeperConfig.java @@ -15,10 +15,10 @@ package org.apache.aurora.scheduler.discovery; import java.net.InetSocketAddress; import java.util.List; +import java.util.Optional; import javax.annotation.Nullable; -import com.google.common.base.Optional; import com.google.common.base.Splitter; import com.google.common.collect.ImmutableList; @@ -27,8 +27,6 @@ import org.apache.aurora.common.args.CmdLine; import org.apache.aurora.common.args.constraints.NotEmpty; import org.apache.aurora.common.quantity.Amount; import org.apache.aurora.common.quantity.Time; -import org.apache.aurora.common.zookeeper.Credentials; -import org.apache.aurora.common.zookeeper.ZooKeeperUtils; /** * A factory that creates a {@link ZooKeeperConfig} instance based on command line argument @@ -67,7 +65,7 @@ public final class FlaggedZooKeeperConfig { public static ZooKeeperConfig create() { return new ZooKeeperConfig( ZK_ENDPOINTS.get(), - Optional.fromNullable(CHROOT_PATH.get()), + Optional.ofNullable(CHROOT_PATH.get()), IN_PROCESS.get(), SESSION_TIMEOUT.get(), getCredentials(DIGEST_CREDENTIALS.get())); @@ -75,7 +73,7 @@ public final class FlaggedZooKeeperConfig { private static Optional<Credentials> getCredentials(@Nullable String userAndPass) { if (userAndPass == null) { - return Optional.absent(); + return Optional.empty(); } List<String> parts = ImmutableList.copyOf(Splitter.on(":").split(userAndPass)); http://git-wip-us.apache.org/repos/asf/aurora/blob/b417be38/src/main/java/org/apache/aurora/scheduler/discovery/JsonCodec.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/discovery/JsonCodec.java b/src/main/java/org/apache/aurora/scheduler/discovery/JsonCodec.java new file mode 100644 index 0000000..9d22b76 --- /dev/null +++ b/src/main/java/org/apache/aurora/scheduler/discovery/JsonCodec.java @@ -0,0 +1,147 @@ +/** + * 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.discovery; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.nio.charset.Charset; +import java.util.Map; + +import javax.annotation.Nullable; + +import com.google.common.base.Charsets; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; +import com.google.gson.Gson; +import com.google.gson.JsonIOException; +import com.google.gson.JsonParseException; + +import org.apache.aurora.common.io.Codec; +import org.apache.aurora.common.thrift.Endpoint; +import org.apache.aurora.common.thrift.ServiceInstance; +import org.apache.aurora.common.thrift.Status; + +import static java.util.Objects.requireNonNull; + +/** + * Encodes a {@link ServiceInstance} as a JSON object. + */ +class JsonCodec implements Codec<ServiceInstance> { + + private static void assertRequiredField(String fieldName, Object fieldValue) { + if (fieldValue == null) { + throw new JsonParseException(String.format("Field %s is required", fieldName)); + } + } + + private static class EndpointSchema { + private final String host; + private final Integer port; + + EndpointSchema(Endpoint endpoint) { + host = endpoint.getHost(); + port = endpoint.getPort(); + } + + Endpoint asEndpoint() { + assertRequiredField("host", host); + assertRequiredField("port", port); + + return new Endpoint(host, port); + } + } + + private static class ServiceInstanceSchema { + private final EndpointSchema serviceEndpoint; + private final Map<String, EndpointSchema> additionalEndpoints; + private final Status status; + @Nullable private final Integer shard; + + ServiceInstanceSchema(ServiceInstance instance) { + serviceEndpoint = new EndpointSchema(instance.getServiceEndpoint()); + if (instance.isSetAdditionalEndpoints()) { + additionalEndpoints = + Maps.transformValues(instance.getAdditionalEndpoints(), EndpointSchema::new); + } else { + additionalEndpoints = ImmutableMap.of(); + } + status = instance.getStatus(); + shard = instance.isSetShard() ? instance.getShard() : null; + } + + ServiceInstance asServiceInstance() { + assertRequiredField("serviceEndpoint", serviceEndpoint); + assertRequiredField("status", status); + + Map<String, EndpointSchema> extraEndpoints = + additionalEndpoints == null ? ImmutableMap.of() : additionalEndpoints; + + ServiceInstance instance = + new ServiceInstance( + serviceEndpoint.asEndpoint(), + Maps.transformValues(extraEndpoints, EndpointSchema::asEndpoint), + status); + if (shard != null) { + instance.setShard(shard); + } + return instance; + } + } + + /** + * The encoding for service instance data in ZooKeeper expected by Aurora clients. + */ + static final Codec<ServiceInstance> INSTANCE = new JsonCodec(); + + private static final Charset ENCODING = Charsets.UTF_8; + + private final Gson gson; + + private JsonCodec() { + this(new Gson()); + } + + JsonCodec(Gson gson) { + this.gson = requireNonNull(gson); + } + + @Override + public void serialize(ServiceInstance instance, OutputStream sink) throws IOException { + Writer writer = new OutputStreamWriter(sink, ENCODING); + try { + gson.toJson(new ServiceInstanceSchema(instance), writer); + } catch (JsonIOException e) { + throw new IOException(String.format("Problem serializing %s to JSON", instance), e); + } + writer.flush(); + } + + @Override + public ServiceInstance deserialize(InputStream source) throws IOException { + InputStreamReader reader = new InputStreamReader(source, ENCODING); + try { + @Nullable ServiceInstanceSchema schema = gson.fromJson(reader, ServiceInstanceSchema.class); + if (schema == null) { + throw new IOException("JSON did not include a ServiceInstance object"); + } + return schema.asServiceInstance(); + } catch (JsonParseException e) { + throw new IOException("Problem parsing JSON ServiceInstance.", e); + } + } +} http://git-wip-us.apache.org/repos/asf/aurora/blob/b417be38/src/main/java/org/apache/aurora/scheduler/discovery/ServiceDiscoveryModule.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/discovery/ServiceDiscoveryModule.java b/src/main/java/org/apache/aurora/scheduler/discovery/ServiceDiscoveryModule.java index 07bce96..ef62f27 100644 --- a/src/main/java/org/apache/aurora/scheduler/discovery/ServiceDiscoveryModule.java +++ b/src/main/java/org/apache/aurora/scheduler/discovery/ServiceDiscoveryModule.java @@ -32,9 +32,8 @@ import com.google.inject.binder.LinkedBindingBuilder; import org.apache.aurora.common.application.ShutdownRegistry; import org.apache.aurora.common.base.MorePreconditions; -import org.apache.aurora.common.zookeeper.ZooKeeperUtils; -import org.apache.aurora.common.zookeeper.testing.ZooKeeperTestServer; import org.apache.aurora.scheduler.SchedulerServicesModule; +import org.apache.aurora.scheduler.discovery.testing.ZooKeeperTestServer; import org.apache.zookeeper.data.ACL; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,8 +52,8 @@ public class ServiceDiscoveryModule extends AbstractModule { /** * Creates a Guice module that will bind a - * {@link org.apache.aurora.common.zookeeper.SingletonService} for scheduler leader election and a - * {@link org.apache.aurora.scheduler.app.ServiceGroupMonitor} that can be used to find the + * {@link SingletonService} for scheduler leader election and a + * {@link ServiceGroupMonitor} that can be used to find the * leading scheduler. * * @param zooKeeperConfig The ZooKeeper client configuration to use to interact with ZooKeeper. http://git-wip-us.apache.org/repos/asf/aurora/blob/b417be38/src/main/java/org/apache/aurora/scheduler/discovery/ServiceGroupMonitor.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/discovery/ServiceGroupMonitor.java b/src/main/java/org/apache/aurora/scheduler/discovery/ServiceGroupMonitor.java new file mode 100644 index 0000000..fea896c --- /dev/null +++ b/src/main/java/org/apache/aurora/scheduler/discovery/ServiceGroupMonitor.java @@ -0,0 +1,46 @@ +/** + * 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.discovery; + +import java.io.Closeable; +import java.util.function.Supplier; + +import com.google.common.collect.ImmutableSet; + +import org.apache.aurora.common.thrift.ServiceInstance; + +/** + * Monitors a service group's membership and supplies a live view of the most recent set. + */ +public interface ServiceGroupMonitor extends Supplier<ImmutableSet<ServiceInstance>>, Closeable { + + /** + * Indicates a problem initiating monitoring of a service group. + */ + class MonitorException extends Exception { + MonitorException(String message, Throwable cause) { + super(message, cause); + } + } + + /** + * Starts monitoring the service group. + * + * When the service group membership no longer needs to be maintained, this monitor should be + * {@link #close() closed}. + * + * @throws MonitorException if there is a problem initiating monitoring of the service group. + */ + void start() throws MonitorException; +} http://git-wip-us.apache.org/repos/asf/aurora/blob/b417be38/src/main/java/org/apache/aurora/scheduler/discovery/SingletonService.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/discovery/SingletonService.java b/src/main/java/org/apache/aurora/scheduler/discovery/SingletonService.java new file mode 100644 index 0000000..adbc318 --- /dev/null +++ b/src/main/java/org/apache/aurora/scheduler/discovery/SingletonService.java @@ -0,0 +1,114 @@ +/** + * 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.discovery; + +import java.net.InetSocketAddress; +import java.util.Map; + +/** + * A service that uses master election to only allow a single service instance to be active amongst + * a set of potential servers at a time. + */ +public interface SingletonService { + + /** + * Indicates an error attempting to lead a group of servers. + */ + class LeadException extends Exception { + LeadException(String message, Throwable cause) { + super(message, cause); + } + } + + /** + * Indicates an error attempting to advertise leadership of a group of servers. + */ + class AdvertiseException extends Exception { + AdvertiseException(String message) { + super(message); + } + + AdvertiseException(String message, Throwable cause) { + super(message, cause); + } + } + + /** + * Indicates an error attempting to leave a group of servers, abdicating leadership of the group. + */ + class LeaveException extends Exception { + LeaveException(String message, Throwable cause) { + super(message, cause); + } + } + + /** + * Attempts to lead the singleton service. + * + * @param endpoint The primary endpoint to register as a leader candidate in the service. + * @param additionalEndpoints Additional endpoints that are available on the host. + * @param listener Handler to call when the candidate is elected or defeated. + * @throws LeadException If there was a problem joining or watching the ZooKeeper group. + * @throws InterruptedException If the thread watching/joining the group was interrupted. + */ + void lead( + InetSocketAddress endpoint, + Map<String, InetSocketAddress> additionalEndpoints, + LeadershipListener listener) + throws LeadException, InterruptedException; + + /** + * A listener to be notified of changes in the leadership status. + * Implementers should be careful to avoid blocking operations in these callbacks. + */ + interface LeadershipListener { + + /** + * Notifies the listener that is is current leader. + * + * @param control A controller handle to advertise and/or leave advertised presence. + */ + void onLeading(LeaderControl control); + + /** + * Notifies the listener that it is no longer leader. + */ + void onDefeated(); + } + + /** + * A controller for the state of the leader. This will be provided to the leader upon election, + * which allows the leader to decide when to advertise as leader of the server set and terminate + * leadership at will. + */ + interface LeaderControl { + + /** + * Advertises the leader's server presence to clients. + * + * @throws AdvertiseException If there was an error advertising the singleton leader to clients + * of the server set. + * @throws InterruptedException If interrupted while advertising. + */ + void advertise() throws AdvertiseException, InterruptedException; + + /** + * Leaves candidacy for leadership, removing advertised server presence if applicable. + * + * @throws LeaveException If the leader's status could not be updated or there was an error + * abdicating server set leadership. + */ + void leave() throws LeaveException; + } +} http://git-wip-us.apache.org/repos/asf/aurora/blob/b417be38/src/main/java/org/apache/aurora/scheduler/discovery/ZooKeeperConfig.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/discovery/ZooKeeperConfig.java b/src/main/java/org/apache/aurora/scheduler/discovery/ZooKeeperConfig.java index e1dc57e..acb7905 100644 --- a/src/main/java/org/apache/aurora/scheduler/discovery/ZooKeeperConfig.java +++ b/src/main/java/org/apache/aurora/scheduler/discovery/ZooKeeperConfig.java @@ -14,14 +14,11 @@ package org.apache.aurora.scheduler.discovery; import java.net.InetSocketAddress; - -import com.google.common.base.Optional; +import java.util.Optional; import org.apache.aurora.common.base.MorePreconditions; import org.apache.aurora.common.quantity.Amount; import org.apache.aurora.common.quantity.Time; -import org.apache.aurora.common.zookeeper.Credentials; -import org.apache.aurora.common.zookeeper.ZooKeeperUtils; import static java.util.Objects.requireNonNull; @@ -41,10 +38,10 @@ public class ZooKeeperConfig { public static ZooKeeperConfig create(Iterable<InetSocketAddress> servers) { return new ZooKeeperConfig( servers, - Optional.absent(), // chrootPath + Optional.empty(), // chrootPath false, ZooKeeperUtils.DEFAULT_ZK_SESSION_TIMEOUT, - Optional.absent()); // credentials + Optional.empty()); // credentials } private final Iterable<InetSocketAddress> servers; http://git-wip-us.apache.org/repos/asf/aurora/blob/b417be38/src/main/java/org/apache/aurora/scheduler/discovery/ZooKeeperUtils.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/discovery/ZooKeeperUtils.java b/src/main/java/org/apache/aurora/scheduler/discovery/ZooKeeperUtils.java new file mode 100644 index 0000000..211aa50 --- /dev/null +++ b/src/main/java/org/apache/aurora/scheduler/discovery/ZooKeeperUtils.java @@ -0,0 +1,51 @@ +/** + * 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.discovery; + +import com.google.common.collect.ImmutableList; + +import org.apache.aurora.common.quantity.Amount; +import org.apache.aurora.common.quantity.Time; +import org.apache.zookeeper.ZooDefs.Ids; +import org.apache.zookeeper.data.ACL; + +/** + * Utilities for dealing with ZooKeeper. + */ +final class ZooKeeperUtils { + + /** + * An appropriate default session timeout for ZooKeeper clusters. + */ + static final Amount<Integer, Time> DEFAULT_ZK_SESSION_TIMEOUT = Amount.of(4, Time.SECONDS); + + /** + * An ACL that gives all permissions any user authenticated or not. + */ + static final ImmutableList<ACL> OPEN_ACL_UNSAFE = + ImmutableList.copyOf(Ids.OPEN_ACL_UNSAFE); + + /** + * An ACL that gives all permissions to node creators and read permissions only to everyone else. + */ + static final ImmutableList<ACL> EVERYONE_READ_CREATOR_ALL = + ImmutableList.<ACL>builder() + .addAll(Ids.CREATOR_ALL_ACL) + .addAll(Ids.READ_ACL_UNSAFE) + .build(); + + private ZooKeeperUtils() { + // utility + } +} http://git-wip-us.apache.org/repos/asf/aurora/blob/b417be38/src/main/java/org/apache/aurora/scheduler/discovery/testing/BaseZooKeeperTest.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/discovery/testing/BaseZooKeeperTest.java b/src/main/java/org/apache/aurora/scheduler/discovery/testing/BaseZooKeeperTest.java new file mode 100644 index 0000000..d84037e --- /dev/null +++ b/src/main/java/org/apache/aurora/scheduler/discovery/testing/BaseZooKeeperTest.java @@ -0,0 +1,53 @@ +/** + * 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.discovery.testing; + +import org.apache.aurora.common.testing.TearDownTestCase; +import org.junit.Before; +import org.junit.Rule; +import org.junit.rules.TemporaryFolder; + +/** + * A base-class for in-process zookeeper tests. + */ +public abstract class BaseZooKeeperTest extends TearDownTestCase { + + private ZooKeeperTestServer zkTestServer; + + @Rule + public TemporaryFolder tmpFolder = new TemporaryFolder(); + + @Before + public final void setUp() throws Exception { + zkTestServer = new ZooKeeperTestServer(tmpFolder.newFolder(), tmpFolder.newFolder()); + addTearDown(zkTestServer::stop); + zkTestServer.startNetwork(); + } + + /** + * Returns the running in-process ZooKeeper server. + * + * @return The in-process ZooKeeper server. + */ + protected final ZooKeeperTestServer getServer() { + return zkTestServer; + } + + /** + * Returns the current port to connect to the in-process zookeeper instance. + */ + protected final int getPort() { + return getServer().getPort(); + } +} http://git-wip-us.apache.org/repos/asf/aurora/blob/b417be38/src/main/java/org/apache/aurora/scheduler/discovery/testing/ZooKeeperTestServer.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/discovery/testing/ZooKeeperTestServer.java b/src/main/java/org/apache/aurora/scheduler/discovery/testing/ZooKeeperTestServer.java new file mode 100644 index 0000000..a7bb48b --- /dev/null +++ b/src/main/java/org/apache/aurora/scheduler/discovery/testing/ZooKeeperTestServer.java @@ -0,0 +1,101 @@ +/** + * 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.discovery.testing; + +import java.io.File; +import java.io.IOException; +import java.net.InetSocketAddress; + +import com.google.common.base.Preconditions; + +import org.apache.zookeeper.server.NIOServerCnxnFactory; +import org.apache.zookeeper.server.ServerCnxnFactory; +import org.apache.zookeeper.server.ZooKeeperServer; +import org.apache.zookeeper.server.ZooKeeperServer.BasicDataTreeBuilder; +import org.apache.zookeeper.server.persistence.FileTxnSnapLog; + +/** + * A helper class for starting in-process ZooKeeper server and clients. + * + * <p>This is ONLY meant to be used for testing. + */ +public class ZooKeeperTestServer { + + private final File dataDir; + private final File snapDir; + + private ZooKeeperServer zooKeeperServer; + private ServerCnxnFactory connectionFactory; + private int port; + + public ZooKeeperTestServer(File dataDir, File snapDir) { + this.dataDir = Preconditions.checkNotNull(dataDir); + this.snapDir = Preconditions.checkNotNull(snapDir); + } + + /** + * Starts zookeeper up on an ephemeral port. + */ + public void startNetwork() throws IOException, InterruptedException { + zooKeeperServer = + new ZooKeeperServer( + new FileTxnSnapLog(dataDir, snapDir), + new BasicDataTreeBuilder()) { + + // TODO(John Sirois): Introduce a builder to configure the in-process server if and when + // some folks need JMX for in-process tests. + @Override protected void registerJMX() { + // noop + } + }; + + connectionFactory = new NIOServerCnxnFactory(); + connectionFactory.configure( + new InetSocketAddress(port), + 60 /* Semi-arbitrary, max 60 connections is the default used by NIOServerCnxnFactory */); + connectionFactory.startup(zooKeeperServer); + port = zooKeeperServer.getClientPort(); + } + + /** + * Stops the zookeeper server. + */ + public void stop() { + if (connectionFactory != null) { + connectionFactory.shutdown(); // Also shuts down zooKeeperServer. + connectionFactory = null; + } + } + + /** + * Expires the client session with the given {@code sessionId}. + * + * @param sessionId The id of the client session to expire. + */ + public final void expireClientSession(long sessionId) { + zooKeeperServer.closeSession(sessionId); + } + + /** + * Returns the current port to connect to the in-process zookeeper instance. + */ + public final int getPort() { + checkEphemeralPortAssigned(); + return port; + } + + private void checkEphemeralPortAssigned() { + Preconditions.checkState(port > 0, "startNetwork must be called first"); + } +} http://git-wip-us.apache.org/repos/asf/aurora/blob/b417be38/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 7bf8185..84f7ef3 100644 --- a/src/main/java/org/apache/aurora/scheduler/http/JettyServerModule.java +++ b/src/main/java/org/apache/aurora/scheduler/http/JettyServerModule.java @@ -65,7 +65,7 @@ import org.apache.aurora.common.net.http.handlers.TimeSeriesDataSource; import org.apache.aurora.common.net.http.handlers.VarsHandler; import org.apache.aurora.common.net.http.handlers.VarsJsonHandler; import org.apache.aurora.scheduler.SchedulerServicesModule; -import org.apache.aurora.scheduler.app.ServiceGroupMonitor.MonitorException; +import org.apache.aurora.scheduler.discovery.ServiceGroupMonitor.MonitorException; import org.apache.aurora.scheduler.http.api.ApiModule; import org.apache.aurora.scheduler.http.api.security.HttpSecurityModule; import org.apache.aurora.scheduler.thrift.ThriftModule; http://git-wip-us.apache.org/repos/asf/aurora/blob/b417be38/src/main/java/org/apache/aurora/scheduler/http/LeaderRedirect.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/http/LeaderRedirect.java b/src/main/java/org/apache/aurora/scheduler/http/LeaderRedirect.java index 9bf6f52..0077911 100644 --- a/src/main/java/org/apache/aurora/scheduler/http/LeaderRedirect.java +++ b/src/main/java/org/apache/aurora/scheduler/http/LeaderRedirect.java @@ -27,8 +27,8 @@ import com.google.common.net.HostAndPort; import org.apache.aurora.common.thrift.Endpoint; import org.apache.aurora.common.thrift.ServiceInstance; -import org.apache.aurora.scheduler.app.ServiceGroupMonitor; -import org.apache.aurora.scheduler.app.ServiceGroupMonitor.MonitorException; +import org.apache.aurora.scheduler.discovery.ServiceGroupMonitor; +import org.apache.aurora.scheduler.discovery.ServiceGroupMonitor.MonitorException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; http://git-wip-us.apache.org/repos/asf/aurora/blob/b417be38/src/main/java/org/apache/aurora/scheduler/log/mesos/MesosLogStreamModule.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/log/mesos/MesosLogStreamModule.java b/src/main/java/org/apache/aurora/scheduler/log/mesos/MesosLogStreamModule.java index 6704a32..c7c0387 100644 --- a/src/main/java/org/apache/aurora/scheduler/log/mesos/MesosLogStreamModule.java +++ b/src/main/java/org/apache/aurora/scheduler/log/mesos/MesosLogStreamModule.java @@ -33,8 +33,8 @@ import org.apache.aurora.common.args.CmdLine; import org.apache.aurora.common.net.InetSocketAddressHelper; import org.apache.aurora.common.quantity.Amount; import org.apache.aurora.common.quantity.Time; -import org.apache.aurora.common.zookeeper.Credentials; import org.apache.aurora.gen.storage.LogEntry; +import org.apache.aurora.scheduler.discovery.Credentials; import org.apache.aurora.scheduler.discovery.ZooKeeperConfig; import org.apache.aurora.scheduler.log.mesos.LogInterface.ReaderInterface; import org.apache.aurora.scheduler.log.mesos.LogInterface.WriterInterface; @@ -157,7 +157,7 @@ public class MesosLogStreamModule extends PrivateModule { zkClientConfig.getSessionTimeout().getUnit().getTimeUnit(), zkLogGroupPath, zkCredentials.scheme(), - zkCredentials.authToken()); + zkCredentials.token()); } else { return new Log( QUORUM_SIZE.get(), http://git-wip-us.apache.org/repos/asf/aurora/blob/b417be38/src/test/java/org/apache/aurora/scheduler/SchedulerLifecycleTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/aurora/scheduler/SchedulerLifecycleTest.java b/src/test/java/org/apache/aurora/scheduler/SchedulerLifecycleTest.java index 051c520..4324ea9 100644 --- a/src/test/java/org/apache/aurora/scheduler/SchedulerLifecycleTest.java +++ b/src/test/java/org/apache/aurora/scheduler/SchedulerLifecycleTest.java @@ -21,9 +21,9 @@ import org.apache.aurora.common.application.ShutdownRegistry; import org.apache.aurora.common.base.Command; import org.apache.aurora.common.base.ExceptionalCommand; import org.apache.aurora.common.testing.easymock.EasyMockTest; -import org.apache.aurora.common.zookeeper.SingletonService.LeaderControl; -import org.apache.aurora.common.zookeeper.SingletonService.LeadershipListener; import org.apache.aurora.scheduler.SchedulerLifecycle.DelayedActions; +import org.apache.aurora.scheduler.discovery.SingletonService.LeaderControl; +import org.apache.aurora.scheduler.discovery.SingletonService.LeadershipListener; import org.apache.aurora.scheduler.events.PubsubEvent.DriverRegistered; import org.apache.aurora.scheduler.mesos.Driver; import org.apache.aurora.scheduler.storage.Storage.StorageException; http://git-wip-us.apache.org/repos/asf/aurora/blob/b417be38/src/test/java/org/apache/aurora/scheduler/app/SchedulerIT.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/aurora/scheduler/app/SchedulerIT.java b/src/test/java/org/apache/aurora/scheduler/app/SchedulerIT.java index 1eabb89..84d7753 100644 --- a/src/test/java/org/apache/aurora/scheduler/app/SchedulerIT.java +++ b/src/test/java/org/apache/aurora/scheduler/app/SchedulerIT.java @@ -44,8 +44,6 @@ import org.apache.aurora.GuavaUtils; import org.apache.aurora.codec.ThriftBinaryCodec.CodingException; import org.apache.aurora.common.application.Lifecycle; import org.apache.aurora.common.stats.Stats; -import org.apache.aurora.common.zookeeper.Credentials; -import org.apache.aurora.common.zookeeper.testing.BaseZooKeeperClientTest; import org.apache.aurora.gen.HostAttributes; import org.apache.aurora.gen.MaintenanceMode; import org.apache.aurora.gen.ScheduleStatus; @@ -62,8 +60,11 @@ import org.apache.aurora.scheduler.AppStartup; import org.apache.aurora.scheduler.TierModule; import org.apache.aurora.scheduler.base.TaskTestUtil; import org.apache.aurora.scheduler.configuration.executor.ExecutorSettings; +import org.apache.aurora.scheduler.discovery.Credentials; import org.apache.aurora.scheduler.discovery.ServiceDiscoveryModule; +import org.apache.aurora.scheduler.discovery.ServiceGroupMonitor; import org.apache.aurora.scheduler.discovery.ZooKeeperConfig; +import org.apache.aurora.scheduler.discovery.testing.BaseZooKeeperTest; import org.apache.aurora.scheduler.log.Log; import org.apache.aurora.scheduler.log.Log.Entry; import org.apache.aurora.scheduler.log.Log.Position; @@ -108,7 +109,7 @@ import static org.easymock.EasyMock.expect; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; -public class SchedulerIT extends BaseZooKeeperClientTest { +public class SchedulerIT extends BaseZooKeeperTest { private static final Logger LOG = LoggerFactory.getLogger(SchedulerIT.class); http://git-wip-us.apache.org/repos/asf/aurora/blob/b417be38/src/test/java/org/apache/aurora/scheduler/discovery/BaseCuratorDiscoveryTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/aurora/scheduler/discovery/BaseCuratorDiscoveryTest.java b/src/test/java/org/apache/aurora/scheduler/discovery/BaseCuratorDiscoveryTest.java index eb8c114..9f86add 100644 --- a/src/test/java/org/apache/aurora/scheduler/discovery/BaseCuratorDiscoveryTest.java +++ b/src/test/java/org/apache/aurora/scheduler/discovery/BaseCuratorDiscoveryTest.java @@ -24,9 +24,7 @@ import com.google.common.collect.ImmutableMap; import org.apache.aurora.common.thrift.Endpoint; import org.apache.aurora.common.thrift.ServiceInstance; import org.apache.aurora.common.thrift.Status; -import org.apache.aurora.common.zookeeper.JsonCodec; -import org.apache.aurora.common.zookeeper.testing.BaseZooKeeperTest; -import org.apache.aurora.scheduler.app.ServiceGroupMonitor; +import org.apache.aurora.scheduler.discovery.testing.BaseZooKeeperTest; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.framework.recipes.cache.PathChildrenCache; http://git-wip-us.apache.org/repos/asf/aurora/blob/b417be38/src/test/java/org/apache/aurora/scheduler/discovery/CuratorDiscoveryModuleTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/aurora/scheduler/discovery/CuratorDiscoveryModuleTest.java b/src/test/java/org/apache/aurora/scheduler/discovery/CuratorDiscoveryModuleTest.java index ea4570a..4ebda5e 100644 --- a/src/test/java/org/apache/aurora/scheduler/discovery/CuratorDiscoveryModuleTest.java +++ b/src/test/java/org/apache/aurora/scheduler/discovery/CuratorDiscoveryModuleTest.java @@ -14,8 +14,8 @@ package org.apache.aurora.scheduler.discovery; import java.net.InetSocketAddress; +import java.util.Optional; -import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; import com.google.inject.AbstractModule; import com.google.inject.Guice; @@ -26,10 +26,6 @@ import org.apache.aurora.common.application.ShutdownRegistry.ShutdownRegistryImp import org.apache.aurora.common.quantity.Amount; import org.apache.aurora.common.quantity.Time; import org.apache.aurora.common.testing.TearDownTestCase; -import org.apache.aurora.common.zookeeper.Credentials; -import org.apache.aurora.common.zookeeper.SingletonService; -import org.apache.aurora.common.zookeeper.ZooKeeperUtils; -import org.apache.aurora.scheduler.app.ServiceGroupMonitor; import org.apache.curator.framework.api.ACLProvider; import org.apache.zookeeper.data.ACL; import org.junit.Test; http://git-wip-us.apache.org/repos/asf/aurora/blob/b417be38/src/test/java/org/apache/aurora/scheduler/discovery/CuratorSingletonServiceTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/aurora/scheduler/discovery/CuratorSingletonServiceTest.java b/src/test/java/org/apache/aurora/scheduler/discovery/CuratorSingletonServiceTest.java index a860ede..bb3d080 100644 --- a/src/test/java/org/apache/aurora/scheduler/discovery/CuratorSingletonServiceTest.java +++ b/src/test/java/org/apache/aurora/scheduler/discovery/CuratorSingletonServiceTest.java @@ -19,8 +19,6 @@ import java.util.concurrent.CountDownLatch; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; -import org.apache.aurora.common.zookeeper.JsonCodec; -import org.apache.aurora.common.zookeeper.SingletonService; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent; import org.easymock.Capture; http://git-wip-us.apache.org/repos/asf/aurora/blob/b417be38/src/test/java/org/apache/aurora/scheduler/discovery/JsonCodecTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/aurora/scheduler/discovery/JsonCodecTest.java b/src/test/java/org/apache/aurora/scheduler/discovery/JsonCodecTest.java new file mode 100644 index 0000000..b88ba37 --- /dev/null +++ b/src/test/java/org/apache/aurora/scheduler/discovery/JsonCodecTest.java @@ -0,0 +1,159 @@ +/** + * 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.discovery; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import com.google.common.base.Charsets; +import com.google.common.collect.ImmutableMap; +import com.google.gson.Gson; +import com.google.gson.JsonIOException; + +import org.apache.aurora.common.thrift.Endpoint; +import org.apache.aurora.common.thrift.ServiceInstance; +import org.apache.aurora.common.thrift.Status; +import org.easymock.EasyMock; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.api.easymock.PowerMock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(Gson.class) +public class JsonCodecTest { + + private static byte[] serializeServiceInstance(ServiceInstance serviceInstance) + throws IOException { + + ByteArrayOutputStream output = new ByteArrayOutputStream(); + JsonCodec.INSTANCE.serialize(serviceInstance, output); + return output.toByteArray(); + } + + private static ServiceInstance deserializeServiceInstance(byte[] data) throws IOException { + return JsonCodec.INSTANCE.deserialize(new ByteArrayInputStream(data)); + } + + @Test + public void testJsonCodecRoundtrip() throws Exception { + ServiceInstance instance1 = new ServiceInstance( + new Endpoint("foo", 1000), + ImmutableMap.of("http", new Endpoint("foo", 8080)), + Status.ALIVE) + .setShard(0); + byte[] data = serializeServiceInstance(instance1); + assertTrue(deserializeServiceInstance(data).getServiceEndpoint().isSetPort()); + assertTrue(deserializeServiceInstance(data).isSetShard()); + + ServiceInstance instance2 = new ServiceInstance( + new Endpoint("foo", 1000), + ImmutableMap.of("http-admin1", new Endpoint("foo", 8080)), + Status.ALIVE); + data = serializeServiceInstance(instance2); + assertTrue(deserializeServiceInstance(data).getServiceEndpoint().isSetPort()); + assertFalse(deserializeServiceInstance(data).isSetShard()); + + ServiceInstance instance3 = new ServiceInstance( + new Endpoint("foo", 1000), + ImmutableMap.of(), + Status.ALIVE); + data = serializeServiceInstance(instance3); + assertTrue(deserializeServiceInstance(data).getServiceEndpoint().isSetPort()); + assertFalse(deserializeServiceInstance(data).isSetShard()); + } + + @Test + public void testJsonCompatibility() throws IOException { + ServiceInstance instance = new ServiceInstance( + new Endpoint("foo", 1000), + ImmutableMap.of("http", new Endpoint("foo", 8080)), + Status.ALIVE).setShard(42); + + ByteArrayOutputStream results = new ByteArrayOutputStream(); + JsonCodec.INSTANCE.serialize(instance, results); + assertEquals( + "{\"serviceEndpoint\":{\"host\":\"foo\",\"port\":1000}," + + "\"additionalEndpoints\":{\"http\":{\"host\":\"foo\",\"port\":8080}}," + + "\"status\":\"ALIVE\"," + + "\"shard\":42}", + results.toString(Charsets.UTF_8.name())); + } + + @Test + public void testInvalidSerialize() { + // Gson is final so we need to call on PowerMock here. + Gson gson = PowerMock.createMock(Gson.class); + gson.toJson(EasyMock.isA(Object.class), EasyMock.isA(Appendable.class)); + EasyMock.expectLastCall().andThrow(new JsonIOException("error")); + PowerMock.replay(gson); + + ServiceInstance instance = + new ServiceInstance(new Endpoint("foo", 1000), ImmutableMap.of(), Status.ALIVE); + + try { + new JsonCodec(gson).serialize(instance, new ByteArrayOutputStream()); + fail(); + } catch (IOException e) { + // Expected. + } + + PowerMock.verify(gson); + } + + @Test + public void testDeserializeMinimal() throws IOException { + String minimal = "{\"serviceEndpoint\":{\"host\":\"foo\",\"port\":1000},\"status\":\"ALIVE\"}"; + ByteArrayInputStream source = new ByteArrayInputStream(minimal.getBytes(Charsets.UTF_8)); + ServiceInstance actual = JsonCodec.INSTANCE.deserialize(source); + ServiceInstance expected = + new ServiceInstance(new Endpoint("foo", 1000), ImmutableMap.of(), Status.ALIVE); + assertEquals(expected, actual); + } + + @Test + public void testInvalidDeserialize() { + // Not JSON. + assertInvalidDeserialize(new byte[] {0xC, 0xA, 0xF, 0xE}); + + // No JSON object. + assertInvalidDeserialize(""); + assertInvalidDeserialize("[]"); + + // Missing required fields. + assertInvalidDeserialize("{}"); + assertInvalidDeserialize("{\"serviceEndpoint\":{\"host\":\"foo\",\"port\":1000}}"); + assertInvalidDeserialize("{\"status\":\"ALIVE\"}"); + } + + private void assertInvalidDeserialize(String data) { + assertInvalidDeserialize(data.getBytes(Charsets.UTF_8)); + } + + private void assertInvalidDeserialize(byte[] data) { + try { + JsonCodec.INSTANCE.deserialize(new ByteArrayInputStream(data)); + fail(); + } catch (IOException e) { + // Expected. + } + } +} http://git-wip-us.apache.org/repos/asf/aurora/blob/b417be38/src/test/java/org/apache/aurora/scheduler/discovery/ZooKeeperConfigTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/aurora/scheduler/discovery/ZooKeeperConfigTest.java b/src/test/java/org/apache/aurora/scheduler/discovery/ZooKeeperConfigTest.java index d45dbb5..4d833f2 100644 --- a/src/test/java/org/apache/aurora/scheduler/discovery/ZooKeeperConfigTest.java +++ b/src/test/java/org/apache/aurora/scheduler/discovery/ZooKeeperConfigTest.java @@ -14,14 +14,12 @@ package org.apache.aurora.scheduler.discovery; import java.net.InetSocketAddress; +import java.util.Optional; -import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; import org.apache.aurora.common.quantity.Amount; import org.apache.aurora.common.quantity.Time; -import org.apache.aurora.common.zookeeper.Credentials; -import org.apache.aurora.common.zookeeper.ZooKeeperUtils; import org.junit.Test; import static org.junit.Assert.assertEquals; @@ -38,10 +36,10 @@ public class ZooKeeperConfigTest { public void testEmptyServers() { new ZooKeeperConfig( ImmutableList.of(), - Optional.absent(), + Optional.empty(), false, Amount.of(1, Time.DAYS), - Optional.absent()); + Optional.empty()); } @Test @@ -49,10 +47,10 @@ public class ZooKeeperConfigTest { ZooKeeperConfig config = new ZooKeeperConfig( SERVERS, - Optional.absent(), + Optional.empty(), false, Amount.of(1, Time.HOURS), - Optional.absent()); // credentials + Optional.empty()); // credentials assertFalse(config.getCredentials().isPresent()); Credentials joeCreds = Credentials.digestCredentials("Joe", "Schmoe"); http://git-wip-us.apache.org/repos/asf/aurora/blob/b417be38/src/test/java/org/apache/aurora/scheduler/http/AbstractJettyTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/aurora/scheduler/http/AbstractJettyTest.java b/src/test/java/org/apache/aurora/scheduler/http/AbstractJettyTest.java index fb03f25..d9e7374 100644 --- a/src/test/java/org/apache/aurora/scheduler/http/AbstractJettyTest.java +++ b/src/test/java/org/apache/aurora/scheduler/http/AbstractJettyTest.java @@ -48,9 +48,9 @@ import org.apache.aurora.scheduler.AppStartup; import org.apache.aurora.scheduler.SchedulerServicesModule; import org.apache.aurora.scheduler.TierManager; import org.apache.aurora.scheduler.app.LifecycleModule; -import org.apache.aurora.scheduler.app.ServiceGroupMonitor; import org.apache.aurora.scheduler.async.AsyncModule; import org.apache.aurora.scheduler.cron.CronJobManager; +import org.apache.aurora.scheduler.discovery.ServiceGroupMonitor; import org.apache.aurora.scheduler.http.api.GsonMessageBodyHandler; import org.apache.aurora.scheduler.offers.OfferManager; import org.apache.aurora.scheduler.scheduling.RescheduleCalculator; @@ -132,9 +132,8 @@ public abstract class AbstractJettyTest extends EasyMockTest { bindMock(Thread.UncaughtExceptionHandler.class); bindMock(TaskGroups.TaskGroupBatchWorker.class); - bind(ServletContextListener.class).toProvider(() -> { - return makeServletContextListener(injector, getChildServletModule()); - }); + bind(ServletContextListener.class) + .toProvider(() -> makeServletContextListener(injector, getChildServletModule())); } }, new JettyServerModule(false)); @@ -147,12 +146,12 @@ public abstract class AbstractJettyTest extends EasyMockTest { expect(serviceGroupMonitor.get()).andAnswer(schedulers::get).anyTimes(); } - protected void setLeadingScheduler(String host, int port) { + void setLeadingScheduler(String host, int port) { schedulers.set( ImmutableSet.of(new ServiceInstance().setServiceEndpoint(new Endpoint(host, port)))); } - protected void unsetLeadingSchduler() { + void unsetLeadingSchduler() { schedulers.set(ImmutableSet.of()); } @@ -162,9 +161,7 @@ public abstract class AbstractJettyTest extends EasyMockTest { ServiceManagerIface service = injector.getInstance(Key.get(ServiceManagerIface.class, AppStartup.class)); service.startAsync().awaitHealthy(); - addTearDown(() -> { - service.stopAsync().awaitStopped(5L, TimeUnit.SECONDS); - }); + addTearDown(() -> service.stopAsync().awaitStopped(5L, TimeUnit.SECONDS)); } catch (Exception e) { throw Throwables.propagate(e); } http://git-wip-us.apache.org/repos/asf/aurora/blob/b417be38/src/test/java/org/apache/aurora/scheduler/http/LeaderRedirectTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/aurora/scheduler/http/LeaderRedirectTest.java b/src/test/java/org/apache/aurora/scheduler/http/LeaderRedirectTest.java index a16058f..a308ba2 100644 --- a/src/test/java/org/apache/aurora/scheduler/http/LeaderRedirectTest.java +++ b/src/test/java/org/apache/aurora/scheduler/http/LeaderRedirectTest.java @@ -27,8 +27,8 @@ import com.google.common.net.HostAndPort; import org.apache.aurora.common.testing.easymock.EasyMockTest; import org.apache.aurora.common.thrift.Endpoint; import org.apache.aurora.common.thrift.ServiceInstance; -import org.apache.aurora.scheduler.app.ServiceGroupMonitor; -import org.apache.aurora.scheduler.app.ServiceGroupMonitor.MonitorException; +import org.apache.aurora.scheduler.discovery.ServiceGroupMonitor; +import org.apache.aurora.scheduler.discovery.ServiceGroupMonitor.MonitorException; import org.junit.Before; import org.junit.Test; http://git-wip-us.apache.org/repos/asf/aurora/blob/b417be38/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 3caad32..e578f5a 100644 --- a/src/test/java/org/apache/aurora/scheduler/thrift/ThriftIT.java +++ b/src/test/java/org/apache/aurora/scheduler/thrift/ThriftIT.java @@ -42,12 +42,12 @@ import org.apache.aurora.gen.TaskQuery; import org.apache.aurora.scheduler.TierModule; import org.apache.aurora.scheduler.app.AppModule; import org.apache.aurora.scheduler.app.LifecycleModule; -import org.apache.aurora.scheduler.app.ServiceGroupMonitor; import org.apache.aurora.scheduler.app.local.FakeNonVolatileStorage; import org.apache.aurora.scheduler.base.TaskTestUtil; import org.apache.aurora.scheduler.configuration.ConfigurationManager.ConfigurationManagerSettings; import org.apache.aurora.scheduler.configuration.executor.ExecutorSettings; import org.apache.aurora.scheduler.cron.quartz.CronModule; +import org.apache.aurora.scheduler.discovery.ServiceGroupMonitor; import org.apache.aurora.scheduler.mesos.DriverFactory; import org.apache.aurora.scheduler.mesos.DriverSettings; import org.apache.aurora.scheduler.mesos.TestExecutorSettings;
