From 40571ad2a213162a717fb836c44e26fea4ac3b9a Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Mon, 20 Jan 2025 17:45:21 +0100 Subject: [PATCH] Display a warning when data is stale --- pom.xml | 4 ++ .../java/io/quarkus/status/StatusService.java | 11 ++++- .../quarkus/status/github/GitHubService.java | 43 ++++++++++++++++++- .../java/io/quarkus/status/github/Issue.java | 1 + .../io/quarkus/status/model/StatusLine.java | 4 ++ .../templates/StatusResource/index.html | 4 +- 6 files changed, 64 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index f6df9f5..26bb4ed 100644 --- a/pom.xml +++ b/pom.xml @@ -73,6 +73,10 @@ quarkus-prettytime 2.0.10 + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + io.quarkus quarkus-junit5 diff --git a/src/main/java/io/quarkus/status/StatusService.java b/src/main/java/io/quarkus/status/StatusService.java index dc167a7..fb3c879 100644 --- a/src/main/java/io/quarkus/status/StatusService.java +++ b/src/main/java/io/quarkus/status/StatusService.java @@ -1,6 +1,7 @@ package io.quarkus.status; import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; import java.util.Arrays; import java.util.List; @@ -104,8 +105,16 @@ private StatusLine fromIssue(Issue issue) { StatusLine statusLine = new StatusLine(); statusLine.name = issue.title; statusLine.url = issue.url; - statusLine.statusCode = issue.isOpen() ? StatusCode.FAILURE : StatusCode.SUCCESS; + statusLine.statusCode = determineStatusCode(issue); statusLine.failureMessage = issue.getFailureMessage(); return statusLine; } + + private static StatusCode determineStatusCode(Issue issue) { + if (issue.updatedAt == null || ChronoUnit.DAYS.between(issue.updatedAt, LocalDateTime.now()) > 2) { + return StatusCode.WARNING; + } + + return issue.isOpen() ? StatusCode.FAILURE : StatusCode.SUCCESS; + } } diff --git a/src/main/java/io/quarkus/status/github/GitHubService.java b/src/main/java/io/quarkus/status/github/GitHubService.java index 7ead7de..ce39d37 100644 --- a/src/main/java/io/quarkus/status/github/GitHubService.java +++ b/src/main/java/io/quarkus/status/github/GitHubService.java @@ -1,7 +1,9 @@ package io.quarkus.status.github; import java.io.IOException; +import java.time.Instant; import java.time.LocalDateTime; +import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Collection; @@ -9,7 +11,13 @@ import java.util.Comparator; import java.util.List; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.json.JsonArray; @@ -26,11 +34,23 @@ import io.smallrye.graphql.client.GraphQLError; import io.smallrye.graphql.client.Response; import io.smallrye.graphql.client.dynamic.api.DynamicGraphQLClient; +import org.jboss.logging.Logger; @ApplicationScoped public class GitHubService { + private static final Logger LOG = Logger.getLogger(GitHubService.class); private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'"); + private static final String STATUS_MARKER = ""; + private static final Pattern STATUS_PATTERN = Pattern.compile(STATUS_MARKER + "\r?\n(.*?)\r?\n" + END_OF_MARKER, + Pattern.DOTALL); + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(new YAMLFactory()); + + static { + OBJECT_MAPPER.registerModule(new JavaTimeModule()); + OBJECT_MAPPER.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + } @Inject @GraphQLClient("github") @@ -167,11 +187,11 @@ private Issue extractIssue(JsonObject issueJson) { issue.id = issueJson.getString("id"); issue.title = issueJson.getString("title"); issue.number = issueJson.getInt("number"); - issue.author = jsonb.fromJson(issueJson.getJsonObject("author").toString(), User.class); issue.body = issueJson.getString("body"); issue.closedAt = issueJson.get("closedAt") != JsonValue.NULL ? LocalDateTime.parse(issueJson.getString("closedAt"), DATE_TIME_FORMATTER) : null; + issue.updatedAt = extractUpdatedAt(issue.body); issue.state = issueJson.getString("state"); issue.url = issueJson.getString("url"); @@ -235,4 +255,25 @@ private static class Templates { public static native TemplateInstance labelsStats(String owner, String repo, String label, int count, String cursor); } + private static LocalDateTime extractUpdatedAt(String body) { + if (body == null || body.isBlank()) { + return null; + } + + Matcher matcher = STATUS_PATTERN.matcher(body); + if (!matcher.find()) { + return null; + } + + try { + Status status = OBJECT_MAPPER.readValue(matcher.group(1), Status.class); + return LocalDateTime.ofInstant(status.updatedAt, ZoneId.systemDefault()); + } catch (Exception e) { + LOG.warn("Unable to extract Status from issue body", e); + return null; + } + } + + public record Status(Instant updatedAt, boolean failure, String repository, Long runId) { + } } \ No newline at end of file diff --git a/src/main/java/io/quarkus/status/github/Issue.java b/src/main/java/io/quarkus/status/github/Issue.java index 6275662..794fca8 100644 --- a/src/main/java/io/quarkus/status/github/Issue.java +++ b/src/main/java/io/quarkus/status/github/Issue.java @@ -18,6 +18,7 @@ public class Issue implements Comparable { public String url; public String state; public LocalDateTime closedAt; + public LocalDateTime updatedAt; public User author; diff --git a/src/main/java/io/quarkus/status/model/StatusLine.java b/src/main/java/io/quarkus/status/model/StatusLine.java index ae19529..3018db1 100644 --- a/src/main/java/io/quarkus/status/model/StatusLine.java +++ b/src/main/java/io/quarkus/status/model/StatusLine.java @@ -23,6 +23,10 @@ public boolean isFailure() { return statusCode == StatusCode.FAILURE; } + public boolean isWarning() { + return statusCode == StatusCode.WARNING; + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/src/main/resources/templates/StatusResource/index.html b/src/main/resources/templates/StatusResource/index.html index 3019ad2..014f32e 100644 --- a/src/main/resources/templates/StatusResource/index.html +++ b/src/main/resources/templates/StatusResource/index.html @@ -25,7 +25,7 @@ {#for line in section.value.lines} - +
{line.name} @@ -48,6 +48,8 @@ {#if line.failure} + {#else if line.warning} + {#else} {/if}