Repository: aurora Updated Branches: refs/heads/master de046f757 -> 02ffef5de
Centralize ZooKeeper configuration in discovery. This moves `ZooKeeperClient` configuration to the discovery package and factors `ZooKeeperConfig` up out of the `ZooKeeperClientModule` for re-use as ZooKeeper config data by Curator. Bugs closed: AURORA-1468 Reviewed at https://reviews.apache.org/r/46171/ Project: http://git-wip-us.apache.org/repos/asf/aurora/repo Commit: http://git-wip-us.apache.org/repos/asf/aurora/commit/02ffef5d Tree: http://git-wip-us.apache.org/repos/asf/aurora/tree/02ffef5d Diff: http://git-wip-us.apache.org/repos/asf/aurora/diff/02ffef5d Branch: refs/heads/master Commit: 02ffef5de3e33f420039dbc50a960c004d9155e0 Parents: de046f7 Author: John Sirois <[email protected]> Authored: Fri Apr 15 12:37:12 2016 -0600 Committer: John Sirois <[email protected]> Committed: Fri Apr 15 12:37:12 2016 -0600 ---------------------------------------------------------------------- config/legacy_untested_classes.txt | 14 +- .../aurora/scheduler/app/SchedulerMain.java | 10 +- .../discovery/FlaggedZooKeeperConfig.java | 88 ++++++++ .../discovery/ZooKeeperClientModule.java | 144 +++++++++++++ .../scheduler/discovery/ZooKeeperConfig.java | 94 ++++++++ .../log/mesos/MesosLogStreamModule.java | 12 +- .../guice/client/ZooKeeperClientModule.java | 214 ------------------- .../client/flagged/FlaggedClientConfig.java | 88 -------- .../aurora/scheduler/app/SchedulerIT.java | 6 +- .../discovery/ZooKeeperConfigTest.java | 79 +++++++ 10 files changed, 428 insertions(+), 321 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/aurora/blob/02ffef5d/config/legacy_untested_classes.txt ---------------------------------------------------------------------- diff --git a/config/legacy_untested_classes.txt b/config/legacy_untested_classes.txt index 00e1666..30875da 100644 --- a/config/legacy_untested_classes.txt +++ b/config/legacy_untested_classes.txt @@ -1,9 +1,9 @@ -org/apache/aurora/Protobufs$1 org/apache/aurora/auth/CapabilityValidator$AuditCheck org/apache/aurora/auth/UnsecureAuthModule$UnsecureCapabilityValidator org/apache/aurora/auth/UnsecureAuthModule$UnsecureCapabilityValidator$1 org/apache/aurora/auth/UnsecureAuthModule$UnsecureCapabilityValidator$2 org/apache/aurora/auth/UnsecureAuthModule$UnsecureSessionValidator +org/apache/aurora/Protobufs$1 org/apache/aurora/scheduler/app/SchedulerMain$1 org/apache/aurora/scheduler/app/SchedulerMain$2 org/apache/aurora/scheduler/app/SchedulerMain$2$1 @@ -15,7 +15,12 @@ org/apache/aurora/scheduler/base/Conversions$3 org/apache/aurora/scheduler/configuration/executor/ExecutorModule$1 org/apache/aurora/scheduler/cron/quartz/CronSchedulerImpl org/apache/aurora/scheduler/cron/quartz/CronSchedulerImpl$1 +org/apache/aurora/scheduler/discovery/FlaggedZooKeeperConfig +org/apache/aurora/scheduler/discovery/ZooKeeperClientModule$1 +org/apache/aurora/scheduler/discovery/ZooKeeperClientModule$LocalClientProvider +org/apache/aurora/scheduler/discovery/ZooKeeperClientModule$TestServerService org/apache/aurora/scheduler/http/AbortCallback +org/apache/aurora/scheduler/http/api/security/Kerberos5Realm org/apache/aurora/scheduler/http/JerseyTemplateServlet org/apache/aurora/scheduler/http/LogConfig org/apache/aurora/scheduler/http/LogConfig$LoggerConfig @@ -49,7 +54,6 @@ org/apache/aurora/scheduler/http/Utilization$4 org/apache/aurora/scheduler/http/Utilization$5 org/apache/aurora/scheduler/http/Utilization$Display org/apache/aurora/scheduler/http/Utilization$DisplayMetric -org/apache/aurora/scheduler/http/api/security/Kerberos5Realm org/apache/aurora/scheduler/log/mesos/MesosLogStreamModule org/apache/aurora/scheduler/log/mesos/MesosLogStreamModule$3 org/apache/aurora/scheduler/log/mesos/MesosLogStreamModule$4 @@ -58,14 +62,10 @@ org/apache/aurora/scheduler/mesos/DriverFactoryImpl org/apache/aurora/scheduler/mesos/LibMesosLoadingModule org/apache/aurora/scheduler/stats/AsyncStatsModule$OfferAdapter$1 org/apache/aurora/scheduler/stats/TaskStatCalculator -org/apache/aurora/scheduler/storage/CallOrderEnforcingStorage$State org/apache/aurora/scheduler/storage/backup/BackupModule$LifecycleHook +org/apache/aurora/scheduler/storage/CallOrderEnforcingStorage$State org/apache/aurora/scheduler/storage/mem/MemTaskStore$Task org/apache/aurora/scheduler/storage/mem/Util org/apache/aurora/scheduler/storage/mem/Util$1 org/apache/aurora/scheduler/testing/FakeStatsProvider$1 org/apache/aurora/scheduler/testing/FakeStatsProvider$3 -org/apache/aurora/scheduler/zookeeper/guice/client/ZooKeeperClientModule$1 -org/apache/aurora/scheduler/zookeeper/guice/client/ZooKeeperClientModule$LocalClientProvider -org/apache/aurora/scheduler/zookeeper/guice/client/ZooKeeperClientModule$TestServerService -org/apache/aurora/scheduler/zookeeper/guice/client/flagged/FlaggedClientConfig http://git-wip-us.apache.org/repos/asf/aurora/blob/02ffef5d/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 6c7ae7e..25e1312 100644 --- a/src/main/java/org/apache/aurora/scheduler/app/SchedulerMain.java +++ b/src/main/java/org/apache/aurora/scheduler/app/SchedulerMain.java @@ -50,7 +50,10 @@ import org.apache.aurora.scheduler.SchedulerLifecycle; import org.apache.aurora.scheduler.TierModule; import org.apache.aurora.scheduler.configuration.executor.ExecutorModule; import org.apache.aurora.scheduler.cron.quartz.CronModule; +import org.apache.aurora.scheduler.discovery.FlaggedZooKeeperConfig; import org.apache.aurora.scheduler.discovery.ServiceDiscoveryModule; +import org.apache.aurora.scheduler.discovery.ZooKeeperClientModule; +import org.apache.aurora.scheduler.discovery.ZooKeeperConfig; import org.apache.aurora.scheduler.http.HttpService; import org.apache.aurora.scheduler.log.mesos.MesosLogStreamModule; import org.apache.aurora.scheduler.mesos.CommandLineDriverSettingsModule; @@ -62,9 +65,6 @@ import org.apache.aurora.scheduler.storage.db.DbModule; import org.apache.aurora.scheduler.storage.entities.IServerInfo; import org.apache.aurora.scheduler.storage.log.LogStorageModule; import org.apache.aurora.scheduler.storage.log.SnapshotStoreImpl; -import org.apache.aurora.scheduler.zookeeper.guice.client.ZooKeeperClientModule; -import org.apache.aurora.scheduler.zookeeper.guice.client.ZooKeeperClientModule.ClientConfig; -import org.apache.aurora.scheduler.zookeeper.guice.client.flagged.FlaggedClientConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -156,7 +156,7 @@ public class SchedulerMain { LOG.error("Uncaught exception from " + t + ":" + e, e); }); - ClientConfig zkClientConfig = FlaggedClientConfig.create(); + ZooKeeperConfig zkClientConfig = FlaggedZooKeeperConfig.create(); Module module = Modules.combine( appEnvironmentModule, getUniversalModule(), @@ -200,7 +200,7 @@ public class SchedulerMain { .add( new CommandLineDriverSettingsModule(), new LibMesosLoadingModule(), - new MesosLogStreamModule(FlaggedClientConfig.create()), + new MesosLogStreamModule(FlaggedZooKeeperConfig.create()), new LogStorageModule(), new TierModule()) .build(); http://git-wip-us.apache.org/repos/asf/aurora/blob/02ffef5d/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 new file mode 100644 index 0000000..c3a524f --- /dev/null +++ b/src/main/java/org/apache/aurora/scheduler/discovery/FlaggedZooKeeperConfig.java @@ -0,0 +1,88 @@ +/** + * 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.List; + +import javax.annotation.Nullable; + +import com.google.common.base.Optional; +import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableList; + +import org.apache.aurora.common.args.Arg; +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 + * values. + */ +public final class FlaggedZooKeeperConfig { + @CmdLine(name = "zk_in_proc", + help = "Launches an embedded zookeeper server for local testing causing -zk_endpoints " + + "to be ignored if specified.") + private static final Arg<Boolean> IN_PROCESS = Arg.create(false); + + @NotEmpty + @CmdLine(name = "zk_endpoints", help = "Endpoint specification for the ZooKeeper servers.") + private static final Arg<List<InetSocketAddress>> ZK_ENDPOINTS = Arg.create(); + + @CmdLine(name = "zk_chroot_path", help = "chroot path to use for the ZooKeeper connections") + private static final Arg<String> CHROOT_PATH = Arg.create(null); + + @CmdLine(name = "zk_session_timeout", help = "The ZooKeeper session timeout.") + private static final Arg<Amount<Integer, Time>> SESSION_TIMEOUT = + Arg.create(ZooKeeperUtils.DEFAULT_ZK_SESSION_TIMEOUT); + + @CmdLine(name = "zk_digest_credentials", + help = "user:password to use when authenticating with ZooKeeper.") + private static final Arg<String> DIGEST_CREDENTIALS = Arg.create(null); + + private FlaggedZooKeeperConfig() { + // Utility class. + } + + /** + * Creates a configuration from command line arguments. + * + * @return Configuration instance. + */ + public static ZooKeeperConfig create() { + return new ZooKeeperConfig( + ZK_ENDPOINTS.get(), + Optional.fromNullable(CHROOT_PATH.get()), + IN_PROCESS.get(), + SESSION_TIMEOUT.get(), + getCredentials(DIGEST_CREDENTIALS.get())); + } + + private static Optional<Credentials> getCredentials(@Nullable String userAndPass) { + if (userAndPass == null) { + return Optional.absent(); + } + + List<String> parts = ImmutableList.copyOf(Splitter.on(":").split(userAndPass)); + if (parts.size() != 2) { + throw new IllegalArgumentException( + "zk_digest_credentials must be formatted as user:pass"); + } + return Optional.of(Credentials.digestCredentials(parts.get(0), parts.get(1))); + } +} http://git-wip-us.apache.org/repos/asf/aurora/blob/02ffef5d/src/main/java/org/apache/aurora/scheduler/discovery/ZooKeeperClientModule.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/discovery/ZooKeeperClientModule.java b/src/main/java/org/apache/aurora/scheduler/discovery/ZooKeeperClientModule.java new file mode 100644 index 0000000..c0f2061 --- /dev/null +++ b/src/main/java/org/apache/aurora/scheduler/discovery/ZooKeeperClientModule.java @@ -0,0 +1,144 @@ +/** + * 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.File; +import java.io.IOException; +import java.net.InetSocketAddress; + +import com.google.common.base.Optional; +import com.google.common.base.Throwables; +import com.google.common.collect.ImmutableList; +import com.google.common.io.Files; +import com.google.common.util.concurrent.AbstractIdleService; +import com.google.inject.AbstractModule; +import com.google.inject.Inject; +import com.google.inject.Key; +import com.google.inject.PrivateModule; +import com.google.inject.Provider; +import com.google.inject.Singleton; + +import org.apache.aurora.common.application.ShutdownRegistry; +import org.apache.aurora.common.inject.Bindings.KeyFactory; +import org.apache.aurora.common.zookeeper.ZooKeeperClient; +import org.apache.aurora.common.zookeeper.testing.ZooKeeperTestServer; +import org.apache.aurora.scheduler.SchedulerServicesModule; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * A guice binding module that configures and binds a {@link ZooKeeperClient} instance. + */ +public class ZooKeeperClientModule extends AbstractModule { + private final KeyFactory keyFactory; + private final ZooKeeperConfig config; + + /** + * Creates a new ZK client module from the provided configuration. + * + * @param config Configuration parameters for the client. + */ + public ZooKeeperClientModule(ZooKeeperConfig config) { + this(KeyFactory.PLAIN, config); + } + + /** + * Creates a new ZK client module from the provided configuration, using a key factory to + * qualify any bindings. + * + * @param keyFactory Factory to use when creating any exposed bindings. + * @param config Configuration parameters for the client. + */ + public ZooKeeperClientModule(KeyFactory keyFactory, ZooKeeperConfig config) { + this.keyFactory = checkNotNull(keyFactory); + this.config = checkNotNull(config); + } + + @Override + protected void configure() { + Key<ZooKeeperClient> clientKey = keyFactory.create(ZooKeeperClient.class); + if (config.inProcess) { + File tempDir = Files.createTempDir(); + bind(ZooKeeperTestServer.class).toInstance(new ZooKeeperTestServer(tempDir, tempDir)); + + install(new PrivateModule() { + @Override + protected void configure() { + requireBinding(ShutdownRegistry.class); + // Bound privately to give the local provider access to configuration settings. + bind(ZooKeeperConfig.class).toInstance(config); + bind(clientKey).toProvider(LocalClientProvider.class).in(Singleton.class); + expose(clientKey); + } + }); + SchedulerServicesModule.addAppStartupServiceBinding(binder()).to(TestServerService.class); + } else { + bind(clientKey).toInstance(new ZooKeeperClient( + config.sessionTimeout, + config.credentials, + config.chrootPath, + config.servers)); + } + } + + /** + * A service to wrap ZooKeeperTestServer. ZooKeeperTestServer is not a service itself because + * some tests depend on stop/start routines that do not no-op, like startAsync and stopAsync may. + */ + private static class TestServerService extends AbstractIdleService { + private final ZooKeeperTestServer testServer; + + @Inject + TestServerService(ZooKeeperTestServer testServer) { + this.testServer = checkNotNull(testServer); + } + + @Override + protected void startUp() { + // We actually start the test server on-demand rather than with the normal lifecycle. + // This is because a ZooKeeperClient binding is needed before scheduler services are started. + } + + @Override + protected void shutDown() { + testServer.stop(); + } + } + + private static class LocalClientProvider implements Provider<ZooKeeperClient> { + private final ZooKeeperConfig config; + private final ZooKeeperTestServer testServer; + + @Inject + LocalClientProvider(ZooKeeperConfig config, ZooKeeperTestServer testServer) { + this.config = checkNotNull(config); + this.testServer = checkNotNull(testServer); + } + + @Override + public ZooKeeperClient get() { + try { + testServer.startNetwork(); + } catch (IOException | InterruptedException e) { + throw Throwables.propagate(e); + } + return new ZooKeeperClient( + config.sessionTimeout, + config.credentials, + Optional.absent(), // chrootPath + ImmutableList.of(InetSocketAddress.createUnresolved("localhost", testServer.getPort()))); + } + } + +} http://git-wip-us.apache.org/repos/asf/aurora/blob/02ffef5d/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 new file mode 100644 index 0000000..80f4da4 --- /dev/null +++ b/src/main/java/org/apache/aurora/scheduler/discovery/ZooKeeperConfig.java @@ -0,0 +1,94 @@ +/** + * 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 com.google.common.base.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; + +/** + * Composite type that contains configuration parameters used when creating a ZooKeeper client. + * <p> + * Instances of this class are immutable, but builder-style chained calls are supported. + */ +public class ZooKeeperConfig { + + /** + * Creates a new client configuration with defaults for the session timeout and credentials. + * + * @param servers ZooKeeper server addresses. + * @return A new configuration. + */ + public static ZooKeeperConfig create(Iterable<InetSocketAddress> servers) { + return new ZooKeeperConfig( + servers, + Optional.absent(), // chrootPath + false, + ZooKeeperUtils.DEFAULT_ZK_SESSION_TIMEOUT, + Optional.absent()); // credentials + } + + public final Iterable<InetSocketAddress> servers; + public final boolean inProcess; + public final Amount<Integer, Time> sessionTimeout; + public final Optional<String> chrootPath; + public final Optional<Credentials> credentials; + + /** + * Creates a new client configuration. + * + * @param servers ZooKeeper server addresses. + * @param inProcess Whether to run and create clients for an in-process ZooKeeper server. + * @param chrootPath an optional chroot path + * @param sessionTimeout Timeout duration for established sessions. + * @param credentials ZooKeeper authentication credentials. + */ + public ZooKeeperConfig( + Iterable<InetSocketAddress> servers, + Optional<String> chrootPath, + boolean inProcess, + Amount<Integer, Time> sessionTimeout, + Optional<Credentials> credentials) { + + this.servers = MorePreconditions.checkNotBlank(servers); + this.chrootPath = requireNonNull(chrootPath); + this.inProcess = inProcess; + this.sessionTimeout = requireNonNull(sessionTimeout); + this.credentials = requireNonNull(credentials); + } + + /** + * Creates a new configuration identical to this configuration, but with the provided + * credentials. + * + * @param newCredentials ZooKeeper authentication credentials. + * @return A modified clone of this configuration. + */ + public ZooKeeperConfig withCredentials(Credentials newCredentials) { + return new ZooKeeperConfig( + servers, + chrootPath, + inProcess, + sessionTimeout, + Optional.of(newCredentials)); + } +} http://git-wip-us.apache.org/repos/asf/aurora/blob/02ffef5d/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 b20ea5d..2aa31ee 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 @@ -35,9 +35,9 @@ 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.ZooKeeperConfig; import org.apache.aurora.scheduler.log.mesos.LogInterface.ReaderInterface; import org.apache.aurora.scheduler.log.mesos.LogInterface.WriterInterface; -import org.apache.aurora.scheduler.zookeeper.guice.client.ZooKeeperClientModule.ClientConfig; import org.apache.mesos.Log; import org.apache.zookeeper.common.PathUtils; @@ -102,17 +102,21 @@ public class MesosLogStreamModule extends PrivateModule { return arg.get(); } - private final ClientConfig zkClientConfig; + private final ZooKeeperConfig zkClientConfig; private final File logPath; private final String zkLogGroupPath; - public MesosLogStreamModule(ClientConfig zkClientConfig) { + public MesosLogStreamModule(ZooKeeperConfig zkClientConfig) { this(zkClientConfig, getRequiredArg(LOG_PATH, "native_log_file_path"), getRequiredArg(ZK_LOG_GROUP_PATH, "native_log_zk_group_path")); } - public MesosLogStreamModule(ClientConfig zkClientConfig, File logPath, String zkLogGroupPath) { + public MesosLogStreamModule( + ZooKeeperConfig zkClientConfig, + File logPath, + String zkLogGroupPath) { + this.zkClientConfig = Objects.requireNonNull(zkClientConfig); this.logPath = Objects.requireNonNull(logPath); http://git-wip-us.apache.org/repos/asf/aurora/blob/02ffef5d/src/main/java/org/apache/aurora/scheduler/zookeeper/guice/client/ZooKeeperClientModule.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/zookeeper/guice/client/ZooKeeperClientModule.java b/src/main/java/org/apache/aurora/scheduler/zookeeper/guice/client/ZooKeeperClientModule.java deleted file mode 100644 index cab3691..0000000 --- a/src/main/java/org/apache/aurora/scheduler/zookeeper/guice/client/ZooKeeperClientModule.java +++ /dev/null @@ -1,214 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.aurora.scheduler.zookeeper.guice.client; - -import java.io.File; -import java.io.IOException; -import java.net.InetSocketAddress; - -import com.google.common.base.Optional; -import com.google.common.base.Throwables; -import com.google.common.collect.ImmutableList; -import com.google.common.io.Files; -import com.google.common.util.concurrent.AbstractIdleService; -import com.google.inject.AbstractModule; -import com.google.inject.Inject; -import com.google.inject.Key; -import com.google.inject.PrivateModule; -import com.google.inject.Provider; -import com.google.inject.Singleton; - -import org.apache.aurora.common.application.ShutdownRegistry; -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.common.zookeeper.Credentials; -import org.apache.aurora.common.zookeeper.ZooKeeperClient; -import org.apache.aurora.common.zookeeper.ZooKeeperUtils; -import org.apache.aurora.common.zookeeper.testing.ZooKeeperTestServer; -import org.apache.aurora.scheduler.SchedulerServicesModule; - -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * A guice binding module that configures and binds a {@link ZooKeeperClient} instance. - */ -public class ZooKeeperClientModule extends AbstractModule { - private final KeyFactory keyFactory; - private final ClientConfig config; - - /** - * Creates a new ZK client module from the provided configuration. - * - * @param config Configuration parameters for the client. - */ - public ZooKeeperClientModule(ClientConfig config) { - this(KeyFactory.PLAIN, config); - } - - /** - * Creates a new ZK client module from the provided configuration, using a key factory to - * qualify any bindings. - * - * @param keyFactory Factory to use when creating any exposed bindings. - * @param config Configuration parameters for the client. - */ - public ZooKeeperClientModule(KeyFactory keyFactory, ClientConfig config) { - this.keyFactory = checkNotNull(keyFactory); - this.config = checkNotNull(config); - } - - @Override - protected void configure() { - Key<ZooKeeperClient> clientKey = keyFactory.create(ZooKeeperClient.class); - if (config.inProcess) { - File tempDir = Files.createTempDir(); - bind(ZooKeeperTestServer.class).toInstance(new ZooKeeperTestServer(tempDir, tempDir)); - - install(new PrivateModule() { - @Override - protected void configure() { - requireBinding(ShutdownRegistry.class); - // Bound privately to give the local provider access to configuration settings. - bind(ClientConfig.class).toInstance(config); - bind(clientKey).toProvider(LocalClientProvider.class).in(Singleton.class); - expose(clientKey); - } - }); - SchedulerServicesModule.addAppStartupServiceBinding(binder()).to(TestServerService.class); - } else { - bind(clientKey).toInstance(new ZooKeeperClient( - config.sessionTimeout, - config.credentials, - config.chrootPath, - config.servers)); - } - } - - /** - * A service to wrap ZooKeeperTestServer. ZooKeeperTestServer is not a service itself because - * some tests depend on stop/start routines that do not no-op, like startAsync and stopAsync may. - */ - private static class TestServerService extends AbstractIdleService { - private final ZooKeeperTestServer testServer; - - @Inject - TestServerService(ZooKeeperTestServer testServer) { - this.testServer = checkNotNull(testServer); - } - - @Override - protected void startUp() { - // We actually start the test server on-demand rather than with the normal lifecycle. - // This is because a ZooKeeperClient binding is needed before scheduler services are started. - } - - @Override - protected void shutDown() { - testServer.stop(); - } - } - - private static class LocalClientProvider implements Provider<ZooKeeperClient> { - private final ClientConfig config; - private final ZooKeeperTestServer testServer; - - @Inject - LocalClientProvider(ClientConfig config, ZooKeeperTestServer testServer) { - this.config = checkNotNull(config); - this.testServer = checkNotNull(testServer); - } - - @Override - public ZooKeeperClient get() { - try { - testServer.startNetwork(); - } catch (IOException | InterruptedException e) { - throw Throwables.propagate(e); - } - return new ZooKeeperClient( - config.sessionTimeout, - config.credentials, - Optional.absent(), // chrootPath - ImmutableList.of(InetSocketAddress.createUnresolved("localhost", testServer.getPort()))); - } - } - - /** - * Composite type that contains configuration parameters used when creating a client. - * <p> - * Instances of this class are immutable, but builder-style chained calls are supported. - */ - public static class ClientConfig { - public final Iterable<InetSocketAddress> servers; - public final boolean inProcess; - public final Amount<Integer, Time> sessionTimeout; - public final Optional<String> chrootPath; - public final Optional<Credentials> credentials; - - /** - * Creates a new client configuration. - * - * @param servers ZooKeeper server addresses. - * @param inProcess Whether to run and create clients for an in-process ZooKeeper server. - * @param chrootPath an optional chroot path - * @param sessionTimeout Timeout duration for established sessions. - * @param credentials ZooKeeper authentication credentials. - */ - public ClientConfig( - Iterable<InetSocketAddress> servers, - Optional<String> chrootPath, - boolean inProcess, - Amount<Integer, Time> sessionTimeout, - Optional<Credentials> credentials) { - - this.servers = servers; - this.chrootPath = chrootPath; - this.inProcess = inProcess; - this.sessionTimeout = sessionTimeout; - this.credentials = credentials; - } - - /** - * Creates a new client configuration with defaults for the session timeout and credentials. - * - * @param servers ZooKeeper server addresses. - * @return A new configuration. - */ - public static ClientConfig create(Iterable<InetSocketAddress> servers) { - return new ClientConfig( - servers, - Optional.absent(), // chrootPath - false, - ZooKeeperUtils.DEFAULT_ZK_SESSION_TIMEOUT, - Optional.absent()); // credentials - } - - /** - * Creates a new configuration identical to this configuration, but with the provided - * credentials. - * - * @param newCredentials ZooKeeper authentication credentials. - * @return A modified clone of this configuration. - */ - public ClientConfig withCredentials(Credentials newCredentials) { - return new ClientConfig( - servers, - chrootPath, - inProcess, - sessionTimeout, - Optional.of(newCredentials)); - } - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/02ffef5d/src/main/java/org/apache/aurora/scheduler/zookeeper/guice/client/flagged/FlaggedClientConfig.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/zookeeper/guice/client/flagged/FlaggedClientConfig.java b/src/main/java/org/apache/aurora/scheduler/zookeeper/guice/client/flagged/FlaggedClientConfig.java deleted file mode 100644 index 92f3673..0000000 --- a/src/main/java/org/apache/aurora/scheduler/zookeeper/guice/client/flagged/FlaggedClientConfig.java +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.aurora.scheduler.zookeeper.guice.client.flagged; - -import java.net.InetSocketAddress; -import java.util.List; - -import javax.annotation.Nullable; - -import com.google.common.base.Optional; -import com.google.common.base.Splitter; -import com.google.common.collect.ImmutableList; - -import org.apache.aurora.common.args.Arg; -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; -import org.apache.aurora.scheduler.zookeeper.guice.client.ZooKeeperClientModule.ClientConfig; - -/** - * A factory that creates a {@link ClientConfig} instance based on command line argument values. - */ -public final class FlaggedClientConfig { - @CmdLine(name = "zk_in_proc", - help = "Launches an embedded zookeeper server for local testing causing -zk_endpoints " - + "to be ignored if specified.") - private static final Arg<Boolean> IN_PROCESS = Arg.create(false); - - @NotEmpty - @CmdLine(name = "zk_endpoints", help = "Endpoint specification for the ZooKeeper servers.") - private static final Arg<List<InetSocketAddress>> ZK_ENDPOINTS = Arg.create(); - - @CmdLine(name = "zk_chroot_path", help = "chroot path to use for the ZooKeeper connections") - private static final Arg<String> CHROOT_PATH = Arg.create(null); - - @CmdLine(name = "zk_session_timeout", help = "The ZooKeeper session timeout.") - private static final Arg<Amount<Integer, Time>> SESSION_TIMEOUT = - Arg.create(ZooKeeperUtils.DEFAULT_ZK_SESSION_TIMEOUT); - - @CmdLine(name = "zk_digest_credentials", - help = "user:password to use when authenticating with ZooKeeper.") - private static final Arg<String> DIGEST_CREDENTIALS = Arg.create(null); - - private FlaggedClientConfig() { - // Utility class. - } - - /** - * Creates a configuration from command line arguments. - * - * @return Configuration instance. - */ - public static ClientConfig create() { - return new ClientConfig( - ZK_ENDPOINTS.get(), - Optional.fromNullable(CHROOT_PATH.get()), - IN_PROCESS.get(), - SESSION_TIMEOUT.get(), - getCredentials(DIGEST_CREDENTIALS.get())); - } - - private static Optional<Credentials> getCredentials(@Nullable String userAndPass) { - if (userAndPass == null) { - return Optional.absent(); - } - - List<String> parts = ImmutableList.copyOf(Splitter.on(":").split(userAndPass)); - if (parts.size() != 2) { - throw new IllegalArgumentException( - "zk_digest_credentials must be formatted as user:pass"); - } - return Optional.of(Credentials.digestCredentials(parts.get(0), parts.get(1))); - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/02ffef5d/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 88d3e3e..b83815b 100644 --- a/src/test/java/org/apache/aurora/scheduler/app/SchedulerIT.java +++ b/src/test/java/org/apache/aurora/scheduler/app/SchedulerIT.java @@ -63,6 +63,8 @@ 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.ServiceDiscoveryModule; +import org.apache.aurora.scheduler.discovery.ZooKeeperClientModule; +import org.apache.aurora.scheduler.discovery.ZooKeeperConfig; import org.apache.aurora.scheduler.log.Log; import org.apache.aurora.scheduler.log.Log.Entry; import org.apache.aurora.scheduler.log.Log.Position; @@ -79,8 +81,6 @@ import org.apache.aurora.scheduler.storage.log.LogStorageModule; import org.apache.aurora.scheduler.storage.log.SnapshotStoreImpl; import org.apache.aurora.scheduler.storage.log.testing.LogOpMatcher; import org.apache.aurora.scheduler.storage.log.testing.LogOpMatcher.StreamMatcher; -import org.apache.aurora.scheduler.zookeeper.guice.client.ZooKeeperClientModule; -import org.apache.aurora.scheduler.zookeeper.guice.client.ZooKeeperClientModule.ClientConfig; import org.apache.mesos.Protos.FrameworkID; import org.apache.mesos.Protos.MasterInfo; import org.apache.mesos.Protos.Status; @@ -194,7 +194,7 @@ public class SchedulerIT extends BaseZooKeeperClientTest { } }; Credentials credentials = Credentials.digestCredentials("mesos", "mesos"); - ClientConfig zkClientConfig = ClientConfig + ZooKeeperConfig zkClientConfig = ZooKeeperConfig .create(ImmutableList.of(InetSocketAddress.createUnresolved("localhost", getPort()))) .withCredentials(credentials); SchedulerMain main = SchedulerMain.class.newInstance(); http://git-wip-us.apache.org/repos/asf/aurora/blob/02ffef5d/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 new file mode 100644 index 0000000..ac781ea --- /dev/null +++ b/src/test/java/org/apache/aurora/scheduler/discovery/ZooKeeperConfigTest.java @@ -0,0 +1,79 @@ +/** + * 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 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; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertTrue; + +public class ZooKeeperConfigTest { + + private static final ImmutableList<InetSocketAddress> SERVERS = + ImmutableList.of(InetSocketAddress.createUnresolved("localhost", 42)); + + @Test(expected = IllegalArgumentException.class) + public void testEmptyServers() { + new ZooKeeperConfig( + ImmutableList.of(), + Optional.absent(), + false, + Amount.of(1, Time.DAYS), + Optional.absent()); + } + + @Test + public void testWithCredentials() { + ZooKeeperConfig config = + new ZooKeeperConfig( + SERVERS, + Optional.absent(), + false, + Amount.of(1, Time.HOURS), + Optional.absent()); // credentials + assertFalse(config.credentials.isPresent()); + + Credentials joeCreds = Credentials.digestCredentials("Joe", "Schmoe"); + ZooKeeperConfig joeConfig = config.withCredentials(joeCreds); + + // Should not mutate the original. + assertNotSame(config, joeConfig); + assertFalse(config.credentials.isPresent()); + + assertTrue(joeConfig.credentials.isPresent()); + assertEquals(joeCreds, joeConfig.credentials.get()); + } + + @Test + public void testCreateFactory() { + ZooKeeperConfig config = ZooKeeperConfig.create(SERVERS); + + assertEquals(SERVERS, ImmutableList.copyOf(config.servers)); + assertFalse(config.chrootPath.isPresent()); + assertFalse(config.inProcess); + assertEquals(ZooKeeperUtils.DEFAULT_ZK_SESSION_TIMEOUT, config.sessionTimeout); + assertFalse(config.credentials.isPresent()); + } +}
