This project has retired. For details please refer to its Attic page.
Source code
001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.reef.examples.scheduler.driver.http;
020
021import org.apache.reef.examples.scheduler.driver.SchedulerDriver;
022import org.apache.reef.examples.scheduler.driver.exceptions.NotFoundException;
023import org.apache.reef.examples.scheduler.driver.exceptions.UnsuccessfulException;
024import org.apache.reef.tang.InjectionFuture;
025import org.apache.reef.webserver.HttpHandler;
026import org.apache.reef.webserver.ParsedHttpRequest;
027
028import javax.inject.Inject;
029import javax.servlet.ServletException;
030import javax.servlet.http.HttpServletResponse;
031import java.io.IOException;
032import java.util.List;
033import java.util.Map;
034
035/**
036 * Receive HttpRequest so that it can handle the command list.
037 */
038public final class SchedulerHttpHandler implements HttpHandler {
039  private final InjectionFuture<SchedulerDriver> schedulerDriver;
040
041  private String uriSpecification = "reef-example-scheduler";
042
043  @Inject
044  private SchedulerHttpHandler(final InjectionFuture<SchedulerDriver> schedulerDriver) {
045    this.schedulerDriver = schedulerDriver;
046  }
047
048  @Override
049  public String getUriSpecification() {
050    return uriSpecification;
051  }
052
053  @Override
054  public void setUriSpecification(final String s) {
055    uriSpecification = s;
056  }
057
058  /**
059   * HttpRequest handler. You must specify UriSpecification and API version.
060   * The request url is http://{address}:{port}/scheduler/v1
061   *
062   * APIs
063   *   /list                to get the status list for all tasks
064   *   /status?id={id}      to query the status of such a task, given id
065   *   /submit?cmd={cmd}    to submit a Task, which returns its id
066   *   /cancel?id={id}      to cancel the task's execution
067   *   /max-eval?num={num}  to set the maximum number of evaluators
068   *   /clear               to clear the waiting queue
069   */
070  @Override
071  public void onHttpRequest(final ParsedHttpRequest request, final HttpServletResponse response)
072      throws IOException, ServletException {
073    final String target = request.getTargetEntity().toLowerCase();
074    final Map<String, List<String>> queryMap = request.getQueryMap();
075
076    final SchedulerResponse result;
077    switch (target) {
078    case "list":
079      result = onList();
080      break;
081    case "clear":
082      result = onClear();
083      break;
084    case "status":
085      result = onStatus(queryMap);
086      break;
087    case "submit":
088      result = onSubmit(queryMap);
089      break;
090    case "cancel":
091      result = onCancel(queryMap);
092      break;
093    case "max-eval":
094      result = onMaxEval(queryMap);
095      break;
096    default:
097      result = SchedulerResponse.notFound("Unsupported operation");
098    }
099
100    // Send response to the http client
101    final int status = result.getStatus();
102    final String message= result.getMessage();
103
104    if (result.isOK()) {
105      response.getOutputStream().println(message);
106    } else {
107      response.sendError(status, message);
108    }
109  }
110
111  private SchedulerResponse onList() {
112    final Map<String, List<Integer>> listMap = schedulerDriver.get().getList();
113
114    final StringBuilder sb = new StringBuilder();
115    for (final Map.Entry<String, List<Integer>> entry : listMap.entrySet()) {
116      sb.append("\n").append(entry.getKey()).append(" :");
117      for (final int taskId : entry.getValue()) {
118        sb.append(" ").append(taskId);
119      }
120    }
121    return SchedulerResponse.ok(sb.toString());
122  }
123
124  private SchedulerResponse onClear() {
125    final int count = schedulerDriver.get().clearList();
126    return SchedulerResponse.ok(count + " tasks removed.");
127  }
128
129  private SchedulerResponse onStatus(final Map<String, List<String>> queryMap) {
130    final List<String> args = queryMap.get("id");
131    if (args.size() != 1) {
132      return SchedulerResponse.badRequest("Usage : only one ID at a time");
133    }
134
135    try {
136
137      final int taskId = Integer.parseInt(args.get(0));
138      return SchedulerResponse.ok(schedulerDriver.get().getTaskStatus(taskId));
139
140    } catch (final NotFoundException e) {
141      return SchedulerResponse.notFound(e.getMessage());
142    } catch (final NumberFormatException e) {
143      return SchedulerResponse.badRequest("Usage : ID must be an integer");
144    }
145  }
146
147  private SchedulerResponse onSubmit(final Map<String, List<String>> queryMap) {
148    final List<String> args = queryMap.get("cmd");
149    if (args.size() != 1) {
150      return SchedulerResponse.badRequest("Usage : only one command at a time");
151    }
152
153    return SchedulerResponse.ok("Task ID : " + schedulerDriver.get().submitCommand(args.get(0)));
154  }
155
156  private SchedulerResponse onCancel(final Map<String, List<String>> queryMap) {
157    final List<String> args = queryMap.get("id");
158    if (args.size() != 1) {
159      return SchedulerResponse.badRequest("Usage : only one ID at a time");
160    }
161
162    try {
163
164      final int taskId = Integer.parseInt(args.get(0));
165      final int canceledId = schedulerDriver.get().cancelTask(taskId);
166      return SchedulerResponse.ok("Canceled " + canceledId);
167
168    } catch (final NotFoundException e) {
169      return SchedulerResponse.notFound(e.getMessage());
170    } catch (final UnsuccessfulException e) {
171      return SchedulerResponse.forbidden(e.getMessage());
172    } catch (final NumberFormatException e) {
173      return SchedulerResponse.badRequest("Usage : ID must be an integer");
174    }
175  }
176
177  private SchedulerResponse onMaxEval(final Map<String, List<String>> queryMap) {
178    final List<String> args = queryMap.get("num");
179    if (args.size() != 1) {
180      return SchedulerResponse.badRequest("Usage : Only one value can be used");
181    }
182
183    try {
184
185      final int targetNum = Integer.parseInt(args.get(0));
186      final int maxEval = schedulerDriver.get().setMaxEvaluators(targetNum);
187      return SchedulerResponse.ok("You can use up to " + maxEval + " evaluators.");
188
189    } catch (final UnsuccessfulException e) {
190      return SchedulerResponse.forbidden(e.getMessage());
191    } catch (final NumberFormatException e) {
192      return SchedulerResponse.badRequest("Usage : num must be an integer");
193    }
194  }
195}