com.dangdang.ddframe.job.cloud.scheduler.mesos.FacadeService.java Source code

Java tutorial

Introduction

Here is the source code for com.dangdang.ddframe.job.cloud.scheduler.mesos.FacadeService.java

Source

/*
 * Copyright 1999-2015 dangdang.com.
 * <p>
 * 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.
 * </p>
 */

package com.dangdang.ddframe.job.cloud.scheduler.mesos;

import com.dangdang.ddframe.job.cloud.scheduler.config.app.CloudAppConfiguration;
import com.dangdang.ddframe.job.cloud.scheduler.config.app.CloudAppConfigurationService;
import com.dangdang.ddframe.job.cloud.scheduler.config.job.CloudJobConfiguration;
import com.dangdang.ddframe.job.cloud.scheduler.config.job.CloudJobConfigurationService;
import com.dangdang.ddframe.job.cloud.scheduler.config.job.CloudJobExecutionType;
import com.dangdang.ddframe.job.cloud.scheduler.context.JobContext;
import com.dangdang.ddframe.job.cloud.scheduler.context.TaskFullViewInfo;
import com.dangdang.ddframe.job.cloud.scheduler.state.disable.app.DisableAppService;
import com.dangdang.ddframe.job.cloud.scheduler.state.disable.job.DisableJobService;
import com.dangdang.ddframe.job.cloud.scheduler.state.failover.FailoverService;
import com.dangdang.ddframe.job.cloud.scheduler.state.failover.FailoverTaskInfo;
import com.dangdang.ddframe.job.cloud.scheduler.state.ready.ReadyService;
import com.dangdang.ddframe.job.cloud.scheduler.state.running.RunningService;
import com.dangdang.ddframe.job.context.ExecutionType;
import com.dangdang.ddframe.job.context.TaskContext;
import com.dangdang.ddframe.job.context.TaskContext.MetaInfo;
import com.dangdang.ddframe.job.reg.base.CoordinatorRegistryCenter;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Mesos????.
 *
 * @author zhangliang
 * @author caohao
 */
@Slf4j
public final class FacadeService {

    private static final String RUNNING_STATUS = "RUNNING";

    private static final String RUNNING_STATUS_COMMENT = "FRAMEWORK:RUNNING;ZK:MISSING";

    private static final String FAILOVER_STATUS = "FAILOVER";

    private final CloudAppConfigurationService appConfigService;

    private final CloudJobConfigurationService jobConfigService;

    private final ReadyService readyService;

    private final RunningService runningService;

    private final FailoverService failoverService;

    private final DisableAppService disableAppService;

    private final DisableJobService disableJobService;

    private final MesosStateService mesosStateService;

    private final MesosSlaveService mesosSlaveService;

    public FacadeService(final CoordinatorRegistryCenter regCenter) {
        appConfigService = new CloudAppConfigurationService(regCenter);
        jobConfigService = new CloudJobConfigurationService(regCenter);
        readyService = new ReadyService(regCenter);
        runningService = new RunningService(regCenter);
        failoverService = new FailoverService(regCenter);
        disableAppService = new DisableAppService(regCenter);
        disableJobService = new DisableJobService(regCenter);
        mesosStateService = new MesosStateService(regCenter);
        mesosSlaveService = new MesosSlaveService();
    }

    /**
     * ???.
     */
    public void start() {
        log.info("Elastic Job: Start facade service");
        runningService.start();
    }

    /**
     * ??.
     * 
     * @return ?
     */
    public Collection<JobContext> getEligibleJobContext() {
        Collection<JobContext> failoverJobContexts = failoverService.getAllEligibleJobContexts();
        Collection<JobContext> readyJobContexts = readyService.getAllEligibleJobContexts(failoverJobContexts);
        Collection<JobContext> result = new ArrayList<>(failoverJobContexts.size() + readyJobContexts.size());
        result.addAll(failoverJobContexts);
        result.addAll(readyJobContexts);
        return result;
    }

    /**
     * ?.
     * 
     * @param taskContexts ?
     */
    public void removeLaunchTasksFromQueue(final List<TaskContext> taskContexts) {
        List<TaskContext> failoverTaskContexts = new ArrayList<>(taskContexts.size());
        Collection<String> readyJobNames = new HashSet<>(taskContexts.size(), 1);
        for (TaskContext each : taskContexts) {
            switch (each.getType()) {
            case FAILOVER:
                failoverTaskContexts.add(each);
                break;
            case READY:
                readyJobNames.add(each.getMetaInfo().getJobName());
                break;
            default:
                break;
            }
        }
        failoverService
                .remove(Lists.transform(failoverTaskContexts, new Function<TaskContext, TaskContext.MetaInfo>() {

                    @Override
                    public TaskContext.MetaInfo apply(final TaskContext input) {
                        return input.getMetaInfo();
                    }
                }));
        readyService.remove(readyJobNames);
    }

