You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aurora.apache.org by wf...@apache.org on 2013/12/31 22:20:39 UTC

[46/51] [partial] Rename twitter* and com.twitter to apache and org.apache directories to preserve all file history before the refactor.

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/bc1635df/src/main/java/com/twitter/aurora/scheduler/http/HttpStatsFilter.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/twitter/aurora/scheduler/http/HttpStatsFilter.java b/src/main/java/com/twitter/aurora/scheduler/http/HttpStatsFilter.java
deleted file mode 100644
index a846383..0000000
--- a/src/main/java/com/twitter/aurora/scheduler/http/HttpStatsFilter.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2013 Twitter, 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 com.twitter.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 javax.servlet.http.HttpServletResponseWrapper;
-
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-
-import com.twitter.common.net.http.filters.AbstractHttpFilter;
-import com.twitter.common.stats.SlidingStats;
-
-/**
- * An HTTP filter that exports counts and timing for requests based on response code.
- */
-public class HttpStatsFilter extends AbstractHttpFilter {
-
-  private final LoadingCache<Integer, SlidingStats> counters = CacheBuilder.newBuilder()
-      .build(new CacheLoader<Integer, SlidingStats>() {
-        @Override public SlidingStats load(Integer status) {
-          return new SlidingStats("http_" + status + "_responses", "nanos");
-        }
-      });
-
-  private static class ResponseWithStatus extends HttpServletResponseWrapper {
-    // 200 response code is the default if none is explicitly set.
-    private int wrappedStatus = 200;
-
-    ResponseWithStatus(HttpServletResponse resp) {
-      super(resp);
-    }
-
-    @Override public void setStatus(int sc) {
-      super.setStatus(sc);
-      wrappedStatus = sc;
-    }
-
-    @Override public void setStatus(int sc, String sm) {
-      super.setStatus(sc, sm);
-      wrappedStatus = sc;
-    }
-  }
-
-  @Override
-  public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
-      throws IOException, ServletException {
-
-    long start = System.nanoTime();
-    ResponseWithStatus wrapper = new ResponseWithStatus(response);
-    chain.doFilter(request, wrapper);
-    counters.getUnchecked(wrapper.wrappedStatus).accumulate(System.nanoTime() - start);
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/bc1635df/src/main/java/com/twitter/aurora/scheduler/http/JerseyTemplateServlet.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/twitter/aurora/scheduler/http/JerseyTemplateServlet.java b/src/main/java/com/twitter/aurora/scheduler/http/JerseyTemplateServlet.java
deleted file mode 100644
index 5c13de5..0000000
--- a/src/main/java/com/twitter/aurora/scheduler/http/JerseyTemplateServlet.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2013 Twitter, 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 com.twitter.aurora.scheduler.http;
-
-import java.io.StringWriter;
-
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Response;
-
-import org.antlr.stringtemplate.StringTemplate;
-
-import com.twitter.common.base.Closure;
-import com.twitter.common.util.templating.StringTemplateHelper;
-import com.twitter.common.util.templating.StringTemplateHelper.TemplateException;
-
-/**
- * Base class for common functions needed in a jersey stringtemplate servlet.
- */
-abstract class JerseyTemplateServlet {
-
-  private final StringTemplateHelper templateHelper;
-
-  JerseyTemplateServlet(String templatePath) {
-    templateHelper = new StringTemplateHelper(getClass(), templatePath, true);
-  }
-
-  protected final Response fillTemplate(Closure<StringTemplate> populator) {
-    StringWriter output = new StringWriter();
-    try {
-      templateHelper.writeTemplate(output, populator);
-    } catch (TemplateException e) {
-      throw new WebApplicationException(e);
-    }
-    return Response.ok(output.toString()).build();
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/bc1635df/src/main/java/com/twitter/aurora/scheduler/http/LeaderRedirect.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/twitter/aurora/scheduler/http/LeaderRedirect.java b/src/main/java/com/twitter/aurora/scheduler/http/LeaderRedirect.java
deleted file mode 100644
index 20e4446..0000000
--- a/src/main/java/com/twitter/aurora/scheduler/http/LeaderRedirect.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright 2013 Twitter, 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 com.twitter.aurora.scheduler.http;
-
-import java.net.InetSocketAddress;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.logging.Logger;
-
-import javax.inject.Inject;
-import javax.servlet.http.HttpServletRequest;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.net.HostAndPort;
-import com.google.common.util.concurrent.Atomics;
-
-import com.twitter.common.application.modules.LocalServiceRegistry;
-import com.twitter.common.net.pool.DynamicHostSet;
-import com.twitter.common.net.pool.DynamicHostSet.HostChangeMonitor;
-import com.twitter.common.net.pool.DynamicHostSet.MonitorException;
-import com.twitter.thrift.Endpoint;
-import com.twitter.thrift.ServiceInstance;
-
-/**
- * Redirect logic for finding the leading scheduler in the event that this process is not the
- * leader.
- */
-public class LeaderRedirect {
-
-  // TODO(wfarner): Should we tie this directly to the producer of the node (HttpModule?  It seems
-  // like the right thing to do, but would introduce an otherwise unnecessary dependency.
-  @VisibleForTesting
-  static final String HTTP_PORT_NAME = "http";
-
-  private static final Logger LOG = Logger.getLogger(LeaderRedirect.class.getName());
-
-  private final LocalServiceRegistry serviceRegistry;
-  private final DynamicHostSet<ServiceInstance> schedulers;
-
-  private final AtomicReference<ServiceInstance> leader = Atomics.newReference();
-
-  @Inject
-  LeaderRedirect(LocalServiceRegistry serviceRegistry, DynamicHostSet<ServiceInstance> schedulers) {
-    this.serviceRegistry = Preconditions.checkNotNull(serviceRegistry);
-    this.schedulers = Preconditions.checkNotNull(schedulers);
-  }
-
-  /**
-   * Initiates the monitor that will watch the scheduler host set.
-   *
-   * @throws MonitorException If monitoring failed to initialize.
-   */
-  public void monitor() throws MonitorException {
-    schedulers.watch(new SchedulerMonitor());
-  }
-
-  private Optional<HostAndPort> getLeaderHttp() {
-    ServiceInstance leadingScheduler = leader.get();
-    if (leadingScheduler == null) {
-      return Optional.absent();
-    }
-
-    if (leadingScheduler.isSetAdditionalEndpoints()) {
-      Endpoint leaderHttp = leadingScheduler.getAdditionalEndpoints().get(HTTP_PORT_NAME);
-      if (leaderHttp != null && leaderHttp.isSetHost() && leaderHttp.isSetPort()) {
-        return Optional.of(HostAndPort.fromParts(leaderHttp.getHost(), leaderHttp.getPort()));
-      }
-    }
-
-    LOG.warning("Leader service instance seems to be incomplete: " + leadingScheduler);
-    return Optional.absent();
-  }
-
-  private Optional<HostAndPort> getLocalHttp() {
-    InetSocketAddress localHttp = serviceRegistry.getAuxiliarySockets().get(HTTP_PORT_NAME);
-    return (localHttp == null) ? Optional.<HostAndPort>absent()
-        : Optional.of(HostAndPort.fromParts(localHttp.getHostName(), localHttp.getPort()));
-  }
-
-  /**
-   * Gets the optional HTTP endpoint that should be redirected to in the event that this
-   * scheduler is not the leader.
-   *
-   * @return Optional redirect target.
-   */
-  @VisibleForTesting
-  Optional<HostAndPort> getRedirect() {
-    Optional<HostAndPort> leaderHttp = getLeaderHttp();
-    Optional<HostAndPort> localHttp = getLocalHttp();
-
-    if (leaderHttp.isPresent()) {
-      if (leaderHttp.equals(localHttp)) {
-        return Optional.absent();
-      } else {
-        return leaderHttp;
-      }
-    } else {
-      LOG.info("No leader found, not redirecting.");
-      return Optional.absent();
-    }
-  }
-
-  /**
-   * Gets the optional redirect URI target in the event that this process is not the leading
-   * scheduler.
-   *
-   * @param req HTTP request.
-   * @return An optional redirect destination to route the request to the leading scheduler.
-   */
-  public Optional<String> getRedirectTarget(HttpServletRequest req) {
-    Optional<HostAndPort> redirectTarget = getRedirect();
-    if (redirectTarget.isPresent()) {
-      HostAndPort target = redirectTarget.get();
-      StringBuilder redirect = new StringBuilder()
-          .append(req.getScheme())
-          .append("://")
-          .append(target.getHostText())
-          .append(":")
-          .append(target.getPort())
-          .append(req.getRequestURI());
-
-      String queryString = req.getQueryString();
-      if (queryString != null) {
-        redirect.append("?").append(queryString);
-      }
-
-      return Optional.of(redirect.toString());
-    } else {
-      return Optional.absent();
-    }
-  }
-
-  /**
-   * Monitor to track scheduler leader changes.
-   */
-  private class SchedulerMonitor implements HostChangeMonitor<ServiceInstance> {
-    @Override public void onChange(ImmutableSet<ServiceInstance> hostSet) {
-      switch (hostSet.size()) {
-        case 0:
-          LOG.warning("No schedulers in host set, will not redirect despite not being leader.");
-          leader.set(null);
-          break;
-
-        case 1:
-          LOG.info("Found leader scheduler at " + hostSet);
-          leader.set(Iterables.getOnlyElement(hostSet));
-          break;
-
-        default:
-          LOG.severe("Multiple schedulers detected, will not redirect: " + hostSet);
-          leader.set(null);
-      }
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/bc1635df/src/main/java/com/twitter/aurora/scheduler/http/LeaderRedirectFilter.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/twitter/aurora/scheduler/http/LeaderRedirectFilter.java b/src/main/java/com/twitter/aurora/scheduler/http/LeaderRedirectFilter.java
deleted file mode 100644
index 86f0567..0000000
--- a/src/main/java/com/twitter/aurora/scheduler/http/LeaderRedirectFilter.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2013 Twitter, 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 com.twitter.aurora.scheduler.http;
-
-import java.io.IOException;
-
-import javax.inject.Inject;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-
-import com.twitter.common.net.http.filters.AbstractHttpFilter;
-
-/**
- * An HTTP filter that will redirect the request to the leading scheduler.
- */
-public class LeaderRedirectFilter extends AbstractHttpFilter {
-
-  private final LeaderRedirect redirector;
-
-  @Inject
-  LeaderRedirectFilter(LeaderRedirect redirector) {
-    this.redirector = Preconditions.checkNotNull(redirector);
-  }
-
-  @Override
-  public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
-      throws IOException, ServletException {
-
-    Optional<String> leaderRedirect = redirector.getRedirectTarget(request);
-    if (leaderRedirect.isPresent()) {
-      response.sendRedirect(leaderRedirect.get());
-    } else {
-      chain.doFilter(request, response);
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/bc1635df/src/main/java/com/twitter/aurora/scheduler/http/Maintenance.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/twitter/aurora/scheduler/http/Maintenance.java b/src/main/java/com/twitter/aurora/scheduler/http/Maintenance.java
deleted file mode 100644
index fb71539..0000000
--- a/src/main/java/com/twitter/aurora/scheduler/http/Maintenance.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright 2013 Twitter, 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 com.twitter.aurora.scheduler.http;
-
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Multimaps;
-
-import com.twitter.aurora.gen.HostAttributes;
-import com.twitter.aurora.gen.MaintenanceMode;
-import com.twitter.aurora.scheduler.base.Query;
-import com.twitter.aurora.scheduler.base.Tasks;
-import com.twitter.aurora.scheduler.storage.Storage;
-import com.twitter.aurora.scheduler.storage.Storage.StoreProvider;
-import com.twitter.aurora.scheduler.storage.Storage.Work;
-import com.twitter.aurora.scheduler.storage.entities.IScheduledTask;
-
-import static com.twitter.aurora.gen.MaintenanceMode.DRAINED;
-import static com.twitter.aurora.gen.MaintenanceMode.DRAINING;
-import static com.twitter.aurora.gen.MaintenanceMode.SCHEDULED;
-
-/**
- * Servlet that exposes the maintenance state of hosts.
- */
-@Path("/maintenance")
-public class Maintenance {
-  private final Storage storage;
-
-  @Inject
-  Maintenance(Storage storage) {
-    this.storage = Preconditions.checkNotNull(storage);
-  }
-
-  @GET
-  @Produces(MediaType.APPLICATION_JSON)
-  public Response getHosts() {
-    return storage.weaklyConsistentRead(new Work.Quiet<Response>() {
-      @Override public Response apply(StoreProvider storeProvider) {
-        Multimap<MaintenanceMode, String> hostsByMode =
-            Multimaps.transformValues(
-              Multimaps.index(storeProvider.getAttributeStore().getHostAttributes(), GET_MODE),
-              HOST_NAME);
-
-        Map<MaintenanceMode, Object> hosts = Maps.newHashMap();
-        hosts.put(DRAINED, ImmutableSet.copyOf(hostsByMode.get(DRAINED)));
-        hosts.put(SCHEDULED, ImmutableSet.copyOf(hostsByMode.get(SCHEDULED)));
-        hosts.put(DRAINING, getTasksByHosts(storeProvider, hostsByMode.get(DRAINING)).asMap());
-        return Response.ok(hosts).build();
-      }
-    });
-  }
-
-  private Multimap<String, String> getTasksByHosts(StoreProvider provider, Iterable<String> hosts) {
-    ImmutableSet.Builder<IScheduledTask> drainingTasks = ImmutableSet.builder();
-    for (String host : hosts) {
-      drainingTasks.addAll(provider.getTaskStore().fetchTasks(Query.slaveScoped(host).active()));
-    }
-    return Multimaps.transformValues(
-        Multimaps.index(drainingTasks.build(), TASK_TO_HOST),
-        Tasks.SCHEDULED_TO_ID);
-  }
-
-  private static final Function<IScheduledTask, String> TASK_TO_HOST =
-      new Function<IScheduledTask, String>() {
-        @Override public String apply(IScheduledTask task) {
-          return task.getAssignedTask().getSlaveHost();
-        }
-      };
-
-  private static final Function<HostAttributes, String> HOST_NAME =
-      new Function<HostAttributes, String>() {
-        @Override public String apply(HostAttributes attributes) {
-          return attributes.getHost();
-        }
-      };
-
-  private static final Function<HostAttributes, MaintenanceMode> GET_MODE =
-      new Function<HostAttributes, MaintenanceMode>() {
-        @Override public MaintenanceMode apply(HostAttributes attrs) {
-          return attrs.getMode();
-        }
-      };
-}

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/bc1635df/src/main/java/com/twitter/aurora/scheduler/http/Mname.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/twitter/aurora/scheduler/http/Mname.java b/src/main/java/com/twitter/aurora/scheduler/http/Mname.java
deleted file mode 100644
index c97560f..0000000
--- a/src/main/java/com/twitter/aurora/scheduler/http/Mname.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright 2013 Twitter, 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 com.twitter.aurora.scheduler.http;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import javax.inject.Inject;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
-import javax.ws.rs.core.UriBuilder;
-import javax.ws.rs.core.UriInfo;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-
-import com.twitter.aurora.scheduler.base.JobKeys;
-import com.twitter.aurora.scheduler.base.Query;
-import com.twitter.aurora.scheduler.storage.Storage;
-import com.twitter.aurora.scheduler.storage.entities.IAssignedTask;
-import com.twitter.aurora.scheduler.storage.entities.IScheduledTask;
-
-import static javax.ws.rs.core.Response.Status.NOT_FOUND;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import static com.twitter.aurora.gen.ScheduleStatus.RUNNING;
-
-/**
- * Simple redirector from the canonical name of a task to its configured HTTP port.
- *
- * <p>Forwards for GET, PUT, POST and DELETE requests using HTTP 307 allowing compliant clients to
- * seamlessly perform re-directed mutations.
- */
-@Path("/mname")
-public class Mname {
-
-  private static final Set<String> HTTP_PORT_NAMES = ImmutableSet.of(
-      "health", "http", "HTTP", "web");
-
-  private final Storage storage;
-
-  @Inject
-  public Mname(Storage storage) {
-    this.storage = checkNotNull(storage);
-  }
-
-  @GET
-  @Produces(MediaType.TEXT_HTML)
-  public Response getUsage() {
-    return Response
-        .status(Status.BAD_REQUEST)
-        .entity("<html>Usage: /mname/{role}/{env}/{job}/{instance}</html>")
-        .build();
-  }
-
-  @GET
-  @Path("/{role}/{env}/{job}/{instance}/{forward:.+}")
-  @Produces(MediaType.TEXT_HTML)
-  public Response getWithForwardRequest(
-      @PathParam("role") String role,
-      @PathParam("env") String env,
-      @PathParam("job") String job,
-      @PathParam("instance") int instanceId,
-      @PathParam("forward") String forward,
-      @Context UriInfo uriInfo) {
-
-    return get(role, env, job, instanceId, uriInfo, Optional.of(forward));
-  }
-
-  @PUT
-  @Path("/{role}/{env}/{job}/{instance}/{forward:.+}")
-  @Produces(MediaType.TEXT_HTML)
-  public Response putWithForwardRequest(
-      @PathParam("role") String role,
-      @PathParam("env") String env,
-      @PathParam("job") String job,
-      @PathParam("instance") int instanceId,
-      @PathParam("forward") String forward,
-      @Context UriInfo uriInfo) {
-
-    return get(role, env, job, instanceId, uriInfo, Optional.of(forward));
-  }
-
-  @POST
-  @Path("/{role}/{env}/{job}/{instance}/{forward:.+}")
-  @Produces(MediaType.TEXT_HTML)
-  public Response postWithForwardRequest(
-      @PathParam("role") String role,
-      @PathParam("env") String env,
-      @PathParam("job") String job,
-      @PathParam("instance") int instanceId,
-      @PathParam("forward") String forward,
-      @Context UriInfo uriInfo) {
-
-    return get(role, env, job, instanceId, uriInfo, Optional.of(forward));
-  }
-
-  @DELETE
-  @Path("/{role}/{env}/{job}/{instance}/{forward:.+}")
-  @Produces(MediaType.TEXT_HTML)
-  public Response deleteWithForwardRequest(
-      @PathParam("role") String role,
-      @PathParam("env") String env,
-      @PathParam("job") String job,
-      @PathParam("instance") int instanceId,
-      @PathParam("forward") String forward,
-      @Context UriInfo uriInfo) {
-
-    return get(role, env, job, instanceId, uriInfo, Optional.of(forward));
-  }
-
-  @GET
-  @Path("/{role}/{env}/{job}/{instance}")
-  @Produces(MediaType.TEXT_HTML)
-  public Response get(
-      @PathParam("role") String role,
-      @PathParam("env") String env,
-      @PathParam("job") String job,
-      @PathParam("instance") int instanceId,
-      @Context UriInfo uriInfo) {
-
-    return get(role, env, job, instanceId, uriInfo, Optional.<String>absent());
-  }
-
-  @PUT
-  @Path("/{role}/{env}/{job}/{instance}")
-  @Produces(MediaType.TEXT_HTML)
-  public Response put(
-      @PathParam("role") String role,
-      @PathParam("env") String env,
-      @PathParam("job") String job,
-      @PathParam("instance") int instanceId,
-      @Context UriInfo uriInfo) {
-
-    return get(role, env, job, instanceId, uriInfo, Optional.<String>absent());
-  }
-
-  @POST
-  @Path("/{role}/{env}/{job}/{instance}")
-  @Produces(MediaType.TEXT_HTML)
-  public Response post(
-      @PathParam("role") String role,
-      @PathParam("env") String env,
-      @PathParam("job") String job,
-      @PathParam("instance") int instanceId,
-      @Context UriInfo uriInfo) {
-
-    return get(role, env, job, instanceId, uriInfo, Optional.<String>absent());
-  }
-
-  @DELETE
-  @Path("/{role}/{env}/{job}/{instance}")
-  @Produces(MediaType.TEXT_HTML)
-  public Response delete(
-      @PathParam("role") String role,
-      @PathParam("env") String env,
-      @PathParam("job") String job,
-      @PathParam("instance") int instanceId,
-      @Context UriInfo uriInfo) {
-
-    return get(role, env, job, instanceId, uriInfo, Optional.<String>absent());
-  }
-
-  private Response get(
-      String role,
-      String env,
-      String job,
-      int instanceId,
-      UriInfo uriInfo,
-      Optional<String> forwardRequest) {
-
-    IScheduledTask task = Iterables.getOnlyElement(
-        Storage.Util.consistentFetchTasks(storage,
-            Query.instanceScoped(JobKeys.from(role, env, job), instanceId).active()),
-        null);
-    if (task == null) {
-      return respond(NOT_FOUND, "No such live instance found.");
-    }
-
-    if (task.getStatus() != RUNNING) {
-      return respond(NOT_FOUND, "The selected instance is currently in state " + task.getStatus());
-    }
-
-    IAssignedTask assignedTask = task.getAssignedTask();
-    Optional<Integer> port = getRedirectPort(assignedTask);
-    if (!port.isPresent()) {
-      return respond(NOT_FOUND, "The task does not have a registered http port.");
-    }
-
-    UriBuilder redirect = UriBuilder
-        .fromPath(forwardRequest.or("/"))
-        .scheme("http")
-        .host(assignedTask.getSlaveHost())
-        .port(port.get());
-    for (Entry<String, List<String>> entry : uriInfo.getQueryParameters().entrySet()) {
-      for (String value : entry.getValue()) {
-        redirect.queryParam(entry.getKey(), value);
-      }
-    }
-
-    return Response.temporaryRedirect(redirect.build()).build();
-  }
-
-  @VisibleForTesting
-  static Optional<Integer> getRedirectPort(IAssignedTask task) {
-    Map<String, Integer> ports = task.isSetAssignedPorts()
-        ? task.getAssignedPorts() : ImmutableMap.<String, Integer>of();
-    for (String httpPortName : HTTP_PORT_NAMES) {
-      Integer port = ports.get(httpPortName);
-      if (port != null) {
-        return Optional.of(port);
-      }
-    }
-    return Optional.absent();
-  }
-
-  private Response respond(Status status, String message) {
-    return Response.status(status).entity(message).build();
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/bc1635df/src/main/java/com/twitter/aurora/scheduler/http/Offers.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/twitter/aurora/scheduler/http/Offers.java b/src/main/java/com/twitter/aurora/scheduler/http/Offers.java
deleted file mode 100644
index e90f1cc..0000000
--- a/src/main/java/com/twitter/aurora/scheduler/http/Offers.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright 2013 Twitter, 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 com.twitter.aurora.scheduler.http;
-
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableMap;
-
-import org.apache.mesos.Protos.Attribute;
-import org.apache.mesos.Protos.ExecutorID;
-import org.apache.mesos.Protos.Offer;
-import org.apache.mesos.Protos.Resource;
-import org.apache.mesos.Protos.Value.Range;
-
-import com.twitter.aurora.scheduler.async.OfferQueue;
-
-/**
- * Servlet that exposes resource offers that the scheduler is currently retaining.
- */
-@Path("/offers")
-public class Offers {
-
-  private final OfferQueue offerQueue;
-
-  @Inject
-  Offers(OfferQueue offerQueue) {
-    this.offerQueue = Preconditions.checkNotNull(offerQueue);
-  }
-
-  /**
-   * Dumps the offers queued in the scheduler.
-   *
-   * @return HTTP response.
-   */
-  @GET
-  @Produces(MediaType.APPLICATION_JSON)
-  public Response getOffers() {
-    return Response.ok(
-        FluentIterable.from(offerQueue.getOffers()).transform(TO_BEAN).toList()).build();
-  }
-
-  private static final Function<ExecutorID, String> EXECUTOR_ID_TOSTRING =
-      new Function<ExecutorID, String>() {
-        @Override public String apply(ExecutorID id) {
-          return id.getValue();
-        }
-      };
-
-  private static final Function<Range, Object> RANGE_TO_BEAN = new Function<Range, Object>() {
-    @Override public Object apply(Range range) {
-      return range.getBegin() + "-" + range.getEnd();
-    }
-  };
-
-  private static final Function<Attribute, Object> ATTRIBUTE_TO_BEAN =
-      new Function<Attribute, Object>() {
-        @Override public Object apply(Attribute attr) {
-          ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder();
-          builder.put("name", attr.getName());
-          if (attr.hasScalar()) {
-            builder.put("scalar", attr.getScalar().getValue());
-          }
-          if (attr.hasRanges()) {
-            builder.put("ranges", immutable(attr.getRanges().getRangeList(), RANGE_TO_BEAN));
-          }
-          if (attr.hasSet()) {
-            builder.put("set", attr.getSet().getItemList());
-          }
-          if (attr.hasText()) {
-            builder.put("text", attr.getText().getValue());
-          }
-          return builder.build();
-        }
-      };
-
-  private static final Function<Resource, Object> RESOURCE_TO_BEAN =
-      new Function<Resource, Object>() {
-        @Override public Object apply(Resource resource) {
-          ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder();
-          builder.put("name", resource.getName());
-          if (resource.hasScalar()) {
-            builder.put("scalar", resource.getScalar().getValue());
-          }
-          if (resource.hasRanges()) {
-            builder.put("ranges", immutable(resource.getRanges().getRangeList(), RANGE_TO_BEAN));
-          }
-          if (resource.hasSet()) {
-            builder.put("set", resource.getSet().getItemList());
-          }
-          return builder.build();
-        }
-      };
-
-  private static <A, B> Iterable<B> immutable(Iterable<A> iterable, Function<A, B> transform) {
-    return FluentIterable.from(iterable).transform(transform).toList();
-  }
-
-  private static final Function<Offer, Map<String, ?>> TO_BEAN =
-      new Function<Offer, Map<String, ?>>() {
-        @Override public Map<String, ?> apply(Offer offer) {
-          return ImmutableMap.<String, Object>builder()
-              .put("id", offer.getId().getValue())
-              .put("framework_id", offer.getFrameworkId().getValue())
-              .put("slave_id", offer.getSlaveId().getValue())
-              .put("hostname", offer.getHostname())
-              .put("resources", immutable(offer.getResourcesList(), RESOURCE_TO_BEAN))
-              .put("attributes", immutable(offer.getAttributesList(), ATTRIBUTE_TO_BEAN))
-              .put("executor_ids", immutable(offer.getExecutorIdsList(), EXECUTOR_ID_TOSTRING))
-              .build();
-        }
-      };
-}

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/bc1635df/src/main/java/com/twitter/aurora/scheduler/http/PendingTasks.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/twitter/aurora/scheduler/http/PendingTasks.java b/src/main/java/com/twitter/aurora/scheduler/http/PendingTasks.java
deleted file mode 100644
index 359fb97..0000000
--- a/src/main/java/com/twitter/aurora/scheduler/http/PendingTasks.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2013 Twitter, 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 com.twitter.aurora.scheduler.http;
-
-import javax.inject.Inject;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import com.google.common.base.Preconditions;
-
-import com.twitter.aurora.scheduler.async.TaskGroups;
-
-/**
- * Servlet that exposes detailed information about tasks that are pending.
- */
-@Path("/pendingtasks")
-public class PendingTasks {
-
-  private final TaskGroups taskGroups;
-
-  @Inject
-  PendingTasks(TaskGroups taskGroups) {
-    this.taskGroups = Preconditions.checkNotNull(taskGroups);
-  }
-
-  /**
-   * Returns information about pending tasks.
-   *
-   * @return HTTP response.
-   */
-  @GET
-  @Produces(MediaType.APPLICATION_JSON)
-  public Response getOffers() {
-    return Response.ok(taskGroups.getGroups()).build();
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/bc1635df/src/main/java/com/twitter/aurora/scheduler/http/Quotas.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/twitter/aurora/scheduler/http/Quotas.java b/src/main/java/com/twitter/aurora/scheduler/http/Quotas.java
deleted file mode 100644
index 1183275..0000000
--- a/src/main/java/com/twitter/aurora/scheduler/http/Quotas.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright 2013 Twitter, 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 com.twitter.aurora.scheduler.http;
-
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-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.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-
-import org.codehaus.jackson.annotate.JsonProperty;
-
-import com.twitter.aurora.scheduler.storage.Storage;
-import com.twitter.aurora.scheduler.storage.Storage.StoreProvider;
-import com.twitter.aurora.scheduler.storage.Storage.Work;
-import com.twitter.aurora.scheduler.storage.entities.IQuota;
-
-/**
- * Servlet that exposes allocated resource quotas.
- */
-@Path("/quotas")
-public class Quotas {
-
-  private final Storage storage;
-
-  @Inject
-  Quotas(Storage storage) {
-    this.storage = Preconditions.checkNotNull(storage);
-  }
-
-  /**
-   * Dumps allocated resource quotas.
-   *
-   * @return HTTP response.
-   */
-  @GET
-  @Produces(MediaType.APPLICATION_JSON)
-  public Response getOffers(@QueryParam("role") final String role) {
-    return storage.weaklyConsistentRead(new Work.Quiet<Response>() {
-      @Override public Response apply(StoreProvider storeProvider) {
-        Map<String, IQuota> quotas;
-        if (role == null) {
-          quotas = storeProvider.getQuotaStore().fetchQuotas();
-        } else {
-          Optional<IQuota> quota = storeProvider.getQuotaStore().fetchQuota(role);
-          if (quota.isPresent()) {
-            quotas = ImmutableMap.of(role, quota.get());
-          } else {
-            quotas = ImmutableMap.of();
-          }
-        }
-
-        return Response.ok(Maps.transformValues(quotas, TO_BEAN)).build();
-      }
-    });
-  }
-
-  private static final Function<IQuota, QuotaBean> TO_BEAN = new Function<IQuota, QuotaBean>() {
-    @Override public QuotaBean apply(IQuota quota) {
-      return new QuotaBean(quota.getNumCpus(), quota.getRamMb(), quota.getDiskMb());
-    }
-  };
-
-  private static final class QuotaBean {
-    private final double cpu;
-    private final long ramMb;
-    private final long diskMb;
-
-    private QuotaBean(double cpu, long ramMb, long diskMb) {
-      this.cpu = cpu;
-      this.ramMb = ramMb;
-      this.diskMb = diskMb;
-    }
-
-    @JsonProperty("cpu_cores")
-    public double getCpu() {
-      return cpu;
-    }
-
-    @JsonProperty("ram_mb")
-    public long getRamMb() {
-      return ramMb;
-    }
-
-    @JsonProperty("disk_mb")
-    public long getDiskMb() {
-      return diskMb;
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/bc1635df/src/main/java/com/twitter/aurora/scheduler/http/SchedulerzHome.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/twitter/aurora/scheduler/http/SchedulerzHome.java b/src/main/java/com/twitter/aurora/scheduler/http/SchedulerzHome.java
deleted file mode 100644
index 07a3259..0000000
--- a/src/main/java/com/twitter/aurora/scheduler/http/SchedulerzHome.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright 2013 Twitter, 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 com.twitter.aurora.scheduler.http;
-
-import java.util.Set;
-
-import javax.inject.Inject;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import com.google.common.base.Function;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
-
-import org.antlr.stringtemplate.StringTemplate;
-
-import com.twitter.aurora.scheduler.base.Query;
-import com.twitter.aurora.scheduler.base.Tasks;
-import com.twitter.aurora.scheduler.state.CronJobManager;
-import com.twitter.aurora.scheduler.storage.Storage;
-import com.twitter.aurora.scheduler.storage.entities.IJobConfiguration;
-import com.twitter.aurora.scheduler.storage.entities.IScheduledTask;
-import com.twitter.aurora.scheduler.storage.entities.ITaskConfig;
-import com.twitter.common.base.Closure;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import static com.twitter.common.base.MorePreconditions.checkNotBlank;
-
-/**
- * HTTP interface to serve as a HUD for the aurora scheduler.
- */
-@Path("/scheduler")
-public class SchedulerzHome extends JerseyTemplateServlet {
-
-  private static final Function<String, Role> CREATE_ROLE = new Function<String, Role>() {
-    @Override public Role apply(String ownerRole) {
-      Role role = new Role();
-      role.role = ownerRole;
-      return role;
-    }
-  };
-
-  private final Storage storage;
-  private final CronJobManager cronScheduler;
-  private final String clusterName;
-
-  /**
-   * Creates a new scheduler home servlet.
-   *
-   * @param storage Backing store to fetch tasks from.
-   * @param cronScheduler Cron scheduler.
-   * @param clusterName Name of the serving cluster.
-   */
-  @Inject
-  public SchedulerzHome(
-      Storage storage,
-      CronJobManager cronScheduler,
-      @ClusterName String clusterName) {
-
-    super("schedulerzhome");
-    this.storage = checkNotNull(storage);
-    this.cronScheduler = checkNotNull(cronScheduler);
-    this.clusterName = checkNotBlank(clusterName);
-  }
-
-  /**
-   * Fetches the scheduler landing page.
-   *
-   * @return HTTP response.
-   */
-  @GET
-  @Produces(MediaType.TEXT_HTML)
-  public Response get() {
-    return fillTemplate(new Closure<StringTemplate>() {
-      @Override public void execute(StringTemplate template) {
-        template.setAttribute("cluster_name", clusterName);
-
-        LoadingCache<String, Role> owners =
-            CacheBuilder.newBuilder().build(CacheLoader.from(CREATE_ROLE));
-
-        // TODO(William Farner): Render this page without an expensive query.
-        Set<IScheduledTask> tasks =
-            Storage.Util.weaklyConsistentFetchTasks(storage, Query.unscoped());
-        for (ITaskConfig task : Iterables.transform(tasks, Tasks.SCHEDULED_TO_INFO)) {
-          owners.getUnchecked(task.getOwner().getRole()).accumulate(task);
-        }
-
-        // Add cron job counts for each role.
-        for (IJobConfiguration job : cronScheduler.getJobs()) {
-          owners.getUnchecked(job.getOwner().getRole()).accumulate(job);
-        }
-
-        template.setAttribute(
-            "owners",
-            DisplayUtils.ROLE_ORDERING.sortedCopy(owners.asMap().values()));
-      }
-    });
-  }
-
-  /**
-   * Template object to represent a role.
-   */
-  static class Role {
-    private String role;
-    private Set<String> jobs = Sets.newHashSet();
-    private Set<String> cronJobs = Sets.newHashSet();
-
-    private void accumulate(ITaskConfig task) {
-      jobs.add(task.getJobName());
-    }
-
-    private void accumulate(IJobConfiguration job) {
-      cronJobs.add(job.getKey().getName());
-    }
-
-    public String getRole() {
-      return role;
-    }
-
-    public int getJobCount() {
-      return jobs.size();
-    }
-
-    public int getCronJobCount() {
-      return cronJobs.size();
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/bc1635df/src/main/java/com/twitter/aurora/scheduler/http/SchedulerzJob.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/twitter/aurora/scheduler/http/SchedulerzJob.java b/src/main/java/com/twitter/aurora/scheduler/http/SchedulerzJob.java
deleted file mode 100644
index 12b0bec..0000000
--- a/src/main/java/com/twitter/aurora/scheduler/http/SchedulerzJob.java
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * Copyright 2013 Twitter, 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 com.twitter.aurora.scheduler.http;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-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 org.antlr.stringtemplate.StringTemplate;
-
-import com.twitter.aurora.gen.ScheduleStatus;
-import com.twitter.aurora.gen.apiConstants;
-import com.twitter.aurora.scheduler.base.JobKeys;
-import com.twitter.aurora.scheduler.base.Query;
-import com.twitter.aurora.scheduler.base.Tasks;
-import com.twitter.aurora.scheduler.filter.SchedulingFilter.Veto;
-import com.twitter.aurora.scheduler.metadata.NearestFit;
-import com.twitter.aurora.scheduler.state.CronJobManager;
-import com.twitter.aurora.scheduler.storage.Storage;
-import com.twitter.aurora.scheduler.storage.entities.IAssignedTask;
-import com.twitter.aurora.scheduler.storage.entities.IConstraint;
-import com.twitter.aurora.scheduler.storage.entities.IJobKey;
-import com.twitter.aurora.scheduler.storage.entities.IScheduledTask;
-import com.twitter.aurora.scheduler.storage.entities.ITaskConfig;
-import com.twitter.aurora.scheduler.storage.entities.ITaskConstraint;
-import com.twitter.aurora.scheduler.storage.entities.ITaskEvent;
-import com.twitter.common.base.Closure;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import static com.twitter.aurora.gen.ScheduleStatus.ASSIGNED;
-import static com.twitter.aurora.gen.ScheduleStatus.FAILED;
-import static com.twitter.aurora.gen.ScheduleStatus.FINISHED;
-import static com.twitter.aurora.gen.ScheduleStatus.KILLED;
-import static com.twitter.aurora.gen.ScheduleStatus.KILLING;
-import static com.twitter.aurora.gen.ScheduleStatus.LOST;
-import static com.twitter.aurora.gen.ScheduleStatus.PENDING;
-import static com.twitter.aurora.gen.ScheduleStatus.RUNNING;
-import static com.twitter.aurora.gen.ScheduleStatus.STARTING;
-import static com.twitter.common.base.MorePreconditions.checkNotBlank;
-
-/**
- * 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))
-        .put(FINISHED, EnumSet.of(KILLED, FINISHED))
-        .put(FAILED, EnumSet.of(LOST, FAILED))
-      .build();
-
-  private static final Comparator<IScheduledTask> REVERSE_CHRON_COMPARATOR =
-      new Comparator<IScheduledTask>() {
-        @Override public int compare(IScheduledTask taskA, IScheduledTask taskB) {
-          // Sort in reverse chronological order.
-          Iterable<ITaskEvent> taskAEvents = taskA.getTaskEvents();
-          Iterable<ITaskEvent> taskBEvents = taskB.getTaskEvents();
-
-          boolean taskAHasEvents = taskAEvents != null && !Iterables.isEmpty(taskAEvents);
-          boolean taskBHasEvents = taskBEvents != null && !Iterables.isEmpty(taskBEvents);
-          if (taskAHasEvents && taskBHasEvents) {
-            return Long.signum(Iterables.getLast(taskBEvents).getTimestamp()
-                - Iterables.getLast(taskAEvents).getTimestamp());
-          } else {
-            return 0;
-          }
-        }
-      };
-
-  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("status", scheduledTask.getStatus())
-            .put("statusTimestamp", Iterables.getLast(scheduledTask.getTaskEvents()).getTimestamp())
-            .put("taskEvents", scheduledTask.getTaskEvents());
-
-          if (scheduledTask.getStatus() == ScheduleStatus.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);
-          }
-
-          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 Backing store to fetch tasks from.
-   * @param clusterName Name of the serving cluster.
-   */
-  @Inject
-  public SchedulerzJob(
-      Storage storage,
-      CronJobManager cronJobManager,
-      @ClusterName String clusterName,
-      NearestFit nearestFit) {
-
-    super("schedulerzjob");
-    this.storage = checkNotNull(storage);
-    this.clusterName = checkNotBlank(clusterName);
-    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())));
-          }
-          if (!task.getPackages().isEmpty()) {
-            List<String> packages = Ordering.natural().sortedCopy(
-                Iterables.transform(task.getPackages(), TransformationUtils.PACKAGE_TOSTRING));
-            details.put(
-                "packages",
-                Joiner.on(',').join(packages));
-          }
-          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, REVERSE_CHRON_COMPARATOR);
-          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/bc1635df/src/main/java/com/twitter/aurora/scheduler/http/SchedulerzRole.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/twitter/aurora/scheduler/http/SchedulerzRole.java b/src/main/java/com/twitter/aurora/scheduler/http/SchedulerzRole.java
deleted file mode 100644
index 756c672..0000000
--- a/src/main/java/com/twitter/aurora/scheduler/http/SchedulerzRole.java
+++ /dev/null
@@ -1,393 +0,0 @@
-/*
- * Copyright 2013 Twitter, 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 com.twitter.aurora.scheduler.http;
-
-import java.util.Collection;
-import java.util.Date;
-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.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-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.Ordering;
-import com.google.common.collect.Sets;
-
-import org.antlr.stringtemplate.StringTemplate;
-
-import com.twitter.aurora.gen.CronCollisionPolicy;
-import com.twitter.aurora.gen.ScheduleStatus;
-import com.twitter.aurora.gen.apiConstants;
-import com.twitter.aurora.scheduler.base.JobKeys;
-import com.twitter.aurora.scheduler.base.Query;
-import com.twitter.aurora.scheduler.base.Tasks;
-import com.twitter.aurora.scheduler.cron.CronPredictor;
-import com.twitter.aurora.scheduler.quota.QuotaManager;
-import com.twitter.aurora.scheduler.quota.Quotas;
-import com.twitter.aurora.scheduler.state.CronJobManager;
-import com.twitter.aurora.scheduler.storage.Storage;
-import com.twitter.aurora.scheduler.storage.entities.IJobConfiguration;
-import com.twitter.aurora.scheduler.storage.entities.IJobKey;
-import com.twitter.aurora.scheduler.storage.entities.IQuota;
-import com.twitter.aurora.scheduler.storage.entities.IScheduledTask;
-import com.twitter.aurora.scheduler.storage.entities.ITaskConfig;
-import com.twitter.common.base.Closure;
-import com.twitter.common.quantity.Amount;
-import com.twitter.common.quantity.Time;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import static com.twitter.aurora.scheduler.base.Tasks.GET_STATUS;
-import static com.twitter.aurora.scheduler.base.Tasks.LATEST_ACTIVITY;
-import static com.twitter.common.base.MorePreconditions.checkNotBlank;
-
-/**
- * HTTP interface to provide information about jobs for a specific role.
- */
-@Path("/scheduler/{role}")
-public class SchedulerzRole extends JerseyTemplateServlet {
-
-  private static final List<ScheduleStatus> STATUSES = ImmutableList.<ScheduleStatus>builder()
-      .addAll(apiConstants.TERMINAL_STATES)
-      .addAll(apiConstants.ACTIVE_STATES)
-      .build();
-
-  // The freshest task is the latest active task
-  // or the latest inactive task if no active task exists.
-  private static final Ordering<IScheduledTask> FRESH_TASK_ORDER =
-      Ordering.explicit(STATUSES).onResultOf(GET_STATUS).compound(LATEST_ACTIVITY);
-
-  @VisibleForTesting
-  static IScheduledTask getFreshestTask(Iterable<IScheduledTask> tasks) {
-    return FRESH_TASK_ORDER.max(tasks);
-  }
-
-  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,
-      @ClusterName String clusterName,
-      QuotaManager quotaManager) {
-
-    super("schedulerzrole");
-    this.storage = checkNotNull(storage);
-    this.cronJobManager = checkNotNull(cronJobManager);
-    this.cronPredictor = checkNotNull(cronPredictor);
-    this.clusterName = checkNotBlank(clusterName);
-    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.
-        template.setAttribute("prodResourcesUsed", quotaManager.getConsumption(role.get()));
-        template.setAttribute("nonProdResourcesUsed", getNonProdConsumption(role.get()));
-        template.setAttribute("resourceQuota", getQuota(role.get()));
-      }
-    });
-  }
-
-  private IQuota getQuota(final String role) {
-    return Storage.Util.consistentFetchQuota(storage, role).or(Quotas.noQuota());
-  }
-
-  private IQuota getNonProdConsumption(String role) {
-    FluentIterable<ITaskConfig> tasks = FluentIterable
-        .from(Storage.Util.weaklyConsistentFetchTasks(storage, Query.roleScoped(role).active()))
-        .transform(Tasks.SCHEDULED_TO_INFO)
-        .filter(Predicates.not(Tasks.IS_PRODUCTION));
-
-    return Quotas.fromTasks(tasks);
-  }
-
-  /**
-   * 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("packages", getPackages(job))
-                .build();
-          }
-        });
-  }
-
-  private static CronCollisionPolicy cronCollisionPolicy(IJobConfiguration jobConfiguration) {
-    return CronJobManager.orDefault(jobConfiguration.getCronCollisionPolicy());
-  }
-
-  private static String getPackages(IJobConfiguration job) {
-    Set<String> packages = Sets.newHashSet();
-
-    // Insert all packages for all tasks in the set to eliminate duplicates
-    ITaskConfig task = job.getTaskConfig();
-    if (!task.getPackages().isEmpty()) {
-      packages.addAll(Lists.newArrayList(
-          Iterables.transform(task.getPackages(), TransformationUtils.PACKAGE_TOSTRING)));
-    }
-    return Joiner.on(',').join(packages);
-  }
-
-  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();
-
-            Job job = new Job();
-            job.environment = jobKey.getEnvironment();
-            job.name = jobKey.getName();
-
-            // Pick the freshest task's config and associate it with the job.
-            ITaskConfig freshestConfig = getFreshestTask(tasks).getAssignedTask().getTask();
-            job.production = freshestConfig.isProduction();
-
-            // TODO(Suman Karumuri): Add a source/job type to TaskConfig and replace logic below
-            if (freshestConfig.isIsService()) {
-              job.type = JobType.SERVICE;
-            } else if (cronJobs.containsKey(jobKey)) {
-              job.type = JobType.CRON;
-            } else {
-              job.type = JobType.ADHOC;
-            }
-
-            for (IScheduledTask task : tasks) {
-              switch (task.getStatus()) {
-                case INIT:
-                case PENDING:
-                  job.pendingTaskCount++;
-                  break;
-
-                case ASSIGNED:
-                case STARTING:
-                case RESTARTING:
-                case RUNNING:
-                case KILLING:
-                case PREEMPTING:
-                  job.activeTaskCount++;
-                  break;
-
-                case KILLED:
-                case FINISHED:
-                  job.finishedTaskCount++;
-                  break;
-
-                case LOST:
-                case FAILED:
-                case UNKNOWN:
-                  job.failedTaskCount++;
-                  Date now = new Date();
-                  long elapsedMillis = now.getTime()
-                      - Iterables.getLast(task.getTaskEvents()).getTimestamp();
-
-                  if (Amount.of(elapsedMillis, Time.MILLISECONDS).as(Time.HOURS) < 6) {
-                    job.recentlyFailedTaskCount++;
-                  }
-                  break;
-
-                default:
-                  throw new IllegalArgumentException("Unsupported status: " + task.getStatus());
-              }
-            }
-
-            return job;
-          }
-        };
-
-    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 String name;
-    private String environment;
-    private int pendingTaskCount = 0;
-    private int activeTaskCount = 0;
-    private int finishedTaskCount = 0;
-    private int failedTaskCount = 0;
-    private int recentlyFailedTaskCount = 0;
-    private boolean production = false;
-    private JobType 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/bc1635df/src/main/java/com/twitter/aurora/scheduler/http/ServletModule.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/twitter/aurora/scheduler/http/ServletModule.java b/src/main/java/com/twitter/aurora/scheduler/http/ServletModule.java
deleted file mode 100644
index 825e2e1..0000000
--- a/src/main/java/com/twitter/aurora/scheduler/http/ServletModule.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright 2013 Twitter, 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 com.twitter.aurora.scheduler.http;
-
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.io.Resources;
-import com.google.common.net.MediaType;
-import com.google.inject.AbstractModule;
-import com.google.inject.Key;
-import com.google.inject.TypeLiteral;
-import com.google.inject.servlet.GuiceFilter;
-import com.sun.jersey.api.container.filter.GZIPContentEncodingFilter;
-import com.sun.jersey.guice.JerseyServletModule;
-import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
-
-import com.twitter.aurora.scheduler.quota.QuotaManager;
-import com.twitter.aurora.scheduler.state.CronJobManager;
-import com.twitter.aurora.scheduler.state.SchedulerCore;
-import com.twitter.common.application.http.Registration;
-import com.twitter.common.application.modules.LifecycleModule;
-import com.twitter.common.application.modules.LocalServiceRegistry;
-import com.twitter.common.base.ExceptionalCommand;
-import com.twitter.common.net.pool.DynamicHostSet;
-import com.twitter.common.net.pool.DynamicHostSet.MonitorException;
-import com.twitter.thrift.ServiceInstance;
-
-import static com.sun.jersey.api.core.ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS;
-import static com.sun.jersey.api.core.ResourceConfig.PROPERTY_CONTAINER_RESPONSE_FILTERS;
-import static com.sun.jersey.api.json.JSONConfiguration.FEATURE_POJO_MAPPING;
-
-/**
- * Binding module for scheduler HTTP servlets.
- */
-public class ServletModule extends AbstractModule {
-
-  private static final Map<String, String> CONTAINER_PARAMS = ImmutableMap.of(
-      FEATURE_POJO_MAPPING, Boolean.TRUE.toString(),
-      PROPERTY_CONTAINER_REQUEST_FILTERS, GZIPContentEncodingFilter.class.getName(),
-      PROPERTY_CONTAINER_RESPONSE_FILTERS, GZIPContentEncodingFilter.class.getName());
-
-  @Override
-  protected void configure() {
-    requireBinding(SchedulerCore.class);
-    requireBinding(CronJobManager.class);
-    requireBinding(Key.get(String.class, ClusterName.class));
-    requireBinding(QuotaManager.class);
-
-    // Bindings required for the leader redirector.
-    requireBinding(LocalServiceRegistry.class);
-    requireBinding(Key.get(new TypeLiteral<DynamicHostSet<ServiceInstance>>() { }));
-    Registration.registerServletFilter(binder(), GuiceFilter.class, "/*");
-    install(new JerseyServletModule() {
-      private void registerJerseyEndpoint(String indexPath, Class<?>... servlets) {
-        filter(indexPath + "*").through(LeaderRedirectFilter.class);
-        filter(indexPath + "*").through(GuiceContainer.class, CONTAINER_PARAMS);
-        Registration.registerEndpoint(binder(), indexPath);
-        for (Class<?> servlet : servlets) {
-          bind(servlet);
-        }
-      }
-
-      @Override protected void configureServlets() {
-        bind(HttpStatsFilter.class).in(Singleton.class);
-        filter("/scheduler*").through(HttpStatsFilter.class);
-        bind(LeaderRedirectFilter.class).in(Singleton.class);
-        registerJerseyEndpoint("/cron", Cron.class);
-        registerJerseyEndpoint("/maintenance", Maintenance.class);
-        registerJerseyEndpoint("/mname", Mname.class);
-        registerJerseyEndpoint("/offers", Offers.class);
-        registerJerseyEndpoint("/pendingtasks", PendingTasks.class);
-        registerJerseyEndpoint("/quotas", Quotas.class);
-        registerJerseyEndpoint(
-            "/scheduler",
-            SchedulerzHome.class,
-            SchedulerzRole.class,
-            SchedulerzJob.class);
-        registerJerseyEndpoint("/slaves", Slaves.class);
-        registerJerseyEndpoint("/structdump", StructDump.class);
-        registerJerseyEndpoint("/utilization", Utilization.class);
-      }
-    });
-
-    // Static assets.
-    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");
-
-    bind(LeaderRedirect.class).in(Singleton.class);
-    LifecycleModule.bindStartupAction(binder(), RedirectMonitor.class);
-  }
-
-  private void registerJQueryAssets() {
-    registerAsset("bower_components/jquery/jquery.js", "/js/jquery.min.js", false);
-  }
-
-  private void registerBootstrapAssets() {
-    final String BOOTSTRAP_PATH = "bower_components/bootstrap.css/";
-
-    registerAsset(BOOTSTRAP_PATH + "js/bootstrap.min.js", "/js/bootstrap.min.js", false);
-    registerAsset(BOOTSTRAP_PATH + "css/bootstrap.min.css", "/css/bootstrap.min.css", false);
-    registerAsset(BOOTSTRAP_PATH + "css/bootstrap-responsive.min.css",
-        "/css/bootstrap-responsive.min.css",
-        false);
-    registerAsset(BOOTSTRAP_PATH + "img/glyphicons-halflings-white.png",
-        "/img/glyphicons-halflings-white.png",
-        false);
-    registerAsset(BOOTSTRAP_PATH + "img/glyphicons-halflings.png",
-        "/img/glyphicons-halflings.png",
-        false);
-  }
-
-  private void registerAsset(String resourceLocation, String registerLocation) {
-    registerAsset(resourceLocation, registerLocation, true);
-  }
-
-  private void registerAsset(String resourceLocation, String registerLocation, boolean isRelative) {
-    String mediaType = getMediaType(registerLocation).toString();
-
-    if (isRelative) {
-      Registration.registerHttpAsset(
-          binder(),
-          registerLocation,
-          ServletModule.class,
-          resourceLocation,
-          mediaType,
-          true);
-    } else {
-      Registration.registerHttpAsset(
-          binder(),
-          registerLocation,
-          Resources.getResource(resourceLocation),
-          mediaType,
-          true);
-    }
-  }
-
-  private MediaType getMediaType(String filePath) {
-    if (filePath.endsWith(".png")) {
-      return MediaType.PNG;
-    } else if (filePath.endsWith(".js")) {
-      return MediaType.JAVASCRIPT_UTF_8;
-    } else if (filePath.endsWith(".html")) {
-      return MediaType.HTML_UTF_8;
-    } else if (filePath.endsWith(".css")) {
-      return MediaType.CSS_UTF_8;
-    } else {
-      throw new IllegalArgumentException("Could not determine media type for " + filePath);
-    }
-  }
-
-  static class RedirectMonitor implements ExceptionalCommand<MonitorException> {
-
-    private final LeaderRedirect redirector;
-
-    @Inject
-    RedirectMonitor(LeaderRedirect redirector) {
-      this.redirector = Preconditions.checkNotNull(redirector);
-    }
-
-    @Override public void execute() throws MonitorException {
-      redirector.monitor();
-    }
-  }
-}