Package azkaban.web.pages

Source Code of azkaban.web.pages.IndexServlet$FlowComparator

/*
* Copyright 2010 LinkedIn, 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 azkaban.web.pages;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.Hours;
import org.joda.time.LocalDateTime;
import org.joda.time.Minutes;
import org.joda.time.ReadablePeriod;
import org.joda.time.Seconds;
import org.joda.time.format.DateTimeFormat;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

import azkaban.app.AzkabanApplication;
import azkaban.app.JobDescriptor;
import azkaban.app.JobManager;
import azkaban.common.web.Page;
import azkaban.flow.ExecutableFlow;
import azkaban.flow.Flow;
import azkaban.flow.FlowManager;
import azkaban.jobs.JobExecutionException;
import azkaban.jobs.JobExecutorManager.ExecutingJobAndInstance;
import azkaban.util.json.JSONUtils;
import azkaban.web.AbstractAzkabanServlet;

/**
* The main page
*
* @author jkreps
*
*/
public class IndexServlet extends AbstractAzkabanServlet {

    private static final Logger logger = Logger.getLogger(IndexServlet.class.getName());

    private static final long serialVersionUID = 1;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
            IOException {
        /* set runtime properties from request and response */
        super.setRuntimeProperties(req, resp);

        AzkabanApplication app = getApplication();
        @SuppressWarnings("unused")
        Map<String, JobDescriptor> descriptors = app.getJobManager().loadJobDescriptors();
        Page page = newPage(req, resp, "azkaban/web/pages/index.vm");
        page.add("logDir", app.getLogDirectory());
        page.add("flows", app.getAllFlows());
        page.add("scheduled", app.getScheduleManager().getSchedule());
        page.add("executing", app.getJobExecutorManager().getExecutingJobs());
        page.add("completed", app.getJobExecutorManager().getCompleted());
        page.add("rootJobNames", app.getAllFlows().getRootFlowNames());
        page.add("folderNames", app.getAllFlows().getFolders());
        page.add("jobDescComparator", JobDescriptor.NAME_COMPARATOR);
        page.render();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        /* set runtime properties from request and response */
        super.setRuntimeProperties(req, resp);

        AzkabanApplication app = getApplication();
        String action = getParam(req, "action");
        if ("loadjobs".equals(action)) {
          resp.setContentType("application/json");
          String folder = getParam(req, "folder");
          resp.getWriter().print(getJSONJobsForFolder(app.getAllFlows(), folder));
          resp.getWriter().flush();
          return;
        }
        else if("unschedule".equals(action)) {
            String jobid = getParam(req, "job");
            app.getScheduleManager().removeScheduledJob(jobid);
        } else if("cancel".equals(action)) {
            cancelJob(app, req);
        } else if("schedule".equals(action)) {
            String redirect = scheduleJobs(app, req, resp);
            if (!redirect.isEmpty()) {
              resp.sendRedirect(redirect);
              return;
            }
        } else {
            throw new ServletException("Unknown action: " + action);
        }
        resp.sendRedirect(req.getContextPath());
    }
   
    @SuppressWarnings("unchecked")
  private String getJSONJobsForFolder(FlowManager manager, String folder) {
      List<String> rootJobs = manager.getRootNamesByFolder(folder);
      Collections.sort(rootJobs);

      JSONArray rootJobObj = new JSONArray();
      for (String root: rootJobs) {
        Flow flow = manager.getFlow(root);
        JSONObject flowObj = getJSONDependencyTree(flow);
        rootJobObj.add(flowObj);
      }
     
      return rootJobObj.toJSONString();
    }
   
    @SuppressWarnings("unchecked")
  private JSONObject getJSONDependencyTree(Flow flow) {
      JSONObject jobObject = new JSONObject();
      jobObject.put("name", flow.getName());
     
      if (flow.hasChildren()) {
        JSONArray dependencies = new JSONArray();
        for(Flow child : flow.getChildren()) {
          JSONObject childObj = getJSONDependencyTree(child);
          dependencies.add(childObj);
        }
       
        Collections.sort(dependencies, new FlowComparator());
        jobObject.put("dep", dependencies);
      }
     
      return jobObject;
    }
   
    private class FlowComparator implements Comparator<JSONObject> {

    @Override
    public int compare(JSONObject arg0, JSONObject arg1) {
      String first = (String)arg0.get("name");
      String second = (String)arg1.get("name");
      return first.compareTo(second);
    }
     
    }
   
