diff --git a/misc/requests/patch_job_trace.txt b/misc/requests/patch_job_trace.txt new file mode 100644 index 0000000..253cca3 --- /dev/null +++ b/misc/requests/patch_job_trace.txt @@ -0,0 +1,16 @@ +[PATCH /api/v4/jobs/0/trace HTTP/1.1 +Host: 172.17.0.1:8080 +User-Agent: gitlab-runner 13.3.1 (13-3-stable; go1.13.8; linux/amd64) +Content-Length: 363 +Content-Range: 0-362 +Content-Type: text/plain +Job-Token: +Accept-Encoding: gzip] + +Running with gitlab-runner 13.3.1 (738bbe5a) + on manualy registered gitlab runner f336d593 +Preparing the "shell" executor +Using Shell executor... +Preparing environment +Running on 94afd2dbc667... +ERROR: Job failed: panic: runtime error: slice bounds out of range [:8] with length 0 diff --git a/misc/requests/post_webhook_gitea.txt b/misc/requests/post_webhook_gitea.json similarity index 100% rename from misc/requests/post_webhook_gitea.txt rename to misc/requests/post_webhook_gitea.json diff --git a/src/main/java/tk/antoine_roux/wiki/ControllerHandlers.java b/src/main/java/tk/antoine_roux/wiki/ControllerHandlers.java index f38b267..125cf8f 100644 --- a/src/main/java/tk/antoine_roux/wiki/ControllerHandlers.java +++ b/src/main/java/tk/antoine_roux/wiki/ControllerHandlers.java @@ -9,19 +9,23 @@ 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.HookEvent; -import tk.antoine_roux.wiki.model.Runner; +import tk.antoine_roux.wiki.model.internal.HookEvent; +import tk.antoine_roux.wiki.model.internal.Job; +import tk.antoine_roux.wiki.model.internal.Runner; import tk.antoine_roux.wiki.model.request.AddRunner; import tk.antoine_roux.wiki.model.request.JobRequest; import tk.antoine_roux.wiki.model.request.TokenRunner; import tk.antoine_roux.wiki.model.response.RegisterRunnerResponse; +import tk.antoine_roux.wiki.service.JobManager; +import tk.antoine_roux.wiki.service.RunnerRegistrar; import tk.antoine_roux.wiki.utilitary.Boolean; import java.lang.invoke.MethodHandles; import java.util.Map; +import java.util.Optional; import java.util.TreeMap; -import static tk.antoine_roux.wiki.Constant.*; +import static tk.antoine_roux.wiki.utilitary.Constant.*; @RestController @ApiPrefix(API_PREFIX) @@ -30,10 +34,12 @@ public class ControllerHandlers { private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private final RunnerRegistrar runnerRegistrar; + private final JobManager jobManager; @Autowired - public ControllerHandlers(RunnerRegistrar runnerRegistrar) { + public ControllerHandlers(RunnerRegistrar runnerRegistrar, JobManager jobManager) { this.runnerRegistrar = runnerRegistrar; + this.jobManager = jobManager; } /** @@ -96,13 +102,33 @@ public class ControllerHandlers { @ApiVersion(API_VERSION) @PostMapping("/jobs/request") - public ResponseEntity jobRequest(@RequestBody JobRequest jobRequest) { - return ResponseEntity.ok().build(); + 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) { - return ResponseEntity.ok().build(); + ResponseEntity.BodyBuilder responseEntity; + Optional job = webHookData.toJob(); + + if (job.isPresent()) { + this.jobManager.stackJob(job.get()); + responseEntity = ResponseEntity.ok(); + } else { + responseEntity = ResponseEntity.unprocessableEntity(); + } + + return responseEntity.build(); } } diff --git a/src/main/java/tk/antoine_roux/wiki/configuration/Exception/InvalidObjectIdException.java b/src/main/java/tk/antoine_roux/wiki/configuration/Exception/InvalidObjectIdException.java new file mode 100644 index 0000000..2e6931e --- /dev/null +++ b/src/main/java/tk/antoine_roux/wiki/configuration/Exception/InvalidObjectIdException.java @@ -0,0 +1,9 @@ +package tk.antoine_roux.wiki.configuration.Exception; + +public class InvalidObjectIdException extends RuntimeException { + private static final long serialVersionUID = 6274838148439186894L; + + public InvalidObjectIdException(String commitStr) { + super("Try to convert invalid string (" + commitStr + ") to commit id"); + } +} diff --git a/src/main/java/tk/antoine_roux/wiki/configuration/WebConfiguration.java b/src/main/java/tk/antoine_roux/wiki/configuration/WebConfiguration.java index 448e432..903850b 100644 --- a/src/main/java/tk/antoine_roux/wiki/configuration/WebConfiguration.java +++ b/src/main/java/tk/antoine_roux/wiki/configuration/WebConfiguration.java @@ -3,7 +3,7 @@ package tk.antoine_roux.wiki.configuration; import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; -import tk.antoine_roux.wiki.Constant; +import tk.antoine_roux.wiki.utilitary.Constant; /** * spring web configuration diff --git a/src/main/java/tk/antoine_roux/wiki/model/HookEvent.java b/src/main/java/tk/antoine_roux/wiki/model/HookEvent.java deleted file mode 100644 index 5b16301..0000000 --- a/src/main/java/tk/antoine_roux/wiki/model/HookEvent.java +++ /dev/null @@ -1,20 +0,0 @@ -package tk.antoine_roux.wiki.model; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.List; - -public class HookEvent { - public String secret; - public String ref; - public String before; - public String after; - @JsonProperty("compare_url") - public String compareUrl; - public List commits; - @JsonProperty("head_commit") - public String headCommit; - public Repository repository; - public User pusher; - public User sender; -} diff --git a/src/main/java/tk/antoine_roux/wiki/model/UserReduced.java b/src/main/java/tk/antoine_roux/wiki/model/UserReduced.java deleted file mode 100644 index 9b54dec..0000000 --- a/src/main/java/tk/antoine_roux/wiki/model/UserReduced.java +++ /dev/null @@ -1,10 +0,0 @@ -package tk.antoine_roux.wiki.model; - -/** - * Reduced user information - */ -public class UserReduced { - public String name; - public String email; - public String username; -} diff --git a/src/main/java/tk/antoine_roux/wiki/model/Commit.java b/src/main/java/tk/antoine_roux/wiki/model/internal/Commit.java similarity index 92% rename from src/main/java/tk/antoine_roux/wiki/model/Commit.java rename to src/main/java/tk/antoine_roux/wiki/model/internal/Commit.java index 23fa838..7f775c1 100644 --- a/src/main/java/tk/antoine_roux/wiki/model/Commit.java +++ b/src/main/java/tk/antoine_roux/wiki/model/internal/Commit.java @@ -1,4 +1,4 @@ -package tk.antoine_roux.wiki.model; +package tk.antoine_roux.wiki.model.internal; import com.fasterxml.jackson.annotation.JsonFormat; diff --git a/src/main/java/tk/antoine_roux/wiki/model/internal/HookEvent.java b/src/main/java/tk/antoine_roux/wiki/model/internal/HookEvent.java new file mode 100644 index 0000000..48f4740 --- /dev/null +++ b/src/main/java/tk/antoine_roux/wiki/model/internal/HookEvent.java @@ -0,0 +1,56 @@ +package tk.antoine_roux.wiki.model.internal; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.time.ZonedDateTime; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; + +public class HookEvent { + public String secret; + public String ref; + public String before; + public String after; + @JsonProperty("compare_url") + public String compareUrl; + public List commits; + @JsonProperty("head_commit") + public String headCommit; + public Repository repository; + public User pusher; + public User sender; + + AtomicInteger idIncrementer = new AtomicInteger(); + + /** + * convert {@link HookEvent} to {@link Job} if possible + * else return and {@link Optional#empty()} + */ + public Optional toJob() { + Optional optJob; + + if (this.commits.isEmpty()) { + optJob = Optional.empty(); + } else { + // search for head commit or take first in event's list of commit + Commit commit = this.commits.stream().filter(co -> co.id.equals(this.headCommit)) + .findFirst().orElse(this.commits.get(0)); + + Job.Commit co = new Job.Commit( + commit.author.email, commit.author.name, commit.timestamp, + commit.id, commit.message, commit.id.substring(0, 8), commit.message + ); + + Job job = new Job( + null, co, null, ZonedDateTime.now(), null, + this.idIncrementer.getAndIncrement(), UUID.randomUUID().toString(), this.ref, + null, "root", null, JobStatus.CREATED, false, this.pusher.toReducedUser() + ); + optJob = Optional.of(job); + } + + return optJob; + } +} diff --git a/src/main/java/tk/antoine_roux/wiki/model/InternalTracker.java b/src/main/java/tk/antoine_roux/wiki/model/internal/InternalTracker.java similarity index 90% rename from src/main/java/tk/antoine_roux/wiki/model/InternalTracker.java rename to src/main/java/tk/antoine_roux/wiki/model/internal/InternalTracker.java index d395f52..552983f 100644 --- a/src/main/java/tk/antoine_roux/wiki/model/InternalTracker.java +++ b/src/main/java/tk/antoine_roux/wiki/model/internal/InternalTracker.java @@ -1,4 +1,4 @@ -package tk.antoine_roux.wiki.model; +package tk.antoine_roux.wiki.model.internal; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/tk/antoine_roux/wiki/model/internal/Job.java b/src/main/java/tk/antoine_roux/wiki/model/internal/Job.java new file mode 100644 index 0000000..7c2801b --- /dev/null +++ b/src/main/java/tk/antoine_roux/wiki/model/internal/Job.java @@ -0,0 +1,93 @@ +package tk.antoine_roux.wiki.model.internal; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.time.ZonedDateTime; + +// ID int `json:"id"` +// Token string `json:"token"` +// AllowGitFetch bool `json:"allow_git_fetch"` +// JobInfo JobInfo `json:"job_info"` +// GitInfo GitInfo `json:"git_info"` +// RunnerInfo RunnerInfo `json:"runner_info"` +// Variables JobVariables `json:"variables"` +// Steps Steps `json:"steps"` +// Image Image `json:"image"` +// Services Services `json:"services"` +// Artifacts Artifacts `json:"artifacts"` +// Cache Caches `json:"cache"` +// Credentials []Credentials `json:"credentials"` +// Dependencies Dependencies `json:"dependencies"` +// Features GitlabFeatures `json:"features"` +// Secrets Secrets `json:"secrets,omitempty"` + +public class Job { + @JsonProperty("artifacts_file") + public String artifactsFile; + public Commit commit; + public String coverage; + @JsonProperty("created_at") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssSSSXXX") + public ZonedDateTime createdAt; + @JsonProperty("finished_at") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssSSSXXX") + public ZonedDateTime finishedAt; + public Integer id; + public String name; + public String ref; + public Runner runner; + public String stage; + @JsonProperty("started_at") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssSSSXXX") + public ZonedDateTime startedAt; + public JobStatus status; + public boolean tag; + public UserReduced user; + + public Job( + String artifactsFile, Commit commit, String coverage, ZonedDateTime createdAt, ZonedDateTime finishedAt, + Integer id, String name, String ref, Runner runner, String stage, ZonedDateTime startedAt, JobStatus status, + boolean tag, UserReduced user + ) { + this.artifactsFile = artifactsFile; + this.commit = commit; + this.coverage = coverage; + this.createdAt = createdAt; + this.finishedAt = finishedAt; + this.id = id; + this.name = name; + this.ref = ref; + this.runner = runner; + this.stage = stage; + this.startedAt = startedAt; + this.status = status; + this.tag = tag; + this.user = user; + } + + public static class Commit { + @JsonProperty("author_email") + public String authorEmail; + @JsonProperty("author_name") + public String authorName; + @JsonProperty("created_at") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssSSSXXX") + public ZonedDateTime createdAt; + public String id; + public String message; + @JsonProperty("short_id") + public String shortId; + public String title; + + public Commit(String authorEmail, String authorName, ZonedDateTime createdAt, String id, String message, String shortId, String title) { + this.authorEmail = authorEmail; + this.authorName = authorName; + this.createdAt = createdAt; + this.id = id; + this.message = message; + this.shortId = shortId; + this.title = title; + } + } +} diff --git a/src/main/java/tk/antoine_roux/wiki/model/internal/JobStatus.java b/src/main/java/tk/antoine_roux/wiki/model/internal/JobStatus.java new file mode 100644 index 0000000..ca99ddd --- /dev/null +++ b/src/main/java/tk/antoine_roux/wiki/model/internal/JobStatus.java @@ -0,0 +1,12 @@ +package tk.antoine_roux.wiki.model.internal; + +/** + * This enum represent all state a job could take during + * his lifecycle + */ +public enum JobStatus { + CREATED, + STARTED, + STOPPED, + FINISHED +} diff --git a/src/main/java/tk/antoine_roux/wiki/Permission.java b/src/main/java/tk/antoine_roux/wiki/model/internal/Permission.java similarity index 76% rename from src/main/java/tk/antoine_roux/wiki/Permission.java rename to src/main/java/tk/antoine_roux/wiki/model/internal/Permission.java index 7db4a1a..1895119 100644 --- a/src/main/java/tk/antoine_roux/wiki/Permission.java +++ b/src/main/java/tk/antoine_roux/wiki/model/internal/Permission.java @@ -1,4 +1,4 @@ -package tk.antoine_roux.wiki; +package tk.antoine_roux.wiki.model.internal; /** * model about repository permission diff --git a/src/main/java/tk/antoine_roux/wiki/model/Repository.java b/src/main/java/tk/antoine_roux/wiki/model/internal/Repository.java similarity index 96% rename from src/main/java/tk/antoine_roux/wiki/model/Repository.java rename to src/main/java/tk/antoine_roux/wiki/model/internal/Repository.java index a846934..2a665f1 100644 --- a/src/main/java/tk/antoine_roux/wiki/model/Repository.java +++ b/src/main/java/tk/antoine_roux/wiki/model/internal/Repository.java @@ -1,7 +1,6 @@ -package tk.antoine_roux.wiki.model; +package tk.antoine_roux.wiki.model.internal; import com.fasterxml.jackson.annotation.JsonProperty; -import tk.antoine_roux.wiki.Permission; import java.time.ZonedDateTime; diff --git a/src/main/java/tk/antoine_roux/wiki/model/Runner.java b/src/main/java/tk/antoine_roux/wiki/model/internal/Runner.java similarity index 92% rename from src/main/java/tk/antoine_roux/wiki/model/Runner.java rename to src/main/java/tk/antoine_roux/wiki/model/internal/Runner.java index 49b67e9..5b576f0 100644 --- a/src/main/java/tk/antoine_roux/wiki/model/Runner.java +++ b/src/main/java/tk/antoine_roux/wiki/model/internal/Runner.java @@ -1,4 +1,4 @@ -package tk.antoine_roux.wiki.model; +package tk.antoine_roux.wiki.model.internal; import tk.antoine_roux.wiki.model.response.RegisterRunnerResponse; diff --git a/src/main/java/tk/antoine_roux/wiki/model/User.java b/src/main/java/tk/antoine_roux/wiki/model/internal/User.java similarity index 77% rename from src/main/java/tk/antoine_roux/wiki/model/User.java rename to src/main/java/tk/antoine_roux/wiki/model/internal/User.java index 386a59e..dc62cc4 100644 --- a/src/main/java/tk/antoine_roux/wiki/model/User.java +++ b/src/main/java/tk/antoine_roux/wiki/model/internal/User.java @@ -1,4 +1,4 @@ -package tk.antoine_roux.wiki.model; +package tk.antoine_roux.wiki.model.internal; import com.fasterxml.jackson.annotation.JsonProperty; @@ -22,4 +22,8 @@ public class User { @JsonProperty("last_login") public ZonedDateTime lastLogin; public ZonedDateTime created; + + public UserReduced toReducedUser() { + return new UserReduced(this.login, this.email, this.username); + } } diff --git a/src/main/java/tk/antoine_roux/wiki/model/internal/UserReduced.java b/src/main/java/tk/antoine_roux/wiki/model/internal/UserReduced.java new file mode 100644 index 0000000..e28788e --- /dev/null +++ b/src/main/java/tk/antoine_roux/wiki/model/internal/UserReduced.java @@ -0,0 +1,16 @@ +package tk.antoine_roux.wiki.model.internal; + +/** + * Reduced user information + */ +public class UserReduced { + public String name; + public String email; + public String username; + + public UserReduced(String name, String email, String username) { + this.name = name; + this.email = email; + this.username = username; + } +} diff --git a/src/main/java/tk/antoine_roux/wiki/model/request/AddRunner.java b/src/main/java/tk/antoine_roux/wiki/model/request/AddRunner.java index 4a17a76..b80c3a9 100644 --- a/src/main/java/tk/antoine_roux/wiki/model/request/AddRunner.java +++ b/src/main/java/tk/antoine_roux/wiki/model/request/AddRunner.java @@ -1,7 +1,6 @@ package tk.antoine_roux.wiki.model.request; import com.fasterxml.jackson.annotation.JsonProperty; -import tk.antoine_roux.wiki.model.RunnerInfo; import java.util.Arrays; import java.util.List; diff --git a/src/main/java/tk/antoine_roux/wiki/model/request/JobRequest.java b/src/main/java/tk/antoine_roux/wiki/model/request/JobRequest.java index 82662e9..d880009 100644 --- a/src/main/java/tk/antoine_roux/wiki/model/request/JobRequest.java +++ b/src/main/java/tk/antoine_roux/wiki/model/request/JobRequest.java @@ -1,7 +1,5 @@ package tk.antoine_roux.wiki.model.request; -import tk.antoine_roux.wiki.model.RunnerInfo; - /** * Job Request compose from {@link RunnerInfo} and token field */ diff --git a/src/main/java/tk/antoine_roux/wiki/model/RunnerInfo.java b/src/main/java/tk/antoine_roux/wiki/model/request/RunnerInfo.java similarity index 95% rename from src/main/java/tk/antoine_roux/wiki/model/RunnerInfo.java rename to src/main/java/tk/antoine_roux/wiki/model/request/RunnerInfo.java index ff3aab0..a4d1fe7 100644 --- a/src/main/java/tk/antoine_roux/wiki/model/RunnerInfo.java +++ b/src/main/java/tk/antoine_roux/wiki/model/request/RunnerInfo.java @@ -1,4 +1,4 @@ -package tk.antoine_roux.wiki.model; +package tk.antoine_roux.wiki.model.request; import java.util.Map; diff --git a/src/main/java/tk/antoine_roux/wiki/service/JobManager.java b/src/main/java/tk/antoine_roux/wiki/service/JobManager.java new file mode 100644 index 0000000..be19773 --- /dev/null +++ b/src/main/java/tk/antoine_roux/wiki/service/JobManager.java @@ -0,0 +1,27 @@ +package tk.antoine_roux.wiki.service; + +import org.springframework.stereotype.Service; +import tk.antoine_roux.wiki.model.internal.HookEvent; +import tk.antoine_roux.wiki.model.internal.Job; +import tk.antoine_roux.wiki.model.request.JobRequest; + +import java.util.Optional; +import java.util.concurrent.ConcurrentLinkedQueue; + +@Service +public class JobManager { + + /** + * concurrent list of {@link Job} fill by {@link tk.antoine_roux.wiki.ControllerHandlers#webhook(HookEvent)} + * and pop by {@link tk.antoine_roux.wiki.ControllerHandlers#jobRequest(JobRequest)} + */ + ConcurrentLinkedQueue jobQueue = new ConcurrentLinkedQueue<>(); + + public void stackJob(Job newJob) { + this.jobQueue.add(newJob); + } + + public Optional popJob(JobRequest jobRequest) { + return Optional.ofNullable(this.jobQueue.poll()); + } +} diff --git a/src/main/java/tk/antoine_roux/wiki/RunnerRegistrar.java b/src/main/java/tk/antoine_roux/wiki/service/RunnerRegistrar.java similarity index 93% rename from src/main/java/tk/antoine_roux/wiki/RunnerRegistrar.java rename to src/main/java/tk/antoine_roux/wiki/service/RunnerRegistrar.java index eed90a4..89684f8 100644 --- a/src/main/java/tk/antoine_roux/wiki/RunnerRegistrar.java +++ b/src/main/java/tk/antoine_roux/wiki/service/RunnerRegistrar.java @@ -1,7 +1,7 @@ -package tk.antoine_roux.wiki; +package tk.antoine_roux.wiki.service; import org.springframework.stereotype.Service; -import tk.antoine_roux.wiki.model.Runner; +import tk.antoine_roux.wiki.model.internal.Runner; import tk.antoine_roux.wiki.model.request.AddRunner; import tk.antoine_roux.wiki.model.request.TokenRunner; diff --git a/src/main/java/tk/antoine_roux/wiki/Constant.java b/src/main/java/tk/antoine_roux/wiki/utilitary/Constant.java similarity index 74% rename from src/main/java/tk/antoine_roux/wiki/Constant.java rename to src/main/java/tk/antoine_roux/wiki/utilitary/Constant.java index 815dcb8..42147c9 100644 --- a/src/main/java/tk/antoine_roux/wiki/Constant.java +++ b/src/main/java/tk/antoine_roux/wiki/utilitary/Constant.java @@ -1,4 +1,4 @@ -package tk.antoine_roux.wiki; +package tk.antoine_roux.wiki.utilitary; /** * Application level constant @@ -8,4 +8,6 @@ public final class Constant { public static final String API_NAME = "gitlab-runner-gateway"; public static final String API_VERSION = "4"; public static final String VERSION_PREFIX = "v"; + + public static final int OBJECT_ID_STRING_LENGTH = 40; }