package tk.antoine_roux.wiki; import org.eclipse.jgit.api.errors.GitAPIException; 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.*; import tk.antoine_roux.wiki.annotation.ApiPrefix; import tk.antoine_roux.wiki.annotation.ApiVersion; import tk.antoine_roux.wiki.configuration.Exception.DeleteRunnerException; import tk.antoine_roux.wiki.model.internal.GitlabCI; import tk.antoine_roux.wiki.model.internal.Runner; import tk.antoine_roux.wiki.model.request.AddRunner; import tk.antoine_roux.wiki.model.request.HookEvent; import tk.antoine_roux.wiki.model.request.JobRequest; import tk.antoine_roux.wiki.model.request.TokenRunner; import tk.antoine_roux.wiki.model.response.JobResponse; import tk.antoine_roux.wiki.model.response.RegisterRunnerResponse; import tk.antoine_roux.wiki.service.GitService; import tk.antoine_roux.wiki.service.JobManager; import tk.antoine_roux.wiki.service.RunnerRegistrar; import tk.antoine_roux.wiki.utilitary.Boolean; import java.io.IOException; import java.lang.invoke.MethodHandles; import java.util.Map; import java.util.Optional; import java.util.TreeMap; import static tk.antoine_roux.wiki.utilitary.Constant.*; @RestController @ApiPrefix(API_PREFIX) public class ControllerHandlers { private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private final RunnerRegistrar runnerRegistrar; private final JobManager jobManager; private final GitService gitService; @Autowired public ControllerHandlers(RunnerRegistrar runnerRegistrar, JobManager jobManager, GitService gitService) { this.runnerRegistrar = runnerRegistrar; this.jobManager = jobManager; this.gitService = gitService; } /** * hello test endpoint * * @return */ @ResponseBody @GetMapping("/info") public ResponseEntity> info() { return ResponseEntity.ok( // sort attribute by key name new TreeMap<>( Map.of( "api-version", VERSION_PREFIX + API_VERSION, "api-name", API_NAME ) ) ); } /** * add register new runners * * @param body * @return */ @ResponseBody @ApiVersion({API_VERSION}) @PostMapping("/runners") public ResponseEntity addRunner(@RequestBody AddRunner body) { logger.debug("Receive register runner request " + body); Runner createdRunner = this.runnerRegistrar.addRunner(body); RegisterRunnerResponse response = createdRunner.toRegisterResponse(); logger.debug("Response register runner " + response); return ResponseEntity.status(HttpStatus.CREATED).body(response); } @ApiVersion(API_VERSION) @DeleteMapping("/runners") public ResponseEntity deleteRunner(@RequestBody TokenRunner body) throws Exception { logger.debug("Receive delete runner request " + body); Boolean.trueOrElseThrow(this.runnerRegistrar.removeRunnerByRegistrationToken(body), DeleteRunnerException::new); logger.debug("Successfully delete runner "); return ResponseEntity.noContent().build(); } @ApiVersion(API_VERSION) @PostMapping("/runners/verify") public ResponseEntity runnerExist(@RequestBody TokenRunner body) { boolean isValid = this.runnerRegistrar.checkRunner(body); if (isValid) { return ResponseEntity.ok().build(); } else { return ResponseEntity.status(HttpStatus.FORBIDDEN).build(); } } @ApiVersion(API_VERSION) @PostMapping("/jobs/request") public ResponseEntity jobRequest(@RequestBody JobRequest jobRequest) { Optional currentJob = this.jobManager.popJob(jobRequest); return currentJob .map(job -> ResponseEntity.status(HttpStatus.CREATED).body(job)) .orElseGet(() -> ResponseEntity.noContent().build()); } @ApiVersion(API_VERSION) @PatchMapping("jobs/0/trace") public ResponseEntity receiveTrace(@RequestBody String traceContent) { logger.info(traceContent); return ResponseEntity.status(HttpStatus.CREATED).build(); } @ApiVersion(API_VERSION) @PostMapping("/webhook") public ResponseEntity webhook(@RequestBody HookEvent webHookData) throws IOException, GitAPIException { ResponseEntity.BodyBuilder responseEntity; Optional gitlabCI = this.gitService.getYMLGitlabCI(webHookData); if (gitlabCI.isPresent()) { JobResponse job = gitlabCI.get().buildJobResponse(); this.jobManager.stackJob(job); responseEntity = ResponseEntity.ok(); } else { responseEntity = ResponseEntity.unprocessableEntity(); } return responseEntity.build(); } }