Package eu.stratosphere.nephele.jobmanager.web

Source Code of eu.stratosphere.nephele.jobmanager.web.JobmanagerInfoServlet

/***********************************************************************************************************************
* Copyright (C) 2010-2013 by the Stratosphere project (http://stratosphere.eu)
*
* 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 eu.stratosphere.nephele.jobmanager.web;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jetty.io.EofException;

import eu.stratosphere.api.common.accumulators.AccumulatorHelper;
import eu.stratosphere.nephele.event.job.AbstractEvent;
import eu.stratosphere.nephele.event.job.ExecutionStateChangeEvent;
import eu.stratosphere.nephele.event.job.JobEvent;
import eu.stratosphere.nephele.event.job.RecentJobEvent;
import eu.stratosphere.nephele.execution.ExecutionState;
import eu.stratosphere.nephele.jobgraph.JobID;
import eu.stratosphere.nephele.jobgraph.JobStatus;
import eu.stratosphere.nephele.jobmanager.JobManager;
import eu.stratosphere.nephele.managementgraph.ManagementGraph;
import eu.stratosphere.nephele.managementgraph.ManagementGraphIterator;
import eu.stratosphere.nephele.managementgraph.ManagementGroupVertex;
import eu.stratosphere.nephele.managementgraph.ManagementGroupVertexID;
import eu.stratosphere.nephele.managementgraph.ManagementVertex;
import eu.stratosphere.nephele.services.accumulators.AccumulatorEvent;
import eu.stratosphere.util.StringUtils;


public class JobmanagerInfoServlet extends HttpServlet {
 
  private static final long serialVersionUID = 1L;
 
  /**
   * The log for this class.
   */
  private static final Log LOG = LogFactory.getLog(JobmanagerInfoServlet.class);
 
  /**
   * Underlying JobManager
   */
  private final JobManager jobmanager;
 
  public JobmanagerInfoServlet(JobManager jobmanager) {
    this.jobmanager = jobmanager;
  }
 
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     
    resp.setStatus(HttpServletResponse.SC_OK);
    resp.setContentType("application/json");
   
    try {
      if("archive".equals(req.getParameter("get"))) {
        writeJsonForArchive(resp.getWriter(), jobmanager.getOldJobs());
      }
      else if("job".equals(req.getParameter("get"))) {
        String jobId = req.getParameter("job");
        writeJsonForArchivedJob(resp.getWriter(), jobmanager.getArchive().getJob(JobID.fromHexString(jobId)));
      }
      else if("groupvertex".equals(req.getParameter("get"))) {
        String jobId = req.getParameter("job");
        String groupvertexId = req.getParameter("groupvertex");
        writeJsonForArchivedJobGroupvertex(resp.getWriter(), jobmanager.getArchive().getJob(JobID.fromHexString(jobId)), ManagementGroupVertexID.fromHexString(groupvertexId));
      }
      else if("taskmanagers".equals(req.getParameter("get"))) {
        resp.getWriter().write("{\"taskmanagers\": " + jobmanager.getNumberOfTaskTrackers() +"}");
      }
      else if("cancel".equals(req.getParameter("get"))) {
        String jobId = req.getParameter("job");
        jobmanager.cancelJob(JobID.fromHexString(jobId));
      }
      else if("updates".equals(req.getParameter("get"))) {
        String jobId = req.getParameter("job");
        writeJsonUpdatesForJob(resp.getWriter(), JobID.fromHexString(jobId));
      }
      else{
        writeJsonForJobs(resp.getWriter(), jobmanager.getRecentJobs());
      }
     
    } catch (Exception e) {
      resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
      resp.getWriter().print(e.getMessage());
      if (LOG.isWarnEnabled()) {
        LOG.warn(StringUtils.stringifyException(e));
      }
    }
  }
 
  /**
   * Writes ManagementGraph as Json for all recent jobs
   *
   * @param wrt
   * @param jobs
   */
  private void writeJsonForJobs(PrintWriter wrt, List<RecentJobEvent> jobs) {
   
    try {
   
      wrt.write("[");
     
      // Loop Jobs
      for (int i = 0; i < jobs.size(); i++) {
        RecentJobEvent jobEvent = jobs.get(i);
 
        writeJsonForJob(wrt, jobEvent);
 
        //Write seperator between json objects
        if(i != jobs.size() - 1) {
          wrt.write(",");
        }
      }
      wrt.write("]");
   
    } catch (EofException eof) { // Connection closed by client
      LOG.info("Info server for jobmanager: Connection closed by client, EofException");
    } catch (IOException ioe) { // Connection closed by client 
      LOG.info("Info server for jobmanager: Connection closed by client, IOException");
    }
   
  }
 
  private void writeJsonForJob(PrintWriter wrt, RecentJobEvent jobEvent) throws IOException {
   
    ManagementGraph jobManagementGraph = jobmanager.getManagementGraph(jobEvent.getJobID());
   
    //Serialize job to json
    wrt.write("{");
    wrt.write("\"jobid\": \"" + jobEvent.getJobID() + "\",");
    wrt.write("\"jobname\": \"" + jobEvent.getJobName()+"\",");
    wrt.write("\"status\": \""+ jobEvent.getJobStatus() + "\",");
    wrt.write("\"time\": " + jobEvent.getTimestamp()+",");
   
    // Serialize ManagementGraph to json
    wrt.write("\"groupvertices\": [");
    boolean first = true;
    for(ManagementGroupVertex groupVertex : jobManagementGraph.getGroupVerticesInTopologicalOrder()) {
      //Write seperator between json objects
      if(first) {
        first = false;
      } else {
        wrt.write(","); }
     
      wrt.write(groupVertex.toJson());
    }
    wrt.write("]");
    wrt.write("}");
     
  }
 
  /**
   * Writes Json with a list of currently archived jobs, sorted by time
   *
   * @param wrt
   * @param jobs
   */
  private void writeJsonForArchive(PrintWriter wrt, List<RecentJobEvent> jobs) {
   
    wrt.write("[");
   
    // sort jobs by time
    Collections.sort(jobs,  new Comparator<RecentJobEvent>() {
      @Override
      public int compare(RecentJobEvent o1, RecentJobEvent o2) {
        if(o1.getTimestamp() < o2.getTimestamp()) {
          return 1;
        } else {
          return -1;
        }
      }
     
    });
   
    // Loop Jobs
    for (int i = 0; i < jobs.size(); i++) {
      RecentJobEvent jobEvent = jobs.get(i);
     
      //Serialize job to json
      wrt.write("{");
      wrt.write("\"jobid\": \"" + jobEvent.getJobID() + "\",");
      wrt.write("\"jobname\": \"" + jobEvent.getJobName()+"\",");
      wrt.write("\"status\": \""+ jobEvent.getJobStatus() + "\",");
      wrt.write("\"time\": " + jobEvent.getTimestamp());
     
      wrt.write("}");
     
      //Write seperator between json objects
      if(i != jobs.size() - 1) {
        wrt.write(",");
      }
    }
    wrt.write("]");
   
  }
 
  /**
   * Writes infos about archived job in Json format, including groupvertices and groupverticetimes
   *
   * @param wrt
   * @param jobEvent
   */
  private void writeJsonForArchivedJob(PrintWriter wrt, RecentJobEvent jobEvent) {
   
    try {
   
      wrt.write("[");
   
      ManagementGraph jobManagementGraph = jobmanager.getManagementGraph(jobEvent.getJobID());
     
      //Serialize job to json
      wrt.write("{");
      wrt.write("\"jobid\": \"" + jobEvent.getJobID() + "\",");
      wrt.write("\"jobname\": \"" + jobEvent.getJobName()+"\",");
      wrt.write("\"status\": \""+ jobEvent.getJobStatus() + "\",");
      wrt.write("\"SCHEDULED\": "+ jobmanager.getArchive().getJobTime(jobEvent.getJobID(), JobStatus.SCHEDULED) + ",");
      wrt.write("\"RUNNING\": "+ jobmanager.getArchive().getJobTime(jobEvent.getJobID(), JobStatus.RUNNING) + ",");
      wrt.write("\"FINISHED\": "+ jobmanager.getArchive().getJobTime(jobEvent.getJobID(), JobStatus.FINISHED) + ",");
      wrt.write("\"FAILED\": "+ jobmanager.getArchive().getJobTime(jobEvent.getJobID(), JobStatus.FAILED) + ",");
      wrt.write("\"CANCELED\": "+ jobmanager.getArchive().getJobTime(jobEvent.getJobID(), JobStatus.CANCELED) + ",");
      wrt.write("\"CREATED\": " + jobmanager.getArchive().getJobTime(jobEvent.getJobID(), JobStatus.CREATED)+",");

      if (jobEvent.getJobStatus() == JobStatus.FAILED) {
      ManagementGraphIterator managementGraphIterator =  new ManagementGraphIterator(jobManagementGraph,true);
      wrt.write("\"failednodes\": [");
      HashSet<String> map = new HashSet<String>();
      boolean first = true;
      while (managementGraphIterator.hasNext()) {
        ManagementVertex managementVertex = managementGraphIterator.next();
        String instanceName = managementVertex.getInstanceName();
        if (managementVertex.getExecutionState() == ExecutionState.FAILED && !map.contains(instanceName)) {
          if (first) {
            first = false;
          } else {
            wrt.write(",");
          }
          wrt.write("{");
          wrt.write("\"node\": \"" + instanceName + "\",");
          wrt.write("\"message\": \"" + StringUtils.escapeHtml(managementVertex.getOptMessage()) + "\"");
          wrt.write("}");
          map.add(instanceName);
        }
      }
      wrt.write("],");
      }

      // Serialize ManagementGraph to json
      wrt.write("\"groupvertices\": [");
      boolean first = true;
      for(ManagementGroupVertex groupVertex : jobManagementGraph.getGroupVerticesInTopologicalOrder()) {
        //Write seperator between json objects
        if(first) {
          first = false;
        } else {
          wrt.write(","); }
       
        wrt.write(groupVertex.toJson());
       
      }
      wrt.write("],");
     
      // write accumulators
      AccumulatorEvent accumulators = jobmanager.getAccumulatorResults(jobEvent.getJobID());
      Map<String, Object> accMap = AccumulatorHelper.toResultMap(accumulators.getAccumulators());
     
      wrt.write("\n\"accumulators\": [");
      int i = 0;
      for( Entry<String, Object> accumulator : accMap.entrySet()) {
        wrt.write("{ \"name\": \""+accumulator.getKey()+" (" + accumulator.getValue().getClass().getName()+")\","
            + " \"value\": \""+accumulator.getValue().toString()+"\"}\n");
        if(++i < accMap.size()) {
          wrt.write(",");
        }
      }
      wrt.write("],\n");
     
      wrt.write("\"groupverticetimes\": {");
      first = true;
      for(ManagementGroupVertex groupVertex : jobManagementGraph.getGroupVerticesInTopologicalOrder()) {
       
        if(first) {
          first = false;
        } else {
          wrt.write(","); }
       
        // Calculate start and end time for groupvertex
        long started = Long.MAX_VALUE;
        long ended = 0;
       
        // Take earliest running state and latest endstate of groupmembers
        for(int j = 0; j < groupVertex.getNumberOfGroupMembers(); j++) {
          ManagementVertex vertex = groupVertex.getGroupMember(j);
         
          long running = jobmanager.getArchive().getVertexTime(jobEvent.getJobID(), vertex.getID(), ExecutionState.RUNNING);
          if(running != 0 && running < started) {
            started = running;
          }
         
          long finished = jobmanager.getArchive().getVertexTime(jobEvent.getJobID(), vertex.getID(), ExecutionState.FINISHED);
          long canceled = jobmanager.getArchive().getVertexTime(jobEvent.getJobID(), vertex.getID(), ExecutionState.CANCELED);
          long failed = jobmanager.getArchive().getVertexTime(jobEvent.getJobID(), vertex.getID(), ExecutionState.FAILED);
         
          if(finished != 0 && finished > ended) {
            ended = finished;
          }
         
          if(canceled != 0 && canceled > ended) {
            ended = canceled;
          }
         
          if(failed != 0 && failed > ended) {
            ended = failed;
          }

        }
       
        wrt.write("\""+groupVertex.getID()+"\": {");
        wrt.write("\"groupvertexid\": \"" + groupVertex.getID() + "\",");
        wrt.write("\"groupvertexname\": \"" + groupVertex + "\",");
        wrt.write("\"STARTED\": "+ started + ",");
        wrt.write("\"ENDED\": "+ ended);
        wrt.write("}");
       
      }

      wrt.write("}");
     
      wrt.write("}");
     
     
    wrt.write("]");
   
    } catch (EofException eof) { // Connection closed by client
      LOG.info("Info server for jobmanager: Connection closed by client, EofException");
    } catch (IOException ioe) { // Connection closed by client 
      LOG.info("Info server for jobmanager: Connection closed by client, IOException");
    }
   
  }
 
 
  /**
   * Writes all updates (events) for a given job since a given time
   *
   * @param wrt
   * @param jobId
   */
  private void writeJsonUpdatesForJob(PrintWriter wrt, JobID jobId) {
   
    try {
     
      List<AbstractEvent> events = jobmanager.getEvents(jobId);
     
      //Serialize job to json
      wrt.write("{");
      wrt.write("\"jobid\": \"" + jobId + "\",");
      wrt.write("\"timestamp\": \"" + System.currentTimeMillis() + "\",");
      wrt.write("\"recentjobs\": [");
       
      boolean first = true;
      for(RecentJobEvent rje: jobmanager.getRecentJobs()) {
        if(first) {
          first = false;
        } else {
          wrt.write(","); }
       
        wrt.write("\""+rje.getJobID().toString()+"\"");
      }
         
      wrt.write("],");
     
      wrt.write("\"vertexevents\": [");
   
      first = true;
      for(AbstractEvent event: events) {
       
        if(event instanceof ExecutionStateChangeEvent) {
         
          if(first) {
            first = false;
          } else {
            wrt.write(","); }
         
          ExecutionStateChangeEvent vertexevent = (ExecutionStateChangeEvent) event;
          wrt.write("{");
          wrt.write("\"vertexid\": \"" + vertexevent.getVertexID() + "\",");
          wrt.write("\"newstate\": \"" + vertexevent.getNewExecutionState() + "\",");
          wrt.write("\"timestamp\": \"" + vertexevent.getTimestamp() + "\"");
          wrt.write("}");
        }
      }
     
      wrt.write("],");
     
      wrt.write("\"jobevents\": [");
     
      first = true;
      for(AbstractEvent event: events) {
       
        if( event instanceof JobEvent) {
         
          if(first) {
            first = false;
          } else {
            wrt.write(","); }
         
          JobEvent jobevent = (JobEvent) event;
          wrt.write("{");
          wrt.write("\"newstate\": \"" + jobevent.getCurrentJobStatus() + "\",");
          wrt.write("\"timestamp\": \"" + jobevent.getTimestamp() + "\"");
          wrt.write("}");
        }
      }
     
      wrt.write("]");
     
      wrt.write("}");
     
   
    } catch (EofException eof) { // Connection closed by client
      LOG.info("Info server for jobmanager: Connection closed by client, EofException");
    } catch (IOException ioe) { // Connection closed by client 
      LOG.info("Info server for jobmanager: Connection closed by client, IOException");
    }
   
  }
 
  /**
   * Writes infos about one particular archived groupvertex in a job, including all groupmembers, their times and status
   *
   * @param wrt
   * @param jobEvent
   * @param groupvertexId
   */
  private void writeJsonForArchivedJobGroupvertex(PrintWriter wrt, RecentJobEvent jobEvent, ManagementGroupVertexID groupvertexId) {
   
   
    try {
   
    ManagementGraph jobManagementGraph = jobmanager.getManagementGraph(jobEvent.getJobID());
   
    ManagementGroupVertex groupvertex = jobManagementGraph.getGroupVertexByID(groupvertexId);
   
    // Serialize ManagementGraph to json
    wrt.write("{\"groupvertex\": "+groupvertex.toJson()+",");
   
    wrt.write("\"verticetimes\": {");
    boolean first = true;
    for(ManagementGroupVertex groupVertex : jobManagementGraph.getGroupVerticesInTopologicalOrder()) {
     
      for(int j = 0; j < groupVertex.getNumberOfGroupMembers(); j++) {
        ManagementVertex vertex = groupVertex.getGroupMember(j);
       
        if(first) {
          first = false;
        } else {
          wrt.write(","); }
       
        wrt.write("\""+vertex.getID()+"\": {");
        wrt.write("\"vertexid\": \"" + vertex.getID() + "\",");
        wrt.write("\"vertexname\": \"" + vertex + "\",");
        wrt.write("\"CREATED\": "+ jobmanager.getArchive().getVertexTime(jobEvent.getJobID(), vertex.getID(), ExecutionState.CREATED) + ",");
        wrt.write("\"SCHEDULED\": "+ jobmanager.getArchive().getVertexTime(jobEvent.getJobID(), vertex.getID(), ExecutionState.SCHEDULED) + ",");
        wrt.write("\"ASSIGNED\": "+ jobmanager.getArchive().getVertexTime(jobEvent.getJobID(), vertex.getID(), ExecutionState.ASSIGNED) + ",");
        wrt.write("\"READY\": "+ jobmanager.getArchive().getVertexTime(jobEvent.getJobID(), vertex.getID(), ExecutionState.READY) + ",");
        wrt.write("\"STARTING\": "+ jobmanager.getArchive().getVertexTime(jobEvent.getJobID(), vertex.getID(), ExecutionState.STARTING) + ",");
        wrt.write("\"RUNNING\": "+ jobmanager.getArchive().getVertexTime(jobEvent.getJobID(), vertex.getID(), ExecutionState.RUNNING) + ",");
        wrt.write("\"FINISHING\": "+ jobmanager.getArchive().getVertexTime(jobEvent.getJobID(), vertex.getID(), ExecutionState.FINISHING) + ",");
        wrt.write("\"FINISHED\": "+ jobmanager.getArchive().getVertexTime(jobEvent.getJobID(), vertex.getID(), ExecutionState.FINISHED) + ",");
        wrt.write("\"CANCELING\": "+ jobmanager.getArchive().getVertexTime(jobEvent.getJobID(), vertex.getID(), ExecutionState.CANCELING) + ",");
        wrt.write("\"CANCELED\": "+ jobmanager.getArchive().getVertexTime(jobEvent.getJobID(), vertex.getID(), ExecutionState.CANCELED) + ",");
        wrt.write("\"FAILED\": "+ jobmanager.getArchive().getVertexTime(jobEvent.getJobID(), vertex.getID(), ExecutionState.FAILED) + "");
        wrt.write("}");
      }
     
    }
    wrt.write("}}");
   
  } catch (EofException eof) { // Connection closed by client
    LOG.info("Info server for jobmanager: Connection closed by client, EofException");
  } catch (IOException ioe) { // Connection closed by client 
    LOG.info("Info server for jobmanager: Connection closed by client, IOException");
  }
   
  }
}
TOP

Related Classes of eu.stratosphere.nephele.jobmanager.web.JobmanagerInfoServlet

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.