    private void cancelJob(AzkabanApplication app, HttpServletRequest req) throws ServletException {

        String jobId = getParam(req, "job");
        try {
      app.getJobExecutorManager().cancel(jobId);
    } catch (Exception e1) {
      logger.error("Error cancelling job " + e1);
    }
       
        Collection<ExecutingJobAndInstance> executing = app.getJobExecutorManager().getExecutingJobs();
        for(ExecutingJobAndInstance curr: executing) {
            ExecutableFlow flow = curr.getExecutableFlow();
            final String flowId = flow.getId();
            if(flowId.equals(jobId)) {
                final String flowName = flow.getName();
                try {
                    if(flow.cancel()) {
                        addMessage(req, "Cancelled " + flowName);
                        logger.info("Job '" + flowName + "' cancelled from gui.");
                    } else {
                        logger.info("Couldn't cancel flow '" + flowName + "' for some reason.");
                        addError(req, "Failed to cancel flow " + flowName + ".");
                    }
                } catch(Exception e) {
                    logger.error("Exception while attempting to cancel flow '" + flowName + "'.", e);
                    addError(req, "Failed to cancel flow " + flowName + ": " + e.getMessage());
                }
            }
        }
    }

    private String scheduleJobs(AzkabanApplication app,
                              HttpServletRequest req,
                              HttpServletResponse resp) throws IOException, ServletException {
        String[] jobNames = req.getParameterValues("jobs");
        if(!hasParam(req, "jobs")) {
            addError(req, "You must select at least one job to run.");
            return "";
        }
       
        if (hasParam(req, "flow_now")) {
          if (jobNames.length > 1) {
            addError(req, "Can only run flow instance on one job.");
                return "";
          }
         
          String jobName = jobNames[0];
            JobManager jobManager = app.getJobManager();
            JobDescriptor descriptor = jobManager.getJobDescriptor(jobName);
            if (descriptor == null) {
              addError(req, "Can only run flow instance on one job.");
                return "";
            }
            else {
              return req.getContextPath() + "/flow?job_id=" + jobName;
            }
        }
        else {
          for(String job: jobNames) {
              if(hasParam(req, "schedule")) {
                  int hour = getIntParam(req, "hour");
                  int minutes = getIntParam(req, "minutes");
                  boolean isPm = getParam(req, "am_pm").equalsIgnoreCase("pm");
                  String scheduledDate = req.getParameter("date");
                  DateTime day = null;
                  if(scheduledDate == null || scheduledDate.trim().length() == 0) {
                    day = new LocalDateTime().toDateTime();
                  } else {
                    try {
                      day = DateTimeFormat.forPattern("MM-dd-yyyy").parseDateTime(scheduledDate);
                    } catch(IllegalArgumentException e) {
                      addError(req, "Invalid date: '" + scheduledDate + "'");
                      return "";
                    }
                  }
 
                  ReadablePeriod thePeriod = null;
                  if(hasParam(req, "is_recurring"))
                      thePeriod = parsePeriod(req);
 
                  if(isPm && hour < 12)
                      hour += 12;
                  hour %= 24;
 
                  app.getScheduleManager().schedule(job,
                            day.withHourOfDay(hour)
                            .withMinuteOfHour(minutes)
                            .withSecondOfMinute(0),
                         thePeriod,
                         false);

                  addMessage(req, job + " scheduled.");
              } else if(hasParam(req, "run_now")) {
                  boolean ignoreDeps = !hasParam(req, "include_deps");
                  try {
                    app.getJobExecutorManager().execute(job, ignoreDeps);
                  }
                  catch (JobExecutionException e) {
                    addError(req, e.getMessage())
                    return "";
                  }
                  addMessage(req, "Running " + job);
              }
              else {
                  addError(req, "Neither run_now nor schedule param is set.");
              }
          }
          return "";
        }

    }

    private ReadablePeriod parsePeriod(HttpServletRequest req) throws ServletException {
        int period = getIntParam(req, "period");
        String periodUnits = getParam(req, "period_units");
        if("d".equals(periodUnits))
            return Days.days(period);
        else if("h".equals(periodUnits))
            return Hours.hours(period);
        else if("m".equals(periodUnits))
            return Minutes.minutes(period);
        else if("s".equals(periodUnits))
            return Seconds.seconds(period);
        else
            throw new ServletException("Unknown period unit: " + periodUnits);
    }

}
TOP

Related Classes of azkaban.web.pages.IndexServlet$FlowComparator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.