All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.netflix.genie.web.spring.autoconfigure.tasks.leader.LeaderAutoConfiguration Maven / Gradle / Ivy

The newest version!
/*
 *
 *  Copyright 2017 Netflix, Inc.
 *
 *     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 com.netflix.genie.web.spring.autoconfigure.tasks.leader;

import com.netflix.genie.web.agent.services.AgentRoutingService;
import com.netflix.genie.web.data.services.DataServices;
import com.netflix.genie.web.events.GenieEventBus;
import com.netflix.genie.web.properties.AgentCleanupProperties;
import com.netflix.genie.web.properties.ArchiveStatusCleanupProperties;
import com.netflix.genie.web.properties.DatabaseCleanupProperties;
import com.netflix.genie.web.properties.LeadershipProperties;
import com.netflix.genie.web.properties.UserMetricsProperties;
import com.netflix.genie.web.services.ClusterLeaderService;
import com.netflix.genie.web.services.impl.ClusterLeaderServiceCuratorImpl;
import com.netflix.genie.web.services.impl.ClusterLeaderServiceLocalLeaderImpl;
import com.netflix.genie.web.spring.actuators.LeaderElectionActuator;
import com.netflix.genie.web.spring.autoconfigure.ZookeeperAutoConfiguration;
import com.netflix.genie.web.spring.autoconfigure.tasks.TasksAutoConfiguration;
import com.netflix.genie.web.tasks.leader.AgentJobCleanupTask;
import com.netflix.genie.web.tasks.leader.ArchiveStatusCleanupTask;
import com.netflix.genie.web.tasks.leader.DatabaseCleanupTask;
import com.netflix.genie.web.tasks.leader.LeaderTask;
import com.netflix.genie.web.tasks.leader.LeaderTasksCoordinator;
import com.netflix.genie.web.tasks.leader.LocalLeader;
import com.netflix.genie.web.tasks.leader.UserMetricsTask;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.integration.zookeeper.leader.LeaderInitiator;
import org.springframework.scheduling.TaskScheduler;

import java.util.Set;

/**
 * Beans for Leadership of a Genie cluster.
 *
 * @author tgianos
 * @since 3.1.0
 */
@Configuration
@EnableConfigurationProperties(
    {
        AgentCleanupProperties.class,
        ArchiveStatusCleanupProperties.class,
        DatabaseCleanupProperties.class,
        LeadershipProperties.class,
        UserMetricsProperties.class,
    }
)
@AutoConfigureAfter(
    {
        TasksAutoConfiguration.class,
        ZookeeperAutoConfiguration.class
    }
)
public class LeaderAutoConfiguration {

    /**
     * Create the LeadershipTasksCoordination bean used to start and stop all leadership related tasks based on
     * whether leadership is granted or revoked.
     *
     * @param taskScheduler The task scheduler to use for scheduling leadership tasks
     * @param tasks         The leadership tasks to schedule
     * @return The leader coordinator
     */
    @Bean
    @ConditionalOnMissingBean(LeaderTasksCoordinator.class)
    public LeaderTasksCoordinator leaderTasksCoordinator(
        @Qualifier("genieTaskScheduler") final TaskScheduler taskScheduler,
        final Set tasks
    ) {
        return new LeaderTasksCoordinator(taskScheduler, tasks);
    }

    /**
     * Create a {@link DatabaseCleanupTask} if one is required.
     *
     * @param cleanupProperties The properties to use to configure this task
     * @param environment       The application {@link Environment} to pull properties from
     * @param dataServices      The {@link DataServices} encapsulation instance to use
     * @param registry          The metrics registry
     * @return The {@link DatabaseCleanupTask} instance to use if the conditions match
     */
    @Bean
    @ConditionalOnProperty(value = DatabaseCleanupProperties.ENABLED_PROPERTY, havingValue = "true")
    @ConditionalOnMissingBean(DatabaseCleanupTask.class)
    public DatabaseCleanupTask databaseCleanupTask(
        final DatabaseCleanupProperties cleanupProperties,
        final Environment environment,
        final DataServices dataServices,
        final MeterRegistry registry
    ) {
        return new DatabaseCleanupTask(
            cleanupProperties,
            environment,
            dataServices,
            registry
        );
    }

    /**
     * If required get a {@link UserMetricsTask} instance for use.
     *
     * @param registry              The metrics registry
     * @param dataServices          The {@link DataServices} instance to use
     * @param userMetricsProperties The properties
     * @return The {@link UserMetricsTask} instance
     */
    @Bean
    @ConditionalOnProperty(value = UserMetricsProperties.ENABLED_PROPERTY, havingValue = "true")
    @ConditionalOnMissingBean(UserMetricsTask.class)
    public UserMetricsTask userMetricsTask(
        final MeterRegistry registry,
        final DataServices dataServices,
        final UserMetricsProperties userMetricsProperties
    ) {
        return new UserMetricsTask(
            registry,
            dataServices,
            userMetricsProperties
        );
    }

