package com.hubspot.blazar.zookeeper; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import javax.inject.Inject; import javax.inject.Provider; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.framework.state.ConnectionStateListener; import org.apache.curator.retry.ExponentialBackoffRetry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.hubspot.blazar.config.BlazarConfiguration; import com.hubspot.blazar.config.ZooKeeperConfiguration; import io.dropwizard.lifecycle.Managed; public class BlazarCuratorProvider implements Provider<CuratorFramework>, Managed { private static final Logger LOG = LoggerFactory.getLogger(BlazarCuratorProvider.class); private final CuratorFramework curatorFramework; private final AtomicBoolean started = new AtomicBoolean(); private final AtomicBoolean stopped = new AtomicBoolean(); @Inject public BlazarCuratorProvider(BlazarConfiguration configuration, Set<ConnectionStateListener> listeners) { Optional<ZooKeeperConfiguration> maybeZooKeeperConfiguration = configuration.getZooKeeperConfiguration(); if (!maybeZooKeeperConfiguration.isPresent()) { throw new IllegalArgumentException("Can not create a CuratorProvider with no zookeeper connection info in BlazarConfiguration"); } ZooKeeperConfiguration zooKeeperConfiguration = maybeZooKeeperConfiguration.get(); this.curatorFramework = CuratorFrameworkFactory.builder() .connectString(zooKeeperConfiguration.getQuorum()) .sessionTimeoutMs(zooKeeperConfiguration.getSessionTimeoutMillis()) .connectionTimeoutMs(zooKeeperConfiguration.getConnectTimeoutMillis()) .retryPolicy(new ExponentialBackoffRetry(zooKeeperConfiguration.getInitialRetryBackoffMillis(), zooKeeperConfiguration.getMaxRetries())) .namespace(zooKeeperConfiguration.getNamespace()) .defaultData(null) .build(); for (ConnectionStateListener listener : listeners) { curatorFramework.getConnectionStateListenable().addListener(listener); } } @Override public void start() throws Exception { if (started.compareAndSet(false, true)) { curatorFramework.start(); long start = System.currentTimeMillis(); try { Preconditions.checkState(curatorFramework.getZookeeperClient().blockUntilConnectedOrTimedOut(), "Could not connect to zookeeper"); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } long end = System.currentTimeMillis(); LOG.info("Connected to ZooKeeper in {}ms", end - start); } } @Override public CuratorFramework get() { return curatorFramework; } @Override public void stop() throws Exception { if (started.get() && stopped.compareAndSet(false, true)) { curatorFramework.close(); } } }