package com.mozilla.grouperfish.rest.jaxrs; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.StatusType; import javax.ws.rs.core.Response.Status.Family; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.inject.Inject; import com.mozilla.grouperfish.base.Box; import com.mozilla.grouperfish.batch.api.BatchService; import com.mozilla.grouperfish.model.Type; import com.mozilla.grouperfish.model.Access.Operation; import com.mozilla.grouperfish.model.Query; import com.mozilla.grouperfish.model.TransformConfig; import com.mozilla.grouperfish.naming.Scope; import com.mozilla.grouperfish.services.api.Grid; import static com.mozilla.grouperfish.rest.jaxrs.RestHelper.ACCEPTED; import static com.mozilla.grouperfish.rest.jaxrs.RestHelper.FAIL; import static com.mozilla.grouperfish.rest.jaxrs.RestHelper.FORBIDDEN; public class RunResource { private static final Logger log = LoggerFactory.getLogger(RunResource.class); @Path("/run/{namespace}") public static class ForAll extends RunResourceBase { @Inject public ForAll(final Grid grid, final BatchService batchService) { super(grid, batchService); } @POST public Response runTransformsForQuery(@PathParam("namespace") final String namespace, @Context final HttpServletRequest request) { final Scope ns = scope(namespace); if (!ns.allows(RunResource.class, new HttpAccess(Operation.RUN, request))) { return FORBIDDEN; } try { batchService().schedule(ns); } catch (final Exception e) { log.error(String.format("Error initiating run request '%s'", request.getPathInfo()), e); return FAIL; } return ACCEPTED; } } @Path("/run/{namespace}/{queryName}") public static class ForQuery extends RunResourceBase { @Inject public ForQuery(final Grid grid, final BatchService batchService) { super(grid, batchService); } @POST public Response runTransformsForQuery(@PathParam("namespace") final String namespace, @PathParam("transformName") final String transformName, @PathParam("queryName") final String queryName, @Context final HttpServletRequest request) { final Scope ns = scope(namespace); if (!ns.allows(RunResource.class, new HttpAccess(Operation.RUN, request))) { return FORBIDDEN; } final Box<Response> any404 = new Box<Response>(); final Query q = fetchQuery(ns, queryName, any404); for (final Response some404 : any404) return some404; try { batchService().schedule(ns, q); } catch (final Exception e) { log.error(String.format("Error initiating run request '%s'", request.getPathInfo()), e); return FAIL; } return ACCEPTED; } } @Path("/run/{namespace}/{transformName}/{queryName}") public static class ForQueryWithTransform extends RunResourceBase { @Inject public ForQueryWithTransform(final Grid grid, final BatchService system) { super(grid, system); } @POST public Response runOneTransformForQuery(@PathParam("namespace") final String namespace, @PathParam("transformName") final String transformName, @PathParam("queryName") final String queryName, @Context final HttpServletRequest request) { final Scope ns = scope(namespace); if (!ns.allows(RunResource.class, new HttpAccess(Operation.RUN, request))) { return FORBIDDEN; } final Box<Response> any404 = new Box<Response>(); final Query q = fetchQuery(ns, queryName, any404); for (final Response some404 : any404) return some404; final TransformConfig config = fetchTransformConfig(ns, transformName, any404); for (final Response some404 : any404) return some404; try { log.debug("Scheduling run: {} / {}", ns, q); batchService().schedule(ns, q, config); } catch (final Exception e) { log.error(String.format("Error initiating run request '%s'", request.getPathInfo()), e); return FAIL; } return ACCEPTED; } } private static final Query fetchQuery(final Scope ns, final String name, final Box<Response> failure) { final String json = ns.queries().get(name); if (json != null) { return new Query(name, json); } failure.put(Response.status(new StatusType() { @Override public int getStatusCode() { return 404; } @Override public String getReasonPhrase() { return "Unknown query: " + name; } @Override public Family getFamily() { return Family.CLIENT_ERROR; } }).build()); return null; } private static final TransformConfig fetchTransformConfig(final Scope ns, final String name, final Box<Response> failure) { final String json = ns.map(Type.CONFIGURATION_TRANSFORM).get(name); if (json != null) { return new TransformConfig(name, json); } failure.put(Response.status(new StatusType() { @Override public int getStatusCode() { return 404; } @Override public String getReasonPhrase() { return "Unknown transform: " + name; } @Override public Family getFamily() { return Family.CLIENT_ERROR; } }).build()); return null; } private static abstract class RunResourceBase extends ResourceBase { private final BatchService batchService; RunResourceBase(final Grid grid, final BatchService batchService) { super(grid); this.batchService = batchService; } protected BatchService batchService() { return batchService; } } }