    /**
     * If required, get a {@link AgentJobCleanupTask} instance for use.
     *
     * @param dataServices           The {@link DataServices} encapsulation instance to use
     * @param agentCleanupProperties the agent cleanup properties
     * @param registry               the metrics registry
     * @param agentRoutingService    the agent routing service
     * @return a {@link AgentJobCleanupTask}
     */
    @Bean
    @ConditionalOnProperty(value = AgentCleanupProperties.ENABLED_PROPERTY, havingValue = "true")
    @ConditionalOnMissingBean(AgentJobCleanupTask.class)
    public AgentJobCleanupTask agentJobCleanupTask(
        final DataServices dataServices,
        final AgentCleanupProperties agentCleanupProperties,
        final MeterRegistry registry,
        final AgentRoutingService agentRoutingService
    ) {
        return new AgentJobCleanupTask(
            dataServices,
            agentCleanupProperties,
            registry,
            agentRoutingService
        );
    }

    /**
     * If required, get a {@link ArchiveStatusCleanupTask} instance for use.
     *
     * @param dataServices                   The {@link DataServices} encapsulation instance to use
     * @param agentRoutingService            the agent routing service
     * @param archiveStatusCleanupProperties the archive status cleanup properties
     * @param registry                       the metrics registry
     * @return a {@link AgentJobCleanupTask}
     */
    @Bean
    @ConditionalOnProperty(value = ArchiveStatusCleanupProperties.ENABLED_PROPERTY, havingValue = "true")
    @ConditionalOnMissingBean(ArchiveStatusCleanupTask.class)
    public ArchiveStatusCleanupTask archiveStatusCleanupTask(
        final DataServices dataServices,
        final AgentRoutingService agentRoutingService,
        final ArchiveStatusCleanupProperties archiveStatusCleanupProperties,
        final MeterRegistry registry
    ) {
        return new ArchiveStatusCleanupTask(
            dataServices,
            agentRoutingService,
            archiveStatusCleanupProperties,
            registry
        );
    }

    /**
     * Create a {@link ClusterLeaderService} based on Zookeeper/Curator if {@link LeaderInitiator} is
     * available and the bean does not already exist.
     *
     * @param leaderInitiator the Spring Zookeeper/Curator based leader election component
     * @return a {@link ClusterLeaderService}
     */
    @Bean
    @ConditionalOnBean(LeaderInitiator.class)
    @ConditionalOnMissingBean(ClusterLeaderService.class)
    public ClusterLeaderService curatorClusterLeaderService(final LeaderInitiator leaderInitiator) {
        return new ClusterLeaderServiceCuratorImpl(leaderInitiator);
    }

    /**
     * If Zookeeper isn't available and this node is forced to be the leader create the local leader
     * bean which will fire appropriate events.
     *
     * @param genieEventBus        The genie event bus implementation to use
     * @param leadershipProperties Properties related to static leadership configuration for the Genie cluster
     * @return The local leader bean
     */
    @Bean
    @ConditionalOnMissingBean(
        {
            LeaderInitiator.class,
            LocalLeader.class
        }
    )
    public LocalLeader localLeader(
        final GenieEventBus genieEventBus,
        final LeadershipProperties leadershipProperties
    ) {
        return new LocalLeader(genieEventBus, leadershipProperties.isEnabled());
    }

    /**
     * Create a {@link ClusterLeaderService} based on static configuration if {@link LocalLeader} is
     * available and the bean does not already exist.
     *
     * @param localLeader the configuration-based leader election component
     * @return a {@link ClusterLeaderService}
     */
    @Bean
    @ConditionalOnBean(LocalLeader.class)
    @ConditionalOnMissingBean(ClusterLeaderService.class)
    public ClusterLeaderService localClusterLeaderService(final LocalLeader localLeader) {
        return new ClusterLeaderServiceLocalLeaderImpl(localLeader);
    }

    /**
     * Create a {@link LeaderElectionActuator} bean if one is not already defined and if
     * {@link ClusterLeaderService} is available. This bean is an endpoint that gets registered in Spring Actuator.
     *
     * @param clusterLeaderService the cluster leader service
     * @return a {@link LeaderElectionActuator}
     */
    @Bean
    @ConditionalOnBean(ClusterLeaderService.class)
    @ConditionalOnMissingBean(LeaderElectionActuator.class)
    public LeaderElectionActuator leaderElectionActuator(final ClusterLeaderService clusterLeaderService) {
        return new LeaderElectionActuator(clusterLeaderService);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy