@POST @Path("/request/{requestId}/run") @Consumes({MediaType.APPLICATION_JSON}) @ApiOperation( value = "Schedule a one-off or scheduled Singularity request for immediate execution.", response = SingularityRequestParent.class) @ApiResponses({ @ApiResponse(code = 400, message = "Singularity Request is not scheduled or one-off"), }) public SingularityPendingRequestParent scheduleImmediately( @ApiParam("The request ID to run") @PathParam("requestId") String requestId, @ApiParam("Username of the person requesting the execution") @QueryParam("user") Optional<String> user, @ApiParam("Additional command line arguments to append to the task") List<String> commandLineArgs) { SingularityRequestWithState requestWithState = fetchRequestWithState(requestId); checkConflict( requestWithState.getState() != RequestState.PAUSED, "Request %s is paused. Unable to run now (it must be manually unpaused first)", requestWithState.getRequest().getId()); PendingType pendingType = null; if (requestWithState.getRequest().isScheduled()) { pendingType = PendingType.IMMEDIATE; checkConflict( taskManager.getActiveTaskIdsForRequest(requestId).isEmpty(), "Can not request an immediate run of a scheduled job which is currently running (%s)", taskManager.getActiveTaskIdsForRequest(requestId)); } else if (requestWithState.getRequest().isOneOff()) { pendingType = PendingType.ONEOFF; } else { throw badRequest( "Can not request an immediate run of a non-scheduled / always running request (%s)", requestWithState.getRequest()); } final SingularityPendingRequest pendingRequest = new SingularityPendingRequest( requestId, getAndCheckDeployId(requestId), System.currentTimeMillis(), user, pendingType, commandLineArgs); SingularityCreateResult result = requestManager.addToPendingQueue(pendingRequest); checkConflict( result != SingularityCreateResult.EXISTED, "%s is already pending, please try again soon", requestId); return SingularityPendingRequestParent.fromSingularityRequestParent( fillEntireRequest(requestWithState), pendingRequest); }
@POST @Path("/request/{requestId}/pause") @ApiOperation( value = "Pause a Singularity request, future tasks will not run until it is manually unpaused. API can optionally choose to kill existing tasks", response = SingularityRequestParent.class) @ApiResponses({ @ApiResponse(code = 409, message = "Request is already paused or being cleaned"), }) public SingularityRequestParent pause( @ApiParam("The request ID to pause") @PathParam("requestId") String requestId, @ApiParam("Username of the person requesting the pause") @QueryParam("user") Optional<String> user, @ApiParam("Pause Request Options") Optional<SingularityPauseRequest> pauseRequest) { SingularityRequestWithState requestWithState = fetchRequestWithState(requestId); checkConflict( requestWithState.getState() != RequestState.PAUSED, "Request %s is paused. Unable to pause (it must be manually unpaused first)", requestWithState.getRequest().getId()); Optional<Boolean> killTasks = Optional.absent(); if (pauseRequest.isPresent()) { user = pauseRequest.get().getUser(); killTasks = pauseRequest.get().getKillTasks(); } final long now = System.currentTimeMillis(); SingularityCreateResult result = requestManager.createCleanupRequest( new SingularityRequestCleanup( user, RequestCleanupType.PAUSING, now, killTasks, requestId, Optional.<String>absent())); checkConflict( result == SingularityCreateResult.CREATED, "%s is already pausing - try again soon", requestId, result); mailer.sendRequestPausedMail(requestWithState.getRequest(), user); requestManager.pause(requestWithState.getRequest(), now, user); return fillEntireRequest( new SingularityRequestWithState(requestWithState.getRequest(), RequestState.PAUSED, now)); }
@POST @Consumes({MediaType.APPLICATION_JSON}) @ApiOperation( value = "Create or update a Singularity Request", response = SingularityRequestParent.class) @ApiResponses({ @ApiResponse(code = 400, message = "Request object is invalid"), @ApiResponse(code = 409, message = "Request object is being cleaned. Try again shortly"), }) public SingularityRequestParent submit( @ApiParam("The Singularity request to create or update") SingularityRequest request, @ApiParam("Username of the person requesting to create or update") @QueryParam("user") Optional<String> user) { checkNotNullBadRequest(request.getId(), "Request must have an id"); checkConflict( !requestManager.cleanupRequestExists(request.getId()), "Request %s is currently cleaning. Try again after a few moments", request.getId()); Optional<SingularityRequestWithState> maybeOldRequestWithState = requestManager.getRequest(request.getId()); Optional<SingularityRequest> maybeOldRequest = maybeOldRequestWithState.isPresent() ? Optional.of(maybeOldRequestWithState.get().getRequest()) : Optional.<SingularityRequest>absent(); SingularityRequestDeployHolder deployHolder = getDeployHolder(request.getId()); SingularityRequest newRequest = validator.checkSingularityRequest( request, maybeOldRequest, deployHolder.getActiveDeploy(), deployHolder.getPendingDeploy()); checkConflict( maybeOldRequest.isPresent() || !requestManager.cleanupRequestExists(request.getId()), "Request %s is currently cleaning. Try again after a few moments", request.getId()); final long now = System.currentTimeMillis(); requestManager.activate( newRequest, maybeOldRequest.isPresent() ? RequestHistoryType.UPDATED : RequestHistoryType.CREATED, now, user); checkReschedule(newRequest, maybeOldRequest, now); return fillEntireRequest(fetchRequestWithState(request.getId())); }
@POST @Path("/request/{requestId}/exit-cooldown") public SingularityRequestParent exitCooldown( @PathParam("requestId") String requestId, @QueryParam("user") Optional<String> user) { final SingularityRequestWithState requestWithState = fetchRequestWithState(requestId); checkConflict( requestWithState.getState() == RequestState.SYSTEM_COOLDOWN, "Request %s is not in SYSTEM_COOLDOWN state, it is in %s", requestId, requestWithState.getState()); final Optional<String> maybeDeployId = deployManager.getInUseDeployId(requestId); final long now = System.currentTimeMillis(); requestManager.exitCooldown(requestWithState.getRequest(), now, user); if (maybeDeployId.isPresent() && !requestWithState.getRequest().isOneOff()) { requestManager.addToPendingQueue( new SingularityPendingRequest( requestId, maybeDeployId.get(), now, user, PendingType.IMMEDIATE, Collections.<String>emptyList())); } return fillEntireRequest(requestWithState); }
private String getAndCheckDeployId(String requestId) { Optional<String> maybeDeployId = deployManager.getInUseDeployId(requestId); checkConflict( maybeDeployId.isPresent(), "Can not schedule/bounce a request (%s) with no deploy", requestId); return maybeDeployId.get(); }
@POST @Path("/request/{requestId}/bounce") @ApiOperation( value = "Bounce a specific Singularity request. A bounce launches replacement task(s), and then kills the original task(s) if the replacement(s) are healthy.", response = SingularityRequestParent.class) public SingularityRequestParent bounce( @ApiParam("The request ID to bounce") @PathParam("requestId") String requestId, @ApiParam("Username of the person requesting the bounce") @QueryParam("user") Optional<String> user) { SingularityRequestWithState requestWithState = fetchRequestWithState(requestId); checkBadRequest( requestWithState.getRequest().isLongRunning(), "Can not bounce a %s request (%s)", requestWithState.getRequest().getRequestType(), requestWithState); checkConflict( requestWithState.getState() != RequestState.PAUSED, "Request %s is paused. Unable to bounce (it must be manually unpaused first)", requestWithState.getRequest().getId()); SingularityCreateResult createResult = requestManager.createCleanupRequest( new SingularityRequestCleanup( user, RequestCleanupType.BOUNCE, System.currentTimeMillis(), Optional.<Boolean>absent(), requestId, Optional.of(getAndCheckDeployId(requestId)))); checkConflict( createResult != SingularityCreateResult.EXISTED, "%s is already bouncing", requestId); return fillEntireRequest(requestWithState); }
@PUT @Path("/request/{requestId}/instances") @ApiOperation( value = "Scale the number of instances up or down for a specific Request", response = SingularityRequest.class) @ApiResponses({ @ApiResponse(code = 400, message = "Posted object did not match Request ID"), @ApiResponse(code = 404, message = "No Request with that ID"), }) public SingularityRequest updateInstances( @ApiParam("The Request ID to scale") @PathParam("requestId") String requestId, @ApiParam("Username of the person requesting the scale") @QueryParam("user") Optional<String> user, @ApiParam("Object to hold number of instances to request") SingularityRequestInstances newInstances) { checkBadRequest( requestId != null && newInstances.getId() != null && requestId.equals(newInstances.getId()), "Update for request instance must pass a matching non-null requestId in path (%s) and object (%s)", requestId, newInstances.getId()); checkConflict( !requestManager.cleanupRequestExists(requestId), "Request %s is currently cleaning. Try again after a few moments", requestId); SingularityRequest oldRequest = fetchRequest(requestId); Optional<SingularityRequest> maybeOldRequest = Optional.of(oldRequest); SingularityRequestDeployHolder deployHolder = getDeployHolder(newInstances.getId()); SingularityRequest newRequest = oldRequest.toBuilder().setInstances(newInstances.getInstances()).build(); validator.checkSingularityRequest( newRequest, maybeOldRequest, deployHolder.getActiveDeploy(), deployHolder.getPendingDeploy()); final long now = System.currentTimeMillis(); requestManager.update(newRequest, now, user); checkReschedule(newRequest, maybeOldRequest, now); return newRequest; }
@POST @Path("/request/{requestId}/unpause") @ApiOperation( value = "Unpause a Singularity Request, scheduling new tasks immediately", response = SingularityRequestParent.class) @ApiResponses({ @ApiResponse(code = 409, message = "Request is not paused"), }) public SingularityRequestParent unpause( @ApiParam("The request ID to unpause") @PathParam("requestId") String requestId, @ApiParam("Username of the person requesting the unpause") @QueryParam("user") Optional<String> user) { SingularityRequestWithState requestWithState = fetchRequestWithState(requestId); checkConflict( requestWithState.getState() == RequestState.PAUSED, "Request %s is not in PAUSED state, it is in %s", requestId, requestWithState.getState()); mailer.sendRequestUnpausedMail(requestWithState.getRequest(), user); Optional<String> maybeDeployId = deployManager.getInUseDeployId(requestId); final long now = System.currentTimeMillis(); requestManager.unpause(requestWithState.getRequest(), now, user); if (maybeDeployId.isPresent() && !requestWithState.getRequest().isOneOff()) { requestManager.addToPendingQueue( new SingularityPendingRequest( requestId, maybeDeployId.get(), now, user, PendingType.UNPAUSED, Collections.<String>emptyList())); } return fillEntireRequest( new SingularityRequestWithState(requestWithState.getRequest(), RequestState.ACTIVE, now)); }