    /**
     * ??.
     *
     * @param taskContext ?
     */
    public void addRunning(final TaskContext taskContext) {
        runningService.add(taskContext);
    }

    /**
     * ??.
     * 
     * @param taskContext ?
     * @param isIdle ?
     */
    public void updateDaemonStatus(final TaskContext taskContext, final boolean isIdle) {
        runningService.updateIdle(taskContext, isIdle);
    }

    /**
     * ?.
     *
     * @param taskContext ?
     */
    public void removeRunning(final TaskContext taskContext) {
        runningService.remove(taskContext);
    }

    /**
     * .
     * 
     * @param taskContext 
     */
    public void recordFailoverTask(final TaskContext taskContext) {
        Optional<CloudJobConfiguration> jobConfigOptional = jobConfigService
                .load(taskContext.getMetaInfo().getJobName());
        if (!jobConfigOptional.isPresent()) {
            return;
        }
        if (isDisable(jobConfigOptional.get())) {
            return;
        }
        CloudJobConfiguration jobConfig = jobConfigOptional.get();
        if (jobConfig.getTypeConfig().getCoreConfig().isFailover()
                || CloudJobExecutionType.DAEMON == jobConfig.getJobExecutionType()) {
            failoverService.add(taskContext);
        }
    }

    private boolean isDisable(final CloudJobConfiguration jobConfiguration) {
        return disableAppService.isDisabled(jobConfiguration.getAppName())
                || disableJobService.isDisabled(jobConfiguration.getJobName());
    }

    /**
     * .
     *
     * @param jobName ??
     */
    public void addTransient(final String jobName) {
        readyService.addTransient(jobName);
    }

    /**
     * ?????.
     *
     * @param jobName ??
     * @return ?
     */
    public Optional<CloudJobConfiguration> load(final String jobName) {
        return jobConfigService.load(jobName);
    }

    /**
     * ?????.
     *
     * @param appName ??
     * @return ?
     */
    public Optional<CloudAppConfiguration> loadAppConfig(final String appName) {
        return appConfigService.load(appName);
    }

    /**
     * ???Id.
     *
     * @param metaInfo ?
     * @return Id
     */
    public Optional<String> getFailoverTaskId(final MetaInfo metaInfo) {
        return failoverService.getTaskId(metaInfo);
    }

    /**
     * .
     *
     * @param jobName ??
     */
    public void addDaemonJobToReadyQueue(final String jobName) {
        Optional<CloudJobConfiguration> jobConfigOptional = jobConfigService.load(jobName);
        if (!jobConfigOptional.isPresent()) {
            return;
        }
        if (isDisable(jobConfigOptional.get())) {
            return;
        }
        readyService.addDaemon(jobName);
    }

    /**
     * ???.
     *
     * <p>READY, ???. FAILOVER?????.</p>
     * 
     * @param taskContext ?
     * @return ??
     */
    public boolean isRunning(final TaskContext taskContext) {
        return ExecutionType.FAILOVER != taskContext.getType()
                && !runningService.getRunningTasks(taskContext.getMetaInfo().getJobName()).isEmpty()
                || ExecutionType.FAILOVER == taskContext.getType()
                        && runningService.isTaskRunning(taskContext.getMetaInfo());
    }

    /**
     * ??.
     *
     * @param taskId 
     * @param hostname ??
     */
    public void addMapping(final String taskId, final String hostname) {
        runningService.addMapping(taskId, hostname);
    }

    /**
     * ????.
     *
     * @param taskId 
     * @return ??
     */
    public String popMapping(final String taskId) {
        return runningService.popMapping(taskId);
    }

    /**
     * ??.
     *
     * @return ?
     */
    public Map<String, Integer> getAllReadyTasks() {
        return readyService.getAllReadyTasks();
    }

    /**
     * ??.
     *
     * @param jobName ??
     * @return ?
     */
    public Collection<Map<String, String>> getReadyJobTimes(final String jobName) {
        return readyService.getReadyJobTimes(jobName);
    }

    /**
     * ??.
     *
     * @return ??
     */
    public Map<String, Set<TaskContext>> getAllRunningTasks() {
        return runningService.getAllRunningTasks();
    }

    /**
     * ??.
     *
     * @param jobName ??
     * @return ??
     */
    private Collection<TaskContext> getJobRunningTasks(final String jobName) {
        return runningService.getRunningTasks(jobName);
    }

