163 lines
7.2 KiB
Java
163 lines
7.2 KiB
Java
package eu.openaire.urls_controller.controllers;
|
|
|
|
import eu.openaire.urls_controller.models.WorkerInfo;
|
|
import eu.openaire.urls_controller.services.ShutdownService;
|
|
import eu.openaire.urls_controller.util.GenericUtils;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.http.HttpStatus;
|
|
import org.springframework.http.ResponseEntity;
|
|
import org.springframework.web.bind.annotation.PostMapping;
|
|
import org.springframework.web.bind.annotation.RequestMapping;
|
|
import org.springframework.web.bind.annotation.RequestParam;
|
|
import org.springframework.web.bind.annotation.RestController;
|
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
|
|
|
@RestController
|
|
@RequestMapping("")
|
|
public class ShutdownController {
|
|
|
|
private static final Logger logger = LoggerFactory.getLogger(ShutdownController.class);
|
|
|
|
@Autowired
|
|
ShutdownService shutdownService;
|
|
|
|
public static boolean shouldShutdownService = false;
|
|
public static boolean shouldShutdownAllWorkers = false;
|
|
|
|
|
|
@PostMapping("shutdownService")
|
|
public ResponseEntity<?> shutdownServiceGracefully(HttpServletRequest request)
|
|
{
|
|
String initMsg = "Received a \"shutdownService\" request ";
|
|
String remoteAddr = GenericUtils.getRequestorAddress(request);
|
|
initMsg += "from [" + remoteAddr + "]. ";
|
|
ResponseEntity<?> responseEntity = shutdownService.passSecurityChecks(remoteAddr, initMsg);
|
|
if ( responseEntity != null )
|
|
return responseEntity;
|
|
|
|
String endingMsg;
|
|
if ( shouldShutdownService ) {
|
|
endingMsg = "The controller has already received a \"shutdownService\" request (which was not canceled afterwards).";
|
|
logger.info(initMsg + endingMsg);
|
|
} else {
|
|
shouldShutdownService = true;
|
|
endingMsg = "The service will shutdown, after finishing current work.";
|
|
logger.info(initMsg + endingMsg);
|
|
|
|
shutdownService.postShutdownOrCancelRequestsToAllWorkers(false);
|
|
|
|
// That's it for now. The workers may take some hours to finish their work (including delivering the full-text files).
|
|
// A scheduler monitors the shutdown of the workers. Once all worker have shutdown, the Controller shuts down as well.
|
|
}
|
|
|
|
return ResponseEntity.ok().body(endingMsg + GenericUtils.endOfLine);
|
|
}
|
|
|
|
|
|
@PostMapping("cancelShutdownService")
|
|
public ResponseEntity<?> cancelShutdownServiceGracefully(HttpServletRequest request)
|
|
{
|
|
String initMsg = "Received a \"cancelShutdownService\" request ";
|
|
String remoteAddr = GenericUtils.getRequestorAddress(request);
|
|
initMsg += "from [" + remoteAddr + "]. ";
|
|
ResponseEntity<?> responseEntity = shutdownService.passSecurityChecks(remoteAddr, initMsg);
|
|
if ( responseEntity != null )
|
|
return responseEntity;
|
|
|
|
shouldShutdownService = false;
|
|
String endingMsg = "Any previous \"shutdownService\"-request is canceled.";
|
|
logger.info(initMsg + endingMsg);
|
|
|
|
// Cancel the shutdown of the workers, if we are able to catch up with them before they have already shutdown..
|
|
shutdownService.postShutdownOrCancelRequestsToAllWorkers(true);
|
|
|
|
return ResponseEntity.ok().body(endingMsg + GenericUtils.endOfLine);
|
|
}
|
|
|
|
|
|
// The "shutdownAllWorkers" and a "cancelShutdownAllWorkers" endpoints help when updating only the workers,
|
|
// while keeping the Controller running and accepting bulk-import requests.
|
|
|
|
@PostMapping("shutdownAllWorkers")
|
|
public ResponseEntity<?> shutdownAllWorkersGracefully(HttpServletRequest request)
|
|
{
|
|
String initMsg = "Received a \"shutdownAllWorkers\" request ";
|
|
String remoteAddr = GenericUtils.getRequestorAddress(request);
|
|
initMsg += "from [" + remoteAddr + "]. ";
|
|
ResponseEntity<?> responseEntity = shutdownService.passSecurityChecks(remoteAddr, initMsg);
|
|
if ( responseEntity != null )
|
|
return responseEntity;
|
|
|
|
String endingMsg;
|
|
if ( shouldShutdownAllWorkers ) {
|
|
endingMsg = "The controller has already received a \"shutdownAllWorkers\" request (which was not canceled afterwards).";
|
|
logger.info(initMsg + endingMsg);
|
|
} else {
|
|
shouldShutdownAllWorkers = true;
|
|
endingMsg = "All workers will shutdown, after finishing current work.";
|
|
logger.info(initMsg + endingMsg);
|
|
|
|
shutdownService.postShutdownOrCancelRequestsToAllWorkers(false);
|
|
|
|
// That's it for now. The workers may take some hours to finish their work (including delivering the full-text files).
|
|
// The service will continue to run and handle bulk-import requests.
|
|
// Once the workers are ready to work again, they can be started without any additional configuration.
|
|
}
|
|
|
|
return ResponseEntity.ok().body(endingMsg + GenericUtils.endOfLine);
|
|
}
|
|
|
|
|
|
@PostMapping("cancelShutdownAllWorkers")
|
|
public ResponseEntity<?> cancelShutdownAllWorkersGracefully(HttpServletRequest request)
|
|
{
|
|
String initMsg = "Received a \"cancelShutdownAllWorkers\" request ";
|
|
String remoteAddr = GenericUtils.getRequestorAddress(request);
|
|
initMsg += "from [" + remoteAddr + "]. ";
|
|
ResponseEntity<?> responseEntity = shutdownService.passSecurityChecks(remoteAddr, initMsg);
|
|
if ( responseEntity != null )
|
|
return responseEntity;
|
|
|
|
shouldShutdownAllWorkers = false;
|
|
String endingMsg = "Any previous \"shutdownAllWorkers\"-request is canceled.";
|
|
logger.info(initMsg + endingMsg);
|
|
|
|
// Cancel the shutdown of the workers, if we are able to catch up with them before they have already shutdown..
|
|
shutdownService.postShutdownOrCancelRequestsToAllWorkers(true);
|
|
|
|
return ResponseEntity.ok().body(endingMsg + GenericUtils.endOfLine);
|
|
}
|
|
|
|
|
|
@PostMapping("workerShutdownReport")
|
|
public ResponseEntity<?> workerShutdownReport(@RequestParam String workerId, HttpServletRequest request)
|
|
{
|
|
String remoteAddr = GenericUtils.getRequestorAddress(request);
|
|
String initMsg = "Received a \"workerShutdownReport\" from worker: \"" + workerId + "\" [IP: " + remoteAddr + "].";
|
|
WorkerInfo workerInfo = UrlsController.workersInfoMap.get(workerId);
|
|
if ( workerInfo == null ) {
|
|
String errorMsg = "The worker with id \"" + workerId + "\" has not participated in the PDF-Aggregation-Service!";
|
|
logger.warn(initMsg + GenericUtils.endOfLine + errorMsg);
|
|
return ResponseEntity.badRequest().body(errorMsg);
|
|
}
|
|
|
|
if ( ! remoteAddr.equals(workerInfo.getWorkerIP()) ) {
|
|
logger.error(initMsg + " The request came from an IP different from the one this worker was registered with: " + workerInfo.getWorkerIP());
|
|
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
|
|
}
|
|
|
|
logger.info(initMsg);
|
|
|
|
workerInfo.setHasShutdown(true); // This will update the map.
|
|
UrlsController.numOfActiveWorkers.decrementAndGet();
|
|
|
|
// Return "HTTP-OK" to this worker. If this was part of a shutdown-service request, then wait for the scheduler to check and shutdown the service.
|
|
return ResponseEntity.ok().build();
|
|
}
|
|
|
|
}
|