aurora-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ma...@apache.org
Subject [03/15] Role and Job pages using new Angular UI.
Date Tue, 22 Apr 2014 17:59:47 GMT
http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/88d25ed9/src/main/java/org/apache/aurora/scheduler/http/SchedulerzJob.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/http/SchedulerzJob.java b/src/main/java/org/apache/aurora/scheduler/http/SchedulerzJob.java
deleted file mode 100644
index f0469c1..0000000
--- a/src/main/java/org/apache/aurora/scheduler/http/SchedulerzJob.java
+++ /dev/null
@@ -1,425 +0,0 @@
-/**
- * Copyright 2013 Apache Software Foundation
- *
- * 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 org.apache.aurora.scheduler.http;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.inject.Inject;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
-import com.google.common.base.Optional;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.HashBiMap;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSortedSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Multimaps;
-import com.google.common.collect.Ordering;
-import com.twitter.common.base.Closure;
-
-import org.antlr.stringtemplate.StringTemplate;
-import org.apache.aurora.gen.ScheduleStatus;
-import org.apache.aurora.gen.apiConstants;
-import org.apache.aurora.scheduler.base.JobKeys;
-import org.apache.aurora.scheduler.base.Query;
-import org.apache.aurora.scheduler.base.Tasks;
-import org.apache.aurora.scheduler.filter.SchedulingFilter.Veto;
-import org.apache.aurora.scheduler.metadata.NearestFit;
-import org.apache.aurora.scheduler.state.CronJobManager;
-import org.apache.aurora.scheduler.storage.Storage;
-import org.apache.aurora.scheduler.storage.entities.IAssignedTask;
-import org.apache.aurora.scheduler.storage.entities.IConstraint;
-import org.apache.aurora.scheduler.storage.entities.IJobKey;
-import org.apache.aurora.scheduler.storage.entities.IScheduledTask;
-import org.apache.aurora.scheduler.storage.entities.IServerInfo;
-import org.apache.aurora.scheduler.storage.entities.ITaskConfig;
-import org.apache.aurora.scheduler.storage.entities.ITaskConstraint;
-import org.apache.aurora.scheduler.storage.entities.ITaskEvent;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.twitter.common.base.MorePreconditions.checkNotBlank;
-
-import static org.apache.aurora.gen.ScheduleStatus.ASSIGNED;
-import static org.apache.aurora.gen.ScheduleStatus.FAILED;
-import static org.apache.aurora.gen.ScheduleStatus.FINISHED;
-import static org.apache.aurora.gen.ScheduleStatus.KILLED;
-import static org.apache.aurora.gen.ScheduleStatus.KILLING;
-import static org.apache.aurora.gen.ScheduleStatus.LOST;
-import static org.apache.aurora.gen.ScheduleStatus.PENDING;
-import static org.apache.aurora.gen.ScheduleStatus.RUNNING;
-import static org.apache.aurora.gen.ScheduleStatus.SANDBOX_DELETED;
-import static org.apache.aurora.gen.ScheduleStatus.STARTING;
-
-/**
- * HTTP interface to view information about a job in the aurora scheduler.
- */
-@Path("/scheduler/{role}/{environment}/{job}")
-public class SchedulerzJob extends JerseyTemplateServlet {
-  private static final String STATUS_FILTER_PARAM = "status";
-  private static final String ADMIN_VIEW_PARAM = "admin";
-
-  // Pagination controls.
-  private static final String OFFSET_PARAM = "o";
-  private static final int PAGE_SIZE = 50;
-
-  private static final Ordering<IScheduledTask> INSTANCE_ID_COMPARATOR =
-    Ordering.natural().onResultOf(Tasks.SCHEDULED_TO_INSTANCE_ID);
-
-  private static final Map<ScheduleStatus, Set<ScheduleStatus>> FILTER_MAP =
-      ImmutableMap.<ScheduleStatus, Set<ScheduleStatus>>builder()
-        .put(PENDING, EnumSet.of(PENDING))
-        .put(RUNNING, EnumSet.of(ASSIGNED, STARTING, RUNNING, KILLING))
-        // Note: SANDBOX_DELETED can be issued for both FINISHED and FAILED states.
-        // Adding a post-processing filtering to place it into the right bucket may be needed.
-        .put(FINISHED, EnumSet.of(KILLED, FINISHED, SANDBOX_DELETED))
-        .put(FAILED, EnumSet.of(LOST, FAILED))
-      .build();
-
-  private static final Function<Veto, String> GET_REASON = new Function<Veto, String>() {
-    @Override
-    public String apply(Veto veto) {
-      return veto.getReason();
-    }
-  };
-
-  // Double percents to escape formatting sequence.
-  private static final String PORT_FORMAT = "%%port:%s%%";
-  // TODO(William Farner): Search for usage of this, figure out a deprecation strategy to switch
-  //                       to %instance_id%.
-  private static final String INSTANCE_ID_REGEXP = "%shard_id%";
-  private static final String TASK_ID_REGEXP = "%task_id%";
-  private static final String HOST_REGEXP = "%host%";
-
-  private static String expandText(String value, IAssignedTask task) {
-    String expanded = value
-        .replaceAll(INSTANCE_ID_REGEXP, String.valueOf(task.getInstanceId()))
-        .replaceAll(TASK_ID_REGEXP, task.getTaskId());
-
-    if (task.isSetSlaveHost()) {
-      expanded = expanded.replaceAll(HOST_REGEXP, task.getSlaveHost());
-    }
-
-    // Expand ports.
-    if (task.isSetAssignedPorts()) {
-      for (Map.Entry<String, Integer> portEntry : task.getAssignedPorts().entrySet()) {
-        expanded = expanded.replaceAll(
-            String.format(PORT_FORMAT, portEntry.getKey()),
-            String.valueOf(portEntry.getValue()));
-      }
-    }
-
-    return expanded;
-  }
-
-  private final Function<IScheduledTask, Map<String, Object>> taskToStringMap =
-      new Function<IScheduledTask, Map<String, Object>>() {
-        @Override
-        public Map<String, Object> apply(IScheduledTask scheduledTask) {
-          final IAssignedTask task = scheduledTask.getAssignedTask();
-          ImmutableMap.Builder<String, Object> builder = ImmutableMap.<String, Object>builder()
-            .put("taskId", task.getTaskId())
-            .put("instanceId", task.getInstanceId())
-            .put("slaveHost", task.isSetSlaveHost() ? task.getSlaveHost() : "")
-            .put("taskEvents", scheduledTask.getTaskEvents());
-
-          ITaskEvent statusEvent = Tasks.getLatestEvent(scheduledTask);
-
-          if (scheduledTask.getStatus() == SANDBOX_DELETED) {
-            // Avoid displaying SANDBOX_DELETED as completed status.
-            statusEvent = Tasks.getSecondToLatestEvent(scheduledTask);
-            builder.put("hideExecutorUri", true);
-          } else if (scheduledTask.getStatus() == PENDING) {
-            String pendingReason;
-            Set<Veto> vetoes = nearestFit.getNearestFit(task.getTaskId());
-            if (vetoes.isEmpty()) {
-              pendingReason = "No matching hosts.";
-            } else {
-              pendingReason = Joiner.on(",").join(Iterables.transform(vetoes, GET_REASON));
-            }
-            builder.put("pendingReason", pendingReason);
-          }
-
-          builder.put("status", statusEvent.getStatus());
-          builder.put("statusTimestamp", statusEvent.getTimestamp());
-
-          Function<String, String> expander = new Function<String, String>() {
-            @Override
-            public String apply(String input) {
-              return expandText(input, task);
-            }
-          };
-
-          Map<String, String> links = ImmutableMap.of();
-          if (apiConstants.LIVE_STATES.contains(scheduledTask.getStatus())) {
-            links =
-                ImmutableMap.copyOf(Maps.transformValues(task.getTask().getTaskLinks(), expander));
-          }
-          builder.put("links", links);
-          builder.put("executorPort", 1338);
-          if (task.isSetSlaveHost()) {
-            builder.put("executorUri",
-                "http://" + task.getSlaveHost() + ":1338/task/" + task.getTaskId());
-          }
-          return builder.build();
-        }
-      };
-
-  private final Storage storage;
-  private final String clusterName;
-  private final NearestFit nearestFit;
-  private final CronJobManager cronJobManager;
-
-  /**
-   * Creates a new job servlet.
-   *
-   * @param storage a reference to scheduler storage.
-   */
-  @Inject
-  public SchedulerzJob(
-      Storage storage,
-      CronJobManager cronJobManager,
-      IServerInfo serverInfo,
-      NearestFit nearestFit) {
-
-    super("schedulerzjob");
-    this.storage = checkNotNull(storage);
-    this.clusterName = checkNotBlank(serverInfo.getClusterName());
-    this.nearestFit = checkNotNull(nearestFit);
-    this.cronJobManager = checkNotNull(cronJobManager);
-  }
-
-  private static <T> Iterable<T> offsetAndLimit(Iterable<T> iterable, int offset) {
-    return ImmutableList.copyOf(Iterables.limit(Iterables.skip(iterable, offset), PAGE_SIZE));
-  }
-
-  private static String scaleMb(long mb) {
-    return (mb >= 1024) ? ((mb / 1024) + " GiB") : (mb + " MiB");
-  }
-
-  private static final Function<IConstraint, String> DISPLAY_CONSTRAINT =
-      new Function<IConstraint, String>() {
-        @Override
-        public String apply(IConstraint constraint) {
-          StringBuilder sb = new StringBuilder().append(constraint.getName()).append(": ");
-          ITaskConstraint taskConstraint = constraint.getConstraint();
-          switch (taskConstraint.getSetField()) {
-            case VALUE:
-              if (taskConstraint.getValue().isNegated()) {
-                sb.append("not ");
-              }
-              sb.append(Joiner.on(", ").join(taskConstraint.getValue().getValues()));
-              break;
-
-            case LIMIT:
-              sb.append("limit ").append(taskConstraint.getLimit().getLimit());
-              break;
-
-            default:
-              sb.append("Unhandled constraint type " + taskConstraint.getSetField());
-          }
-
-          return sb.toString();
-        }
-      };
-
-  private static final Function<ITaskConfig, SchedulingDetails> CONFIG_TO_DETAILS =
-      new Function<ITaskConfig, SchedulingDetails>() {
-        @Override
-        public SchedulingDetails apply(ITaskConfig task) {
-          String resources = Joiner.on(", ").join(
-              "cpu: " + task.getNumCpus(),
-              "ram: " + scaleMb(task.getRamMb()),
-              "disk: " + scaleMb(task.getDiskMb()));
-          ImmutableMap.Builder<String, Object> details = ImmutableMap.<String, Object>builder()
-              .put("resources", resources);
-          if (!task.getConstraints().isEmpty()) {
-            Iterable<String> displayConstraints = FluentIterable.from(task.getConstraints())
-                .transform(DISPLAY_CONSTRAINT)
-                .toSortedList(Ordering.<String>natural());
-            details.put("constraints", Joiner.on(", ").join(displayConstraints));
-          }
-          if (task.isIsService()) {
-            details.put("service", "true");
-          }
-          if (task.isProduction()) {
-            details.put("production", "true");
-          }
-          if (!task.getRequestedPorts().isEmpty()) {
-            details.put("ports",
-                Joiner.on(", ").join(ImmutableSortedSet.copyOf(task.getRequestedPorts())));
-          }
-          Optional<String> metadata = TransformationUtils.getMetadata(task);
-          if (metadata.isPresent()) {
-            details.put("metadata", metadata.get());
-          }
-          details.put("contact", task.isSetContactEmail() ? task.getContactEmail() : "none");
-          return new SchedulingDetails(details.build());
-        }
-      };
-
-  static class SchedulingDetails {
-    private final Map<String, Object> details;
-
-    SchedulingDetails(ImmutableMap<String, Object> details) {
-      this.details = details;
-    }
-
-    public Map<String, Object> getDetails() {
-      return details;
-    }
-
-    @Override
-    public int hashCode() {
-      return details.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object o) {
-      if (!(o instanceof SchedulingDetails)) {
-        return false;
-      }
-
-      SchedulingDetails other = (SchedulingDetails) o;
-      return other.details.equals(details);
-    }
-  }
-
-
-
-  private static Map<String, SchedulingDetails> buildSchedulingTable(
-      Iterable<IAssignedTask> tasks) {
-
-    Map<Integer, ITaskConfig> byInstance = Maps.transformValues(
-        Maps.uniqueIndex(tasks, Tasks.ASSIGNED_TO_INSTANCE_ID),
-        Tasks.ASSIGNED_TO_INFO);
-    Map<Integer, SchedulingDetails> detailsByInstance =
-        Maps.transformValues(byInstance, CONFIG_TO_DETAILS);
-    Multimap<SchedulingDetails, Integer> instancesByDetails = Multimaps.invertFrom(
-        Multimaps.forMap(detailsByInstance), HashMultimap.<SchedulingDetails, Integer>create());
-    Map<SchedulingDetails, String> instanceStringsByDetails =
-        Maps.transformValues(instancesByDetails.asMap(), TransformationUtils.INSTANCES_TOSTRING);
-    return HashBiMap.create(instanceStringsByDetails).inverse();
-  }
-
-  /**
-   * Fetches the landing page for a job within a role.
-   *
-   * @return HTTP response.
-   */
-  @GET
-  @Produces(MediaType.TEXT_HTML)
-  public Response get(
-      @PathParam("role") final String role,
-      @PathParam("environment") final String environment,
-      @PathParam("job") final String job,
-      @QueryParam(OFFSET_PARAM) final int offset,
-      @QueryParam(STATUS_FILTER_PARAM) final String filterArg,
-      @QueryParam(ADMIN_VIEW_PARAM) final String adminView) {
-
-    return fillTemplate(new Closure<StringTemplate>() {
-      @Override
-      public void execute(StringTemplate template) {
-        template.setAttribute("cluster_name", clusterName);
-        template.setAttribute(ADMIN_VIEW_PARAM, adminView != null);
-        IJobKey jobKey = JobKeys.from(role, environment, job);
-
-        boolean isCron = cronJobManager.hasJob(jobKey);
-        template.setAttribute("is_cron", isCron);
-
-        ScheduleStatus statusFilter = null;
-        if (filterArg != null) {
-          template.setAttribute(STATUS_FILTER_PARAM, filterArg);
-
-          try {
-            statusFilter = ScheduleStatus.valueOf(filterArg.toUpperCase());
-          } catch (IllegalArgumentException e) {
-            template.setAttribute("exception", "Invalid status type: " + filterArg);
-            return;
-          }
-        }
-
-        template.setAttribute("role", role);
-        template.setAttribute("environment", environment);
-        template.setAttribute("job", job);
-        template.setAttribute("statsUrl", DisplayUtils.getJobDashboardUrl(jobKey));
-        boolean hasMore = false;
-
-        Query.Builder builder = Query.jobScoped(JobKeys.from(role, environment, job));
-
-        Optional<Query.Builder> activeQuery = Optional.absent();
-        Optional<Query.Builder> completedQuery = Optional.absent();
-        if (statusFilter != null) {
-          Collection<ScheduleStatus> queryStatuses = FILTER_MAP.get(statusFilter);
-          if (Tasks.isActive(statusFilter)) {
-            activeQuery = Optional.of(builder.byStatus(queryStatuses));
-          } else {
-            completedQuery = Optional.of(builder.byStatus(queryStatuses));
-          }
-        } else {
-          activeQuery = Optional.of(builder.active());
-          completedQuery = Optional.of(builder.terminal());
-        }
-
-        if (activeQuery.isPresent()) {
-          Set<IScheduledTask> activeTasks =
-              Storage.Util.weaklyConsistentFetchTasks(storage, activeQuery.get());
-          List<IScheduledTask> liveTasks = INSTANCE_ID_COMPARATOR.sortedCopy(activeTasks);
-          template.setAttribute("activeTasks",
-              ImmutableList.copyOf(
-                  Iterables.transform(offsetAndLimit(liveTasks, offset), taskToStringMap)));
-          hasMore = hasMore || (liveTasks.size() > (offset + PAGE_SIZE));
-          template.setAttribute("schedulingDetails",
-              buildSchedulingTable(Iterables.transform(liveTasks, Tasks.SCHEDULED_TO_ASSIGNED)));
-        }
-        if (completedQuery.isPresent()) {
-          List<IScheduledTask> completedTasks = Lists.newArrayList(
-              Storage.Util.weaklyConsistentFetchTasks(storage, completedQuery.get()));
-          Collections.sort(completedTasks, Tasks.LATEST_ACTIVITY.reverse());
-          template.setAttribute("completedTasks",
-              ImmutableList.copyOf(
-                  Iterables.transform(offsetAndLimit(completedTasks, offset), taskToStringMap)));
-          hasMore = hasMore || (completedTasks.size() > (offset + PAGE_SIZE));
-        }
-
-        template.setAttribute("offset", offset);
-        if (offset > 0) {
-          template.setAttribute("prevOffset", Math.max(0, offset - PAGE_SIZE));
-        }
-        if (hasMore) {
-          template.setAttribute("nextOffset", offset + PAGE_SIZE);
-        }
-      }
-    });
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/88d25ed9/src/main/java/org/apache/aurora/scheduler/http/SchedulerzRole.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/http/SchedulerzRole.java b/src/main/java/org/apache/aurora/scheduler/http/SchedulerzRole.java
deleted file mode 100644
index e2f9ed0..0000000
--- a/src/main/java/org/apache/aurora/scheduler/http/SchedulerzRole.java
+++ /dev/null
@@ -1,338 +0,0 @@
-/**
- * Copyright 2013 Apache Software Foundation
- *
- * 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 org.apache.aurora.scheduler.http;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
-
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import com.twitter.common.base.Closure;
-
-import org.antlr.stringtemplate.StringTemplate;
-import org.apache.aurora.gen.CronCollisionPolicy;
-import org.apache.aurora.scheduler.base.JobKeys;
-import org.apache.aurora.scheduler.base.Jobs;
-import org.apache.aurora.scheduler.base.Query;
-import org.apache.aurora.scheduler.base.Tasks;
-import org.apache.aurora.scheduler.cron.CronPredictor;
-import org.apache.aurora.scheduler.quota.QuotaInfo;
-import org.apache.aurora.scheduler.quota.QuotaManager;
-import org.apache.aurora.scheduler.state.CronJobManager;
-import org.apache.aurora.scheduler.storage.Storage;
-import org.apache.aurora.scheduler.storage.entities.IJobConfiguration;
-import org.apache.aurora.scheduler.storage.entities.IJobKey;
-import org.apache.aurora.scheduler.storage.entities.IJobStats;
-import org.apache.aurora.scheduler.storage.entities.IScheduledTask;
-import org.apache.aurora.scheduler.storage.entities.IServerInfo;
-import org.apache.aurora.scheduler.storage.entities.ITaskConfig;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.twitter.common.base.MorePreconditions.checkNotBlank;
-
-import static org.apache.aurora.scheduler.base.Tasks.getLatestActiveTask;
-
-/**
- * HTTP interface to provide information about jobs for a specific role.
- */
-@Path("/scheduler/{role}")
-public class SchedulerzRole extends JerseyTemplateServlet {
-
-  private final Storage storage;
-  private final CronJobManager cronJobManager;
-  private final CronPredictor cronPredictor;
-  private final String clusterName;
-  private final QuotaManager quotaManager;
-
-  @Inject
-  SchedulerzRole(
-      Storage storage,
-      CronJobManager cronJobManager,
-      CronPredictor cronPredictor,
-      IServerInfo serverInfo,
-      QuotaManager quotaManager) {
-
-    super("schedulerzrole");
-    this.storage = checkNotNull(storage);
-    this.cronJobManager = checkNotNull(cronJobManager);
-    this.cronPredictor = checkNotNull(cronPredictor);
-    this.clusterName = checkNotBlank(serverInfo.getClusterName());
-    this.quotaManager = checkNotNull(quotaManager);
-  }
-
-  /**
-   * Fetches the landing page for a role.
-   *
-   * @return HTTP response.
-   */
-  @GET
-  @Produces(MediaType.TEXT_HTML)
-  public Response get(@PathParam("role") final String role) {
-    return processRequest(Optional.of(role), Optional.<String>absent());
-  }
-
-  private Response processRequest(final Optional<String> role, final Optional<String> environment) {
-    return fillTemplate(new Closure<StringTemplate>() {
-      @Override
-      public void execute(StringTemplate template) {
-
-        if (!role.isPresent()) {
-          template.setAttribute("exception", "Please specify a user.");
-          return;
-        }
-
-        Map<IJobKey, Map<?, ?>> cronJobs = fetchCronJobsBy(role.get(), environment);
-        List<Job> jobs = fetchJobsBy(role.get(), environment, cronJobs);
-        if (jobs.isEmpty() && cronJobs.isEmpty()) {
-          String msg = "No jobs found for role " + role.get()
-              + (environment.isPresent() ? (" and environment " + environment.get()) : "");
-          throw new WebApplicationException(Response.status(Status.NOT_FOUND).entity(msg).build());
-        }
-
-        template.setAttribute("cluster_name", clusterName);
-        template.setAttribute("role", role.get());
-        template.setAttribute("environment", environment.orNull());
-        template.setAttribute("jobs", jobs);
-        template.setAttribute("cronJobs", cronJobs.values());
-
-        // TODO(Suman Karumuri): In future compute consumption for role and environment.
-        QuotaInfo quotaInfo = quotaManager.getQuotaInfo(role.get());
-        template.setAttribute("prodResourcesUsed", quotaInfo.prodConsumption());
-        template.setAttribute("nonProdResourcesUsed", quotaInfo.nonProdConsumption());
-        template.setAttribute("resourceQuota", quotaInfo.guota());
-      }
-    });
-  }
-
-  /**
-   * Display jobs for a role and environment.
-   */
-  @Path("/{environment}")
-  @GET
-  @Produces(MediaType.TEXT_HTML)
-  public Response get(
-      @PathParam("role") final String role,
-      @PathParam("environment") final String environment) {
-
-    Optional<String> env = Optional.of(environment);
-    if (env.isPresent() && env.get().isEmpty()) {
-      env = Optional.absent();
-    }
-
-    return processRequest(Optional.of(role), env);
-  }
-
-  private Map<IJobKey, Map<?, ?>> fetchCronJobsBy(
-      final String role,
-      final Optional<String> environment) {
-
-    Predicate<IJobConfiguration> byRoleEnv = new Predicate<IJobConfiguration>() {
-      @Override
-      public boolean apply(IJobConfiguration job) {
-        boolean roleMatch = job.getOwner().getRole().equals(role);
-        boolean envMatch = !environment.isPresent()
-            || job.getKey().getEnvironment().equals(environment.get());
-        return roleMatch && envMatch;
-      }
-    };
-
-    Iterable<IJobConfiguration> jobs = FluentIterable
-        .from(cronJobManager.getJobs())
-        .filter(byRoleEnv);
-
-    return Maps.transformValues(Maps.uniqueIndex(jobs, JobKeys.FROM_CONFIG),
-        new Function<IJobConfiguration, Map<?, ?>>() {
-          @Override
-          public Map<?, ?> apply(IJobConfiguration job) {
-            return ImmutableMap.<Object, Object>builder()
-                .put("jobKey", job.getKey())
-                .put("name", job.getKey().getName())
-                .put("environment", job.getKey().getEnvironment())
-                .put("pendingTaskCount", job.getInstanceCount())
-                .put("cronSchedule", job.getCronSchedule())
-                .put("nextRun", cronPredictor.predictNextRun(job.getCronSchedule()).getTime())
-                .put("cronCollisionPolicy", cronCollisionPolicy(job))
-                .put("metadata", getMetadata(job))
-                .build();
-          }
-        });
-  }
-
-  private static CronCollisionPolicy cronCollisionPolicy(IJobConfiguration jobConfiguration) {
-    return CronJobManager.orDefault(jobConfiguration.getCronCollisionPolicy());
-  }
-
-  private static String getMetadata(IJobConfiguration job) {
-    Optional<String> metadata = TransformationUtils.getMetadata(job.getTaskConfig());
-    return metadata.isPresent() ? metadata.get() : "";
-  }
-
-  private List<Job> fetchJobsBy(
-      final String role,
-      final Optional<String> environment,
-      final Map<IJobKey, Map<?, ?>> cronJobs) {
-
-    final Function<Map.Entry<IJobKey, Collection<IScheduledTask>>, Job> toJob =
-        new Function<Map.Entry<IJobKey, Collection<IScheduledTask>>, Job>() {
-          @Override
-          public Job apply(Map.Entry<IJobKey, Collection<IScheduledTask>> tasksByJobKey) {
-            IJobKey jobKey = tasksByJobKey.getKey();
-            Collection<IScheduledTask> tasks = tasksByJobKey.getValue();
-
-            // Pick the freshest task's config and associate it with the job.
-            ITaskConfig mostRecentTaskConfig =
-                getLatestActiveTask(tasks).getAssignedTask().getTask();
-
-            JobType jobType;
-            // TODO(Suman Karumuri): Add a source/job type to TaskConfig and replace logic below
-            if (mostRecentTaskConfig.isIsService()) {
-              jobType = JobType.SERVICE;
-            } else if (cronJobs.containsKey(jobKey)) {
-              jobType = JobType.CRON;
-            } else {
-              jobType = JobType.ADHOC;
-            }
-
-            IJobStats stats = Jobs.getJobStats(tasks);
-
-            return new Job(jobKey.getName(),
-                jobKey.getEnvironment(),
-                stats.getPendingTaskCount(),
-                stats.getActiveTaskCount(),
-                stats.getFinishedTaskCount(),
-                stats.getFailedTaskCount(),
-                0,
-                mostRecentTaskConfig.isProduction(),
-                jobType);
-          }
-        };
-
-    Query.Builder query = environment.isPresent()
-        ? Query.envScoped(role, environment.get())
-        : Query.roleScoped(role);
-
-    Multimap<IJobKey, IScheduledTask> tasks =
-        Tasks.byJobKey(Storage.Util.weaklyConsistentFetchTasks(storage, query));
-
-    Iterable<Job> jobs = FluentIterable
-        .from(tasks.asMap().entrySet())
-        .transform(toJob);
-
-    return DisplayUtils.JOB_ORDERING.sortedCopy(jobs);
-  }
-
-  /**
-   * Template object to represent a job.
-   */
-  static class Job {
-    private final String name;
-    private final String environment;
-    private final int pendingTaskCount;
-    private final int activeTaskCount;
-    private final int finishedTaskCount;
-    private final int failedTaskCount;
-    private final int recentlyFailedTaskCount;
-    private final boolean production;
-    private final JobType type;
-
-    Job(String name,
-        String environment,
-        int pendingTaskCount,
-        int activeTaskCount,
-        int finishedTaskCount,
-        int failedTaskCount,
-        int recentlyFailedTaskCount,
-        boolean production,
-        JobType type) {
-
-      this.name = name;
-      this.environment = environment;
-      this.pendingTaskCount = pendingTaskCount;
-      this.activeTaskCount = activeTaskCount;
-      this.finishedTaskCount = finishedTaskCount;
-      this.failedTaskCount = failedTaskCount;
-      this.recentlyFailedTaskCount = recentlyFailedTaskCount;
-      this.production = production;
-      this.type = type;
-    }
-
-    public String getName() {
-      return name;
-    }
-
-    public String getEnvironment() {
-      return environment;
-    }
-
-    public int getPendingTaskCount() {
-      return pendingTaskCount;
-    }
-
-    public int getActiveTaskCount() {
-      return activeTaskCount;
-    }
-
-    public int getFinishedTaskCount() {
-      return finishedTaskCount;
-    }
-
-    public int getFailedTaskCount() {
-      return failedTaskCount;
-    }
-
-    public int getRecentlyFailedTaskCount() {
-      return recentlyFailedTaskCount;
-    }
-
-    public boolean getProduction() {
-      return production;
-    }
-
-    public String getType() {
-      return type.toString();
-    }
-  }
-
-  static enum JobType {
-    ADHOC("adhoc"), CRON("cron"), SERVICE("service");
-
-    private String jobType;
-
-    private JobType(String jobType) {
-      this.jobType = jobType;
-    }
-
-    public String toString() {
-      return jobType;
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/88d25ed9/src/main/java/org/apache/aurora/scheduler/http/ServletModule.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/http/ServletModule.java b/src/main/java/org/apache/aurora/scheduler/http/ServletModule.java
index e3ff257..9831012 100644
--- a/src/main/java/org/apache/aurora/scheduler/http/ServletModule.java
+++ b/src/main/java/org/apache/aurora/scheduler/http/ServletModule.java
@@ -84,12 +84,7 @@ public class ServletModule extends AbstractModule {
         bind(HttpStatsFilter.class).in(Singleton.class);
         filter("/scheduler*").through(HttpStatsFilter.class);
         bind(LeaderRedirectFilter.class).in(Singleton.class);
-        // Servlets may assign a special meaning to trailing /, but this confuses AngularJS's
-        // resource loader. So, removing them for /scheduler* URLs using a UIRedirectFilter.
-        // TODO (skarumuri): Remove UIRedirectFilter when the /scheduler servlets are removed.
-        bind(UIRedirectFilter.class).in(Singleton.class);
         filter("/scheduler").through(LeaderRedirectFilter.class);
-        filter("/scheduler*").through(UIRedirectFilter.class);
 
         registerJerseyEndpoint("/cron", Cron.class);
         registerJerseyEndpoint("/maintenance", Maintenance.class);
@@ -97,7 +92,6 @@ public class ServletModule extends AbstractModule {
         registerJerseyEndpoint("/offers", Offers.class);
         registerJerseyEndpoint("/pendingtasks", PendingTasks.class);
         registerJerseyEndpoint("/quotas", Quotas.class);
-        registerJerseyEndpoint("/scheduler/", SchedulerzRole.class, SchedulerzJob.class);
         registerJerseyEndpoint("/slaves", Slaves.class);
         registerJerseyEndpoint("/structdump", StructDump.class);
         registerJerseyEndpoint("/utilization", Utilization.class);
@@ -108,49 +102,9 @@ public class ServletModule extends AbstractModule {
     registerJQueryAssets();
     registerBootstrapAssets();
 
-    registerAsset("assets/util.js", "/js/util.js");
-    registerAsset("assets/dictionary.js", "/js/dictionary.js");
     registerAsset("assets/images/viz.png", "/images/viz.png");
     registerAsset("assets/images/aurora.png", "/images/aurora.png");
 
-    // Register datatables
-    registerAsset("assets/datatables/css/jquery.dataTables.css", "/css/jquery.dataTables.css");
-    registerAsset("assets/datatables/images/back_disabled.png", "/images/back_disabled.png");
-    registerAsset(
-        "assets/datatables/images/back_enabled_hover.png",
-        "/images/back_enabled_hover.png");
-    registerAsset("assets/datatables/images/back_enabled.png", "/images/back_enabled.png");
-    registerAsset(
-        "assets/datatables/images/forward_disabled.png",
-        "/images/forward_disabled.png");
-    registerAsset(
-        "assets/datatables/images/forward_enabled_hover.png",
-        "/images/forward_enabled_hover.png");
-    registerAsset(
-        "assets/datatables/images/forward_enabled.png",
-        "/images/forward_enabled.png");
-    registerAsset(
-        "assets/datatables/images/sort_asc_disabled.png",
-        "/images/sort_asc_disabled.png");
-    registerAsset("assets/datatables/images/sort_asc.png", "/images/sort_asc.png");
-    registerAsset("assets/datatables/images/sort_both.png", "/images/sort_both.png");
-    registerAsset(
-        "assets/datatables/images/sort_desc_disabled.png",
-        "/images/sort_desc_disabled.png");
-    registerAsset("assets/datatables/images/sort_desc.png", "/images/sort_desc.png");
-    registerAsset(
-        "assets/datatables/js/jquery.dataTables.min.js",
-        "/js/jquery.dataTables.min.js");
-    registerAsset(
-        "assets/datatables/js/dataTables.bootstrap.js",
-        "/js/dataTables.bootstrap.js");
-    registerAsset(
-        "assets/datatables/js/dataTables.localstorage.js",
-        "/js/dataTables.localstorage.js");
-    registerAsset(
-        "assets/datatables/js/dataTables.htmlNumberType.js",
-        "/js/dataTables.htmlNumberType.js");
-
     registerUIClient();
 
     bind(LeaderRedirect.class).in(Singleton.class);
@@ -175,6 +129,14 @@ public class ServletModule extends AbstractModule {
     registerAsset(BOOTSTRAP_PATH + "img/glyphicons-halflings.png",
         "/img/glyphicons-halflings.png",
         false);
+
+    // Register a complete set of large glyphicons from bootstrap-glyphicons project at
+    // http://marcoceppi.github.io/bootstrap-glyphicons/
+    // TODO(Suman Karumuri): Install the bootstrap-glyphicons via bower, once it is available.
+    registerAsset("bootstrap-glyphicons-master/glyphicons.png", "/img/glyphicons.png", false);
+    registerAsset("bootstrap-glyphicons-master/css/bootstrap.icon-large.min.css",
+        "/css/bootstrap.icon-large.min.css",
+        false);
   }
 
   /**
@@ -183,13 +145,29 @@ public class ServletModule extends AbstractModule {
   private void registerUIClient() {
     registerAsset("bower_components/smart-table/Smart-Table.debug.js", "/js/smartTable.js", false);
     registerAsset("bower_components/angular/angular.js", "/js/angular.js", false);
+    registerAsset("bower_components/angular-route/angular-route.js", "/js/angular-route.js", false);
+    registerAsset("bower_components/underscore/underscore.js", "/js/underscore.js", false);
+    registerAsset("bower_components/momentjs/moment.js", "/js/moment.js", false);
 
     registerAsset("ReadOnlyScheduler.js", "/js/readOnlyScheduler.js", false);
     registerAsset("api_types.js", "/js/apiTypes.js", false);
     registerAsset("thrift.js", "/js/thrift.js", false);
 
-    registerAsset("ui/index.html", "/scheduler");
+    registerAsset("ui/index.html", "/scheduler", true);
+    Registration.registerEndpoint(binder(), "/scheduler");
+
     registerAsset("ui/roleLink.html", "/roleLink.html");
+    registerAsset("ui/roleEnvLink.html", "/roleEnvLink.html");
+    registerAsset("ui/jobLink.html", "/jobLink.html");
+    registerAsset("ui/home.html", "/home.html");
+    registerAsset("ui/role.html", "/role.html");
+    registerAsset("ui/breadcrumb.html", "/breadcrumb.html");
+    registerAsset("ui/error.html", "/error.html");
+    registerAsset("ui/job.html", "/job.html");
+    registerAsset("ui/taskSandbox.html", "/taskSandbox.html");
+    registerAsset("ui/taskStatus.html", "/taskStatus.html");
+    registerAsset("ui/taskLink.html", "/taskLink.html");
+    registerAsset("ui/schedulingDetail.html", "/schedulingDetail.html");
 
     registerAsset("ui/css/app.css", "/css/app.css");
 
@@ -197,6 +175,7 @@ public class ServletModule extends AbstractModule {
     registerAsset("ui/js/controllers.js", "/js/controllers.js");
     registerAsset("ui/js/directives.js", "/js/directives.js");
     registerAsset("ui/js/services.js", "/js/services.js");
+    registerAsset("ui/js/filters.js", "/js/filters.js");
   }
 
   private void registerAsset(String resourceLocation, String registerLocation) {

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/88d25ed9/src/main/java/org/apache/aurora/scheduler/http/UIRedirectFilter.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/http/UIRedirectFilter.java b/src/main/java/org/apache/aurora/scheduler/http/UIRedirectFilter.java
deleted file mode 100644
index b35aad8..0000000
--- a/src/main/java/org/apache/aurora/scheduler/http/UIRedirectFilter.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * Copyright 2013 Apache Software Foundation
- *
- * 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 org.apache.aurora.scheduler.http;
-
-import java.io.IOException;
-
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import com.twitter.common.net.http.filters.AbstractHttpFilter;
-
-/**
- * A filter that maps string template servlet paths to UI client pages. This is needed because
- * AngularJS's resource loader is confused when there is a trailing / at the end of URL's.
- */
-public class UIRedirectFilter extends AbstractHttpFilter {
-
-  @Override
-  public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
-      throws IOException, ServletException {
-
-    if ("/scheduler/".equals(request.getRequestURI())) {
-      response.sendRedirect("/scheduler");
-    } else {
-      chain.doFilter(request, response);
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/88d25ed9/src/main/java/org/apache/aurora/scheduler/local/IsolatedSchedulerModule.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/local/IsolatedSchedulerModule.java b/src/main/java/org/apache/aurora/scheduler/local/IsolatedSchedulerModule.java
index b931baa..1bfd4b6 100644
--- a/src/main/java/org/apache/aurora/scheduler/local/IsolatedSchedulerModule.java
+++ b/src/main/java/org/apache/aurora/scheduler/local/IsolatedSchedulerModule.java
@@ -45,6 +45,7 @@ import com.twitter.common.quantity.Time;
 import com.twitter.common.stats.Stats;
 import com.twitter.common.util.concurrent.ExecutorServiceShutdown;
 
+import org.apache.aurora.codec.ThriftBinaryCodec;
 import org.apache.aurora.gen.AuroraAdmin;
 import org.apache.aurora.gen.ExecutorConfig;
 import org.apache.aurora.gen.Identity;
@@ -54,6 +55,8 @@ import org.apache.aurora.gen.ResourceAggregate;
 import org.apache.aurora.gen.Response;
 import org.apache.aurora.gen.SessionKey;
 import org.apache.aurora.gen.TaskConfig;
+import org.apache.aurora.gen.comm.DeletedTasks;
+import org.apache.aurora.gen.comm.SchedulerMessage;
 import org.apache.aurora.scheduler.DriverFactory;
 import org.apache.aurora.scheduler.base.JobKeys;
 import org.apache.aurora.scheduler.configuration.ConfigurationManager;
@@ -64,6 +67,7 @@ import org.apache.aurora.scheduler.events.PubsubEvent.TaskStateChange;
 import org.apache.aurora.scheduler.events.PubsubEventModule;
 import org.apache.aurora.scheduler.local.FakeDriverFactory.FakeSchedulerDriver;
 import org.apache.aurora.scheduler.log.testing.FileLogStreamModule;
+import org.apache.mesos.Protos;
 import org.apache.mesos.Protos.Attribute;
 import org.apache.mesos.Protos.FrameworkID;
 import org.apache.mesos.Protos.Offer;
@@ -82,7 +86,7 @@ import org.apache.thrift.TException;
 
 /**
  * A module that binds a fake mesos driver factory and a local (non-replicated) storage system.
- * <p>
+ * <p/>
  * The easiest way to run the scheduler in local/isolated mode is by executing:
  * <pre>
  * $ ./pants goal bundle aurora:scheduler-local && ./aurora/scripts/scheduler.sh -c local
@@ -237,6 +241,25 @@ public class IsolatedSchedulerModule extends AbstractModule {
         }
       };
       executor.schedule(changeState, delaySeconds, TimeUnit.SECONDS);
+
+      if (state == TaskState.TASK_FINISHED) {
+        Runnable deleteSandBox = new Runnable() {
+          @Override
+          public void run() {
+            try {
+              scheduler.get().frameworkMessage(
+                  driver,
+                  Protos.ExecutorID.newBuilder().setValue("executor-id").build(),
+                  SlaveID.newBuilder().setValue("slave-id").build(),
+                  ThriftBinaryCodec.encode(
+                      SchedulerMessage.deletedTasks(new DeletedTasks(ImmutableSet.of(taskId)))));
+            } catch (Exception e) {
+              LOG.info("Error deleting tasks " + e);
+            }
+          }
+        };
+        executor.schedule(deleteSandBox, delaySeconds + 100, TimeUnit.SECONDS);
+      }
     }
 
     @Subscribe

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/88d25ed9/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/css/jquery.dataTables.css
----------------------------------------------------------------------
diff --git a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/css/jquery.dataTables.css b/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/css/jquery.dataTables.css
deleted file mode 100644
index ee6da23..0000000
--- a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/css/jquery.dataTables.css
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * File:        jquery.dataTables.css
- * Version:     1.9.4
- * Author:      Allan Jardine (www.sprymedia.co.uk)
- * Info:        www.datatables.net
- * 
- * Copyright 2008-2012 Allan Jardine, all rights reserved.
- *
- * This source file is free software, under either the GPL v2 license or a
- * BSD style license, available at:
- *   http://datatables.net/license_gpl2
- *   http://datatables.net/license_bsd
- * 
- * This source file is distributed in the hope that it will be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
- * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
- */
-
-div.dataTables_length label {
-	float: left;
-	text-align: left;
-}
-
-div.dataTables_length select {
-	width: 75px;
-}
-
-div.dataTables_filter label {
-	float: right;
-}
-
-div.dataTables_info {
-	padding-top: 8px;
-}
-
-div.dataTables_paginate {
-	float: right;
-	margin: 0;
-}
-
-table.table {
-	clear: both;
-	margin-bottom: 6px !important;
-	max-width: none !important;
-}
-
-table.table thead .sorting,
-table.table thead .sorting_asc,
-table.table thead .sorting_desc,
-table.table thead .sorting_asc_disabled,
-table.table thead .sorting_desc_disabled {
-	cursor: pointer;
-	*cursor: hand;
-}
-
-table.table thead .sorting { background: url('/images/sort_both.png') no-repeat center right; }
-table.table thead .sorting_asc { background: url('/images/sort_asc.png') no-repeat center right; }
-table.table thead .sorting_desc { background: url('/images/sort_desc.png') no-repeat center right; }
-
-table.table thead .sorting_asc_disabled { background: url('/images/sort_asc_disabled.png') no-repeat center right; }
-table.table thead .sorting_desc_disabled { background: url('/images/sort_desc_disabled.png') no-repeat center right; }
-
-table.dataTable th:active {
-	outline: none;
-}
-
-/* Scrolling */
-div.dataTables_scrollHead table {
-	margin-bottom: 0 !important;
-	border-bottom-left-radius: 0;
-	border-bottom-right-radius: 0;
-}
-
-div.dataTables_scrollHead table thead tr:last-child th:first-child,
-div.dataTables_scrollHead table thead tr:last-child td:first-child {
-	border-bottom-left-radius: 0 !important;
-	border-bottom-right-radius: 0 !important;
-}
-
-div.dataTables_scrollBody table {
-	border-top: none;
-	margin-bottom: 0 !important;
-}
-
-div.dataTables_scrollBody tbody tr:first-child th,
-div.dataTables_scrollBody tbody tr:first-child td {
-	border-top: none;
-}
-
-div.dataTables_scrollFoot table {
-	border-top: none;
-}
-
-
-
-
-/*
- * TableTools styles
- */
-.table tbody tr.active td,
-.table tbody tr.active th {
-	background-color: #08C;
-	color: white;
-}
-
-.table tbody tr.active:hover td,
-.table tbody tr.active:hover th {
-	background-color: #0075b0 !important;
-}
-
-.table-striped tbody tr.active:nth-child(odd) td,
-.table-striped tbody tr.active:nth-child(odd) th {
-	background-color: #017ebc;
-}
-
-table.DTTT_selectable tbody tr {
-	cursor: pointer;
-	*cursor: hand;
-}
-
-div.DTTT .btn {
-	color: #333 !important;
-	font-size: 12px;
-}
-
-div.DTTT .btn:hover {
-	text-decoration: none !important;
-}
-
-
-ul.DTTT_dropdown.dropdown-menu a {
-	color: #333 !important; /* needed only when demo_page.css is included */
-}
-
-ul.DTTT_dropdown.dropdown-menu li:hover a {
-	background-color: #0088cc;
-	color: white !important;
-}
-
-/* TableTools information display */
-div.DTTT_print_info.modal {
-	height: 150px;
-	margin-top: -75px;
-	text-align: center;
-}
-
-div.DTTT_print_info h6 {
-	font-weight: normal;
-	font-size: 28px;
-	line-height: 28px;
-	margin: 1em;
-}
-
-div.DTTT_print_info p {
-	font-size: 14px;
-	line-height: 20px;
-}
-
-
-
-/*
- * FixedColumns styles
- */
-div.DTFC_LeftHeadWrapper table,
-div.DTFC_LeftFootWrapper table,
-table.DTFC_Cloned tr.even {
-	background-color: white;
-}
-
-div.DTFC_LeftHeadWrapper table {
-	margin-bottom: 0 !important;
-	border-top-right-radius: 0 !important;
-	border-bottom-left-radius: 0 !important;
-	border-bottom-right-radius: 0 !important;
-}
-
-div.DTFC_LeftHeadWrapper table thead tr:last-child th:first-child,
-div.DTFC_LeftHeadWrapper table thead tr:last-child td:first-child {
-	border-bottom-left-radius: 0 !important;
-	border-bottom-right-radius: 0 !important;
-}
-
-div.DTFC_LeftBodyWrapper table {
-	border-top: none;
-	margin-bottom: 0 !important;
-}
-
-div.DTFC_LeftBodyWrapper tbody tr:first-child th,
-div.DTFC_LeftBodyWrapper tbody tr:first-child td {
-	border-top: none;
-}
-
-div.DTFC_LeftFootWrapper table {
-	border-top: none;
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/88d25ed9/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/back_disabled.png
----------------------------------------------------------------------
diff --git a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/back_disabled.png b/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/back_disabled.png
deleted file mode 100644
index 881de79..0000000
Binary files a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/back_disabled.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/88d25ed9/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/back_enabled.png
----------------------------------------------------------------------
diff --git a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/back_enabled.png b/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/back_enabled.png
deleted file mode 100644
index c608682..0000000
Binary files a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/back_enabled.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/88d25ed9/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/back_enabled_hover.png
----------------------------------------------------------------------
diff --git a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/back_enabled_hover.png b/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/back_enabled_hover.png
deleted file mode 100644
index d300f10..0000000
Binary files a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/back_enabled_hover.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/88d25ed9/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/forward_disabled.png
----------------------------------------------------------------------
diff --git a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/forward_disabled.png b/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/forward_disabled.png
deleted file mode 100644
index 6a6ded7..0000000
Binary files a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/forward_disabled.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/88d25ed9/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/forward_enabled.png
----------------------------------------------------------------------
diff --git a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/forward_enabled.png b/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/forward_enabled.png
deleted file mode 100644
index a4e6b53..0000000
Binary files a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/forward_enabled.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/88d25ed9/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/forward_enabled_hover.png
----------------------------------------------------------------------
diff --git a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/forward_enabled_hover.png b/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/forward_enabled_hover.png
deleted file mode 100644
index fc46c5e..0000000
Binary files a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/forward_enabled_hover.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/88d25ed9/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/sort_asc.png
----------------------------------------------------------------------
diff --git a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/sort_asc.png b/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/sort_asc.png
deleted file mode 100644
index a88d797..0000000
Binary files a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/sort_asc.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/88d25ed9/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/sort_asc_disabled.png
----------------------------------------------------------------------
diff --git a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/sort_asc_disabled.png b/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/sort_asc_disabled.png
deleted file mode 100644
index 4e144cf..0000000
Binary files a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/sort_asc_disabled.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/88d25ed9/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/sort_both.png
----------------------------------------------------------------------
diff --git a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/sort_both.png b/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/sort_both.png
deleted file mode 100644
index 1867040..0000000
Binary files a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/sort_both.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/88d25ed9/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/sort_desc.png
----------------------------------------------------------------------
diff --git a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/sort_desc.png b/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/sort_desc.png
deleted file mode 100644
index def071e..0000000
Binary files a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/sort_desc.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/88d25ed9/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/sort_desc_disabled.png
----------------------------------------------------------------------
diff --git a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/sort_desc_disabled.png b/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/sort_desc_disabled.png
deleted file mode 100644
index 7824973..0000000
Binary files a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/images/sort_desc_disabled.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/88d25ed9/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/js/dataTables.bootstrap.js
----------------------------------------------------------------------
diff --git a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/js/dataTables.bootstrap.js b/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/js/dataTables.bootstrap.js
deleted file mode 100644
index 420e507..0000000
--- a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/js/dataTables.bootstrap.js
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * File:        dataTables.bootstrap.js
- * Version:     1.9.4
- * Author:      Allan Jardine (www.sprymedia.co.uk)
- * Info:        www.datatables.net
- * 
- * Copyright 2008-2012 Allan Jardine, all rights reserved.
- *
- * This source file is free software, under either the GPL v2 license or a
- * BSD style license, available at:
- *   http://datatables.net/license_gpl2
- *   http://datatables.net/license_bsd
- * 
- * This source file is distributed in the hope that it will be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
- * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
- */
-
-/* Set the defaults for DataTables initialisation */
-$.extend( true, $.fn.dataTable.defaults, {
-  "sDom": "<'row-fluid'<'span4'l><'span2'r><'span6'f>>t<'row-fluid'<'span6'i><'span6'p>>",
-  "sPaginationType": "bootstrap",
-  "oLanguage": {
-    "sLengthMenu": "_MENU_ records per page"
-  }
-} );
-
-
-/* Default class modification */
-$.extend( $.fn.dataTableExt.oStdClasses, {
-  "sWrapper": "dataTables_wrapper form-inline"
-} );
-
-
-/* API method to get paging information */
-$.fn.dataTableExt.oApi.fnPagingInfo = function ( oSettings )
-{
-  return {
-    "iStart":         oSettings._iDisplayStart,
-    "iEnd":           oSettings.fnDisplayEnd(),
-    "iLength":        oSettings._iDisplayLength,
-    "iTotal":         oSettings.fnRecordsTotal(),
-    "iFilteredTotal": oSettings.fnRecordsDisplay(),
-    "iPage":          oSettings._iDisplayLength === -1 ?
-      0 : Math.ceil( oSettings._iDisplayStart / oSettings._iDisplayLength ),
-    "iTotalPages":    oSettings._iDisplayLength === -1 ?
-      0 : Math.ceil( oSettings.fnRecordsDisplay() / oSettings._iDisplayLength )
-  };
-};
-
-
-/* Bootstrap style pagination control */
-$.extend( $.fn.dataTableExt.oPagination, {
-  "bootstrap": {
-    "fnInit": function( oSettings, nPaging, fnDraw ) {
-      var oLang = oSettings.oLanguage.oPaginate;
-      var fnClickHandler = function ( e ) {
-        e.preventDefault();
-        if ( oSettings.oApi._fnPageChange(oSettings, e.data.action) ) {
-          fnDraw( oSettings );
-        }
-      };
-
-      $(nPaging).addClass('pagination').append(
-        '<ul>'+
-          '<li class="prev disabled"><a href="#">&larr; '+oLang.sPrevious+'</a></li>'+
-          '<li class="next disabled"><a href="#">'+oLang.sNext+' &rarr; </a></li>'+
-        '</ul>'
-      );
-      var els = $('a', nPaging);
-      $(els[0]).bind( 'click.DT', { action: "previous" }, fnClickHandler );
-      $(els[1]).bind( 'click.DT', { action: "next" }, fnClickHandler );
-    },
-
-    "fnUpdate": function ( oSettings, fnDraw ) {
-      var iListLength = 5;
-      var oPaging = oSettings.oInstance.fnPagingInfo();
-      var an = oSettings.aanFeatures.p;
-      var i, ien, j, sClass, iStart, iEnd, iHalf=Math.floor(iListLength/2);
-
-      if ( oPaging.iTotalPages < iListLength) {
-        iStart = 1;
-        iEnd = oPaging.iTotalPages;
-      }
-      else if ( oPaging.iPage <= iHalf ) {
-        iStart = 1;
-        iEnd = iListLength;
-      } else if ( oPaging.iPage >= (oPaging.iTotalPages-iHalf) ) {
-        iStart = oPaging.iTotalPages - iListLength + 1;
-        iEnd = oPaging.iTotalPages;
-      } else {
-        iStart = oPaging.iPage - iHalf + 1;
-        iEnd = iStart + iListLength - 1;
-      }
-
-      for ( i=0, ien=an.length ; i<ien ; i++ ) {
-        // Remove the middle elements
-        $('li:gt(0)', an[i]).filter(':not(:last)').remove();
-
-        // Add the new list items and their event handlers
-        for ( j=iStart ; j<=iEnd ; j++ ) {
-          sClass = (j==oPaging.iPage+1) ? 'class="active"' : '';
-          $('<li '+sClass+'><a href="#">'+j+'</a></li>')
-            .insertBefore( $('li:last', an[i])[0] )
-            .bind('click', function (e) {
-              e.preventDefault();
-              oSettings._iDisplayStart = (parseInt($('a', this).text(),10)-1) * oPaging.iLength;
-              fnDraw( oSettings );
-            } );
-        }
-
-        // Add / remove disabled classes from the static elements
-        if ( oPaging.iPage === 0 ) {
-          $('li:first', an[i]).addClass('disabled');
-        } else {
-          $('li:first', an[i]).removeClass('disabled');
-        }
-
-        if ( oPaging.iPage === oPaging.iTotalPages-1 || oPaging.iTotalPages === 0 ) {
-          $('li:last', an[i]).addClass('disabled');
-        } else {
-          $('li:last', an[i]).removeClass('disabled');
-        }
-      }
-    }
-  }
-} );
-
-
-/*
- * TableTools Bootstrap compatibility
- * Required TableTools 2.1+
- */
-if ( $.fn.DataTable.TableTools ) {
-  // Set the classes that TableTools uses to something suitable for Bootstrap
-  $.extend( true, $.fn.DataTable.TableTools.classes, {
-    "container": "DTTT btn-group",
-    "buttons": {
-      "normal": "btn",
-      "disabled": "disabled"
-    },
-    "collection": {
-      "container": "DTTT_dropdown dropdown-menu",
-      "buttons": {
-        "normal": "",
-        "disabled": "disabled"
-      }
-    },
-    "print": {
-      "info": "DTTT_print_info modal"
-    },
-    "select": {
-      "row": "active"
-    }
-  } );
-
-  // Have the collection use a bootstrap compatible dropdown
-  $.extend( true, $.fn.DataTable.TableTools.DEFAULTS.oTags, {
-    "collection": {
-      "container": "ul",
-      "button": "li",
-      "liner": "a"
-    }
-  } );
-};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/88d25ed9/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/js/dataTables.htmlNumberType.js
----------------------------------------------------------------------
diff --git a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/js/dataTables.htmlNumberType.js b/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/js/dataTables.htmlNumberType.js
deleted file mode 100644
index 885ad34..0000000
--- a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/js/dataTables.htmlNumberType.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * DataTables custom plugin to extract numbers from HTML tags
- * for sorting rows in numeric order.
- *
- * Ref: http://www.datatables.net/plug-ins/sorting
- *
- * Compatible with DataTables v1.9.4
- *
- */
-
-jQuery.extend(jQuery.fn.dataTableExt.oSort, {
-  "num-html-pre": function (a) {
-    // Extract the numeric value from the html by removing all tags.
-    var x = String(a).replace(/<[\s\S]*?>/g, "");
-    return parseFloat(x);
-  },
- 
-  "num-html-asc": function (a, b) {
-    // Compare the extracted numeric values for asc sort.
-    return ((a < b) ? -1 : ((a > b) ? 1 : 0));
-  },
- 
-  "num-html-desc": function (a, b) {
-    // Compare the extracted numeric values for desc sort.
-    return ((a < b) ? 1 : ((a > b) ? -1 : 0));
-  }
-});
-
-/*
- * Type detection function for custom type "num-html".
- *
- * Ref: http://www.datatables.net/plug-ins/type-detection#how_to
- */
-jQuery.fn.dataTableExt.aTypes.unshift(function (sData) {
-  sData = typeof sData.replace == "function" ?
-    sData.replace( /<[\s\S]*?>/g, "" ) : sData;
-  sData = $.trim(sData);
-    
-  var sValidFirstChars = "0123456789-";
-  var sValidChars = "0123456789.";
-  var Char;
-  var bDecimal = false;
-    
-  // Check for a valid first char (no period and allow negatives).
-  Char = sData.charAt(0); 
-  if (sValidFirstChars.indexOf(Char) == -1) {
-    return null;
-  }
-    
-  // Check all the other characters are valid.
-  for ( var i=1 ; i<sData.length ; i++ ) {
-    Char = sData.charAt(i); 
-    if (sValidChars.indexOf(Char) == -1) {
-      return null;
-    }
-      
-    // Only one decimal place allowed.
-    if (Char == ".") {
-      if (bDecimal) {
-        return null;
-      }
-      bDecimal = true;
-    }
-  }
-    
-  return "num-html";
-});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/88d25ed9/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/js/dataTables.localstorage.js
----------------------------------------------------------------------
diff --git a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/js/dataTables.localstorage.js b/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/js/dataTables.localstorage.js
deleted file mode 100644
index 3c0b39a..0000000
--- a/src/main/resources/org/apache/aurora/scheduler/http/assets/datatables/js/dataTables.localstorage.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/**
- * Make browser's local storage as the default storage for Datatables plugin.
- * Compatible with Datatables v1.9.4
- *
- * http://www.datatables.net/beta/1.9/examples/advanced_init/localstorage.html
- *
- * Always link this file after linking jquery.dataTables.min.js
- */
-$.extend(true, $.fn.dataTable.defaults, {    
-  "fnStateSave": function (oSettings, oData) {
-  localStorage.setItem("DataTables_" + window.location.pathname + "_" + oSettings.sTableId, 
-                       JSON.stringify(oData));
-  },
-  "fnStateLoad": function (oSettings) {
-    return JSON.parse(localStorage
-        .getItem("DataTables_" + window.location.pathname + "_" + oSettings.sTableId));
-  }
-});
\ No newline at end of file


Mime
View raw message