package edu.harvard.mcb.leschziner.manage;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import org.vertx.java.core.Handler;
import org.vertx.java.core.Vertx;
import org.vertx.java.core.buffer.Buffer;
import org.vertx.java.core.http.HttpServer;
import org.vertx.java.core.http.HttpServerRequest;
import org.vertx.java.core.http.HttpServerResponse;
import org.vertx.java.core.http.RouteMatcher;
/**
* A Manager serves as an API endpoint to handle requests for information or
* modifications of pipelines. It hands requests off to the appropriate guardian
* where pipeline state is actually stored. Managers are responsible for
* resource allocation and reporting.
*
* @author spartango
*
*/
public class GuardianManager {
private static final Vertx vertx = Vertx.newVertx();
public static final int DEFAULT_PORT = 8082;
private final Map<UUID, PipelineGuardian> guardians;
// HTTP Server
private final HttpServer server;
private final RouteMatcher routeMatcher;
public GuardianManager() {
this(DEFAULT_PORT);
}
public GuardianManager(int port) {
guardians = new ConcurrentHashMap<UUID, PipelineGuardian>();
routeMatcher = new RouteMatcher();
server = vertx.createHttpServer();
setupRoutes();
setupServer(port);
}
private void setupRoutes() {
routeMatcher.get("/pipeline/:uuid/status",
new Handler<HttpServerRequest>() {
@Override public void
handle(HttpServerRequest arg0) {
handleStatus(arg0);
}
});
routeMatcher.get("/pipeline/:uuid/results",
new Handler<HttpServerRequest>() {
@Override public void
handle(HttpServerRequest arg0) {
handleResults(arg0);
}
});
routeMatcher.post("/pipeline/:uuid/destroy",
new Handler<HttpServerRequest>() {
@Override public void
handle(HttpServerRequest arg0) {
handleDestroy(arg0);
}
});
routeMatcher.post("/pipeline/create", new Handler<HttpServerRequest>() {
@Override public void handle(HttpServerRequest arg0) {
handleCreate(arg0);
}
});
}
private void setupServer(int port) {
server.requestHandler(routeMatcher).listen(port);
}
public void handleStatus(HttpServerRequest request) {
HttpServerResponse response = request.response;
String guardianId = request.params().get("uuid");
if (guardianId == null) {
response.statusCode = 400;
response.end();
return;
}
PipelineGuardian guardian = getGuardians().get(UUID.fromString(guardianId));
if (guardian == null) {
response.statusCode = 404;
response.end();
return;
}
response.end(guardian.getStatusJSON());
}
public void handleResults(HttpServerRequest request) {
HttpServerResponse response = request.response;
String guardianId = request.params().get("uuid");
if (guardianId == null) {
response.statusCode = 400;
response.end();
return;
}
PipelineGuardian guardian = getGuardians().get(UUID.fromString(guardianId));
if (guardian == null) {
response.statusCode = 404;
response.end();
return;
}
String results = guardian.getResultsJSON();
if (results == null) {
response.statusCode = 403;
response.end("{}");
return;
}
response.end(results);
}
public void handleDestroy(HttpServerRequest request) {
HttpServerResponse response = request.response;
String guardianId = request.params().get("uuid");
if (guardianId == null) {
response.statusCode = 400;
response.end();
return;
}
UUID gid = UUID.fromString(guardianId);
PipelineGuardian guardian = getGuardians().get(gid);
if (guardian == null) {
response.statusCode = 404;
response.end();
return;
}
guardian.destroy();
guardians.remove(gid);
response.end();
}
public void handleCreate(HttpServerRequest request) {
final HttpServerResponse response = request.response;
// Do something with it at the end
request.bodyHandler(new Handler<Buffer>() {
@Override public void handle(Buffer body) {
// Grab the body
String bodyText = body.getString(0, body.length());
System.out.println("[BodyHandler]: Got "
+ body.length()
+ " bytes");
// Allocate a guardian
// Pass the pipeline parameters
PipelineGuardian newGuardian = new PipelineGuardian();
if (newGuardian.initialize(bodyText)) {
// Give the client a guardian ID
getGuardians().put(newGuardian.getUUID(), newGuardian);
response.end(newGuardian.getUUID().toString());
} else {
response.statusCode = 400;
response.statusMessage = "Bad Pipeline Parameters";
response.end();
}
}
});
}
public void close() {
server.close();
}
public Map<UUID, PipelineGuardian> getGuardians() {
return guardians;
}
}