Java tutorial
/* * 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(); } }