    /**
     * ?.
     *
     * @return 
     */
    public Map<String, Collection<FailoverTaskInfo>> getAllFailoverTasks() {
        return failoverService.getAllFailoverTasks();
    }

    /**
     * ?.
     *
     * @param jobName ??
     * @return ?
     */
    private Collection<FailoverTaskInfo> getJobFailoverTasks(final String jobName) {
        return failoverService.getFailoverTasks(jobName);
    }

    /**
     * ??.
     * 
     * @param jobName ??
     * @return ??
     */
    public boolean isJobDisabled(final String jobName) {
        Optional<CloudJobConfiguration> jobConfiguration = jobConfigService.load(jobName);
        return !jobConfiguration.isPresent() || disableAppService.isDisabled(jobConfiguration.get().getAppName())
                || disableJobService.isDisabled(jobName);
    }

    /**
     * ?.
     *
     * @param jobName ??
     */
    public void enableJob(final String jobName) {
        disableJobService.remove(jobName);
    }

    /**
     * ?.
     *
     * @param jobName ??
     */
    public void disableJob(final String jobName) {
        disableJobService.add(jobName);
    }

    /**
     * ????.
     *
     * @param taskId 
     * @return hostName ??
     */
    private String getHostNameByTaskId(final String taskId) {
        return runningService.getHostNameByTaskId(taskId);
    }

    /**
     * ?zk?running.
     *
     * @param taskId 
     * @return running?
     */
    private boolean getRunningTaskInZookeeper(final String taskId) {
        return runningService.getRunningTaskInZookeeper(taskId);
    }

    /**
     * ?360?.
     *
     * @param jobName ??
     * @return 360??
     */
    public Collection<TaskFullViewInfo> getTaskFullViewInfo(final String jobName) {
        Optional<CloudJobConfiguration> cloudJobConfigurationOptional = this.load(jobName);
        CloudJobConfiguration cloudJobConfiguration;
        String appName = null;
        CloudJobExecutionType cloudJobExecutionType = null;
        if (cloudJobConfigurationOptional.isPresent()) {
            cloudJobConfiguration = cloudJobConfigurationOptional.get();
            appName = cloudJobConfiguration.getAppName();
            cloudJobExecutionType = cloudJobConfiguration.getJobExecutionType();
        }
        Collection<TaskContext> runningTasks = this.getJobRunningTasks(jobName);
        Collection<FailoverTaskInfo> failoverTasks = this.getJobFailoverTasks(jobName);
        Collection<TaskFullViewInfo> result = Lists.newArrayList();
        if (runningTasks.size() > 0) {
            for (TaskContext each : runningTasks) {
                String statusInfo = RUNNING_STATUS;
                if (null != cloudJobExecutionType && cloudJobExecutionType.equals(CloudJobExecutionType.DAEMON)
                        && !this.getRunningTaskInZookeeper(each.getId())) {
                    statusInfo = RUNNING_STATUS_COMMENT;
                }
                String taskId = each.getId();
                result.add(new TaskFullViewInfo(taskId, this.getHostNameByTaskId(taskId), statusInfo,
                        mesosStateService.getMesosSandbox(each.getId())));
            }
        }
        if (failoverTasks.size() > 0) {
            JsonArray slaves = mesosSlaveService.findAllSlaves();
            for (FailoverTaskInfo each : failoverTasks) {
                final TaskContext taskContext = TaskContext.from(each.getOriginalTaskId());
                String serverIp = "";
                Optional<JsonElement> slaveOptional = Iterators.tryFind(slaves.iterator(),
                        new Predicate<JsonElement>() {
                            @Override
                            public boolean apply(final JsonElement input) {
                                return input.getAsJsonObject().get("id").getAsString()
                                        .equals(taskContext.getSlaveId());
                            }
                        });
                if (slaveOptional.isPresent()) {
                    serverIp = slaveOptional.get().getAsJsonObject().get("hostname").getAsString();
                }
                result.add(new TaskFullViewInfo(taskContext.getId(), serverIp, FAILOVER_STATUS,
                        mesosStateService.getMesosSandbox(each.getOriginalTaskId())));
            }
        }
        return result;
    }

    /**
     * ?.
     * 
     * @param taskId Id
     * @return 
     */
    public String getTaskSandbox(final String taskId) {
        return mesosStateService.getMesosSandbox(taskId);
    }

    /**
     * ??Executor?.
     * 
     * @return Executor??
     */
    public Collection<MesosStateService.ExecutorStateInfo> loadExecutorInfo() {
        return mesosStateService.executors();
    }

    /**
     * ???.
     */
    public void stop() {
        log.info("Elastic Job: Stop facade service");
        // TODO ?
        runningService.clear();
    }

}