package com.hubspot.baragon.agent.managed; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.recipes.leader.LeaderLatch; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.inject.Inject; import com.google.inject.name.Named; import com.hubspot.baragon.agent.BaragonAgentServiceModule; import com.hubspot.baragon.agent.config.BaragonAgentConfiguration; import com.hubspot.baragon.agent.healthcheck.ConfigChecker; import com.hubspot.baragon.agent.listeners.ResyncListener; import com.hubspot.baragon.agent.workers.AgentHeartbeatWorker; import com.hubspot.baragon.data.BaragonKnownAgentsDatastore; import com.hubspot.baragon.data.BaragonLoadBalancerDatastore; import com.hubspot.baragon.models.BaragonAgentMetadata; import com.hubspot.baragon.models.BaragonAgentState; import com.hubspot.baragon.models.BaragonKnownAgentMetadata; import io.dropwizard.lifecycle.Managed; public class BootstrapManaged implements Managed { private static final Logger LOG = LoggerFactory.getLogger(BootstrapManaged.class); private final BaragonAgentConfiguration configuration; private final BaragonLoadBalancerDatastore loadBalancerDatastore; private final LeaderLatch leaderLatch; private final BaragonKnownAgentsDatastore knownAgentsDatastore; private final BaragonAgentMetadata baragonAgentMetadata; private final ScheduledExecutorService executorService; private final AgentHeartbeatWorker agentHeartbeatWorker; private final LifecycleHelper lifecycleHelper; private final CuratorFramework curatorFramework; private final ResyncListener resyncListener; private final ConfigChecker configChecker; private final AtomicReference<BaragonAgentState> agentState; private ScheduledFuture<?> requestWorkerFuture = null; private ScheduledFuture<?> configCheckerFuture = null; @Inject public BootstrapManaged(BaragonKnownAgentsDatastore knownAgentsDatastore, BaragonLoadBalancerDatastore loadBalancerDatastore, BaragonAgentConfiguration configuration, AgentHeartbeatWorker agentHeartbeatWorker, BaragonAgentMetadata baragonAgentMetadata, LifecycleHelper lifecycleHelper, CuratorFramework curatorFramework, ResyncListener resyncListener, ConfigChecker configChecker, AtomicReference<BaragonAgentState> agentState, @Named(BaragonAgentServiceModule.AGENT_SCHEDULED_EXECUTOR) ScheduledExecutorService executorService, @Named(BaragonAgentServiceModule.AGENT_LEADER_LATCH) LeaderLatch leaderLatch) { this.configuration = configuration; this.leaderLatch = leaderLatch; this.curatorFramework = curatorFramework; this.resyncListener = resyncListener; this.knownAgentsDatastore = knownAgentsDatastore; this.loadBalancerDatastore = loadBalancerDatastore; this.baragonAgentMetadata = baragonAgentMetadata; this.executorService = executorService; this.agentHeartbeatWorker = agentHeartbeatWorker; this.lifecycleHelper = lifecycleHelper; this.configChecker = configChecker; this.agentState = agentState; } @Override public void start() throws Exception { LOG.info("Applying current configs..."); lifecycleHelper.applyCurrentConfigs(); LOG.info("Starting leader latch..."); leaderLatch.start(); if (configuration.isRegisterOnStartup()) { LOG.info("Notifying BaragonService..."); lifecycleHelper.notifyService("startup"); } LOG.info("Updating BaragonGroup information..."); loadBalancerDatastore.updateGroupInfo(configuration.getLoadBalancerConfiguration().getName(), configuration.getLoadBalancerConfiguration().getDefaultDomain(), configuration.getLoadBalancerConfiguration().getDomains()); LOG.info("Adding to known-agents..."); knownAgentsDatastore.addKnownAgent(configuration.getLoadBalancerConfiguration().getName(), BaragonKnownAgentMetadata.fromAgentMetadata(baragonAgentMetadata, System.currentTimeMillis())); LOG.info("Starting agent heartbeat..."); requestWorkerFuture = executorService.scheduleAtFixedRate(agentHeartbeatWorker, 0, configuration.getHeartbeatIntervalSeconds(), TimeUnit.SECONDS); LOG.info("Starting config checker"); configCheckerFuture = executorService.scheduleAtFixedRate(configChecker, 0, configuration.getConfigCheckIntervalSecs(), TimeUnit.SECONDS); LOG.info("Adding resync listener"); curatorFramework.getConnectionStateListenable().addListener(resyncListener); lifecycleHelper.writeStateFileIfConfigured(); agentState.set(BaragonAgentState.ACCEPTING); } @Override public void stop() throws Exception { lifecycleHelper.shutdown(); } }