diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index af3410b8..2851af2a 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -15,8 +15,11 @@ jobs: uses: actions/setup-java@v1 with: java-version: 13.0.1 - - name: Build app & run tests - run: mvn test -q + - name: SonarCloud Static Analysis + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: mvn verify sonar:sonar -Dsonar.login=${{ secrets.SONAR_TOKEN }} -q - name: Find and Replace Commit uses: jacobtomlinson/gha-find-replace@0.1.1 with: diff --git a/pom.xml b/pom.xml index 51b69253..29e1d3ee 100644 --- a/pom.xml +++ b/pom.xml @@ -1,167 +1,193 @@ - 4.0.0 - com.redhat.labs - lodestar-backend - 1.0-SNAPSHOT - - 3.8.1 - 1.18.12 - true - 1.8 - 1.8 - UTF-8 - UTF-8 - 1.3.0.Final - quarkus-bom - io.quarkus - 1.3.0.Final - 2.22.1 - - - - - ${quarkus.platform.group-id} - ${quarkus.platform.artifact-id} - ${quarkus.platform.version} - pom - import - - - - - - io.quarkus - quarkus-resteasy - - - io.quarkus - quarkus-resteasy-jsonb - - - io.quarkus - quarkus-hibernate-validator - - - io.quarkus - quarkus-smallrye-jwt - - - io.quarkus - quarkus-smallrye-health - - - - io.quarkus - quarkus-smallrye-metrics - - - - io.quarkus - quarkus-smallrye-openapi - - - io.quarkus - quarkus-mongodb-panache - - - io.quarkus - quarkus-rest-client - - - io.quarkus - quarkus-scheduler - - - io.quarkus - quarkus-undertow-websockets - - - org.projectlombok - lombok - ${lombok.version} - provided - - - io.quarkus - quarkus-junit5 - test - - - io.rest-assured - rest-assured - test - - - de.flapdoodle.embed - de.flapdoodle.embed.mongo - test - - - - - - io.quarkus - quarkus-maven-plugin - ${quarkus-plugin.version} - - - - build - - - - - - maven-compiler-plugin - ${compiler-plugin.version} - - - maven-surefire-plugin - ${surefire-plugin.version} - - - org.jboss.logmanager.LogManager - - - - - - - - native - - - native - - - - - - maven-failsafe-plugin - ${surefire-plugin.version} - - - - integration-test - verify - - - - ${project.build.directory}/${project.build.finalName}-runner - - - - - - - - - native - - - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + 4.0.0 + com.redhat.labs + lodestar-backend + 1.0-SNAPSHOT + + 3.8.1 + 1.18.12 + true + 1.8 + 1.8 + UTF-8 + UTF-8 + 1.3.0.Final + quarkus-bom + io.quarkus + 1.3.0.Final + 2.22.1 + rht-labs_open-management-portal-backend + rht-labs + https://sonarcloud.io + target/jacoco.exec + 0.8.5 + + + + + ${quarkus.platform.group-id} + ${quarkus.platform.artifact-id} + ${quarkus.platform.version} + pom + import + + + + + + io.quarkus + quarkus-resteasy + + + io.quarkus + quarkus-resteasy-jsonb + + + io.quarkus + quarkus-hibernate-validator + + + io.quarkus + quarkus-smallrye-jwt + + + io.quarkus + quarkus-smallrye-health + + + + io.quarkus + quarkus-smallrye-metrics + + + + io.quarkus + quarkus-smallrye-openapi + + + io.quarkus + quarkus-mongodb-panache + + + io.quarkus + quarkus-rest-client + + + io.quarkus + quarkus-scheduler + + + io.quarkus + quarkus-undertow-websockets + + + org.projectlombok + lombok + ${lombok.version} + provided + + + io.quarkus + quarkus-junit5 + test + + + io.rest-assured + rest-assured + test + + + de.flapdoodle.embed + de.flapdoodle.embed.mongo + test + + + + + + io.quarkus + quarkus-maven-plugin + ${quarkus-plugin.version} + + + + build + + + + + + maven-compiler-plugin + ${compiler-plugin.version} + + + maven-surefire-plugin + ${surefire-plugin.version} + + + org.jboss.logmanager.LogManager + + + + + org.jacoco + jacoco-maven-plugin + ${jacoco.version} + + + jacoco-initialize + + prepare-agent + + test-compile + + + jacoco-site + verify + + report + + + + + + + + + native + + + native + + + + + + maven-failsafe-plugin + ${surefire-plugin.version} + + + + integration-test + verify + + + + ${project.build.directory}/${project.build.finalName}-runner + + + + + + + + + native + + + diff --git a/src/main/java/com/redhat/labs/omp/model/Commit.java b/src/main/java/com/redhat/labs/omp/model/Commit.java index ade7145c..69767136 100644 --- a/src/main/java/com/redhat/labs/omp/model/Commit.java +++ b/src/main/java/com/redhat/labs/omp/model/Commit.java @@ -1,7 +1,10 @@ package com.redhat.labs.omp.model; +import java.util.ArrayList; import java.util.List; +import javax.json.bind.annotation.JsonbProperty; + import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -12,12 +15,30 @@ @NoArgsConstructor @AllArgsConstructor public class Commit { + private String id; private String message; private String title; - private List added; - private List modified; - private List removed; + @Builder.Default private List added = new ArrayList<>(); + @Builder.Default private List modified = new ArrayList<>(); + @Builder.Default private List removed = new ArrayList<>(); + + @JsonbProperty("short_id") + private String shortId; + @JsonbProperty("author_name") + private String authorName; + @JsonbProperty("author_email") + private String authorEmail; + @JsonbProperty("committer_name") + private String commiterName; + @JsonbProperty("committer_email") + private String commiterEmail; + @JsonbProperty("authored_date") + private String authoredDate; + @JsonbProperty("committed_date") + private String commitDate; + @JsonbProperty("web_url") + private String url; public boolean didFileChange(String fileName) { diff --git a/src/main/java/com/redhat/labs/omp/model/Engagement.java b/src/main/java/com/redhat/labs/omp/model/Engagement.java index c9276c07..6306e1ed 100644 --- a/src/main/java/com/redhat/labs/omp/model/Engagement.java +++ b/src/main/java/com/redhat/labs/omp/model/Engagement.java @@ -73,6 +73,7 @@ public class Engagement extends PanacheMongoEntityBase { private List engagementUsers; private Status status; + private List commits; @JsonbTransient private FileAction action; diff --git a/src/main/java/com/redhat/labs/omp/resource/StatusResource.java b/src/main/java/com/redhat/labs/omp/resource/StatusResource.java index eb5a9933..ad340354 100644 --- a/src/main/java/com/redhat/labs/omp/resource/StatusResource.java +++ b/src/main/java/com/redhat/labs/omp/resource/StatusResource.java @@ -32,9 +32,6 @@ public class StatusResource { @ConfigProperty(name = "webhook.token") String token; - @ConfigProperty(name = "status.file") - String statusFile; - @Inject @RestClient OMPGitLabAPIService gitApi; @@ -55,14 +52,10 @@ public Response fetchConfigData(@HeaderParam(value = "x-gitlab-token") String gi LOGGER.error("Invalid token used"); return Response.status(Status.UNAUTHORIZED).build(); } - - LOGGER.debug("Status updated {}", hook.didFileChange(statusFile)); - - if(hook.didFileChange(statusFile)) { - LOGGER.debug("Hook for {}", hook.getProject().getPathWithNamespace()); - engagementService.updateStatus(hook.getCustomerName(), hook.getEngagementName()); - } + LOGGER.debug("Hook for {}", hook.getProject().getPathWithNamespace()); + engagementService.updateStatusAndCommits(hook); + return Response.ok(hook).build(); } diff --git a/src/main/java/com/redhat/labs/omp/rest/client/OMPGitLabAPIService.java b/src/main/java/com/redhat/labs/omp/rest/client/OMPGitLabAPIService.java index 0822e87f..a31adaab 100644 --- a/src/main/java/com/redhat/labs/omp/rest/client/OMPGitLabAPIService.java +++ b/src/main/java/com/redhat/labs/omp/rest/client/OMPGitLabAPIService.java @@ -12,6 +12,7 @@ import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; import org.jboss.resteasy.annotations.jaxrs.PathParam; +import com.redhat.labs.omp.model.Commit; import com.redhat.labs.omp.model.Engagement; import com.redhat.labs.omp.model.Status; import com.redhat.labs.omp.model.Version; @@ -34,6 +35,11 @@ Response createOrUpdateEngagement(Engagement engagement, @QueryParam("username") @Path("/api/v1/engagements/customer/{customer}/{engagement}/status") @Produces("application/json") Status getStatus(@PathParam("customer") String customer, @PathParam("engagement") String engagement); + + @GET + @Path("/api/v1/engagements/customer/{customer}/{engagement}/commits") + @Produces("application/json") + List getCommits(@PathParam("customer") String customer, @PathParam("engagement") String engagement); @GET @Path("/api/v1/config") diff --git a/src/main/java/com/redhat/labs/omp/service/EngagementService.java b/src/main/java/com/redhat/labs/omp/service/EngagementService.java index 787b3bb9..7f2e4d79 100644 --- a/src/main/java/com/redhat/labs/omp/service/EngagementService.java +++ b/src/main/java/com/redhat/labs/omp/service/EngagementService.java @@ -16,8 +16,10 @@ import com.redhat.labs.omp.exception.InvalidRequestException; import com.redhat.labs.omp.exception.ResourceAlreadyExistsException; import com.redhat.labs.omp.exception.ResourceNotFoundException; +import com.redhat.labs.omp.model.Commit; import com.redhat.labs.omp.model.Engagement; import com.redhat.labs.omp.model.FileAction; +import com.redhat.labs.omp.model.Hook; import com.redhat.labs.omp.model.Launch; import com.redhat.labs.omp.model.Status; import com.redhat.labs.omp.model.event.BackendEvent; @@ -40,6 +42,8 @@ public class EngagementService { String engagementFileBranch; @ConfigProperty(name = "engagement.file.commit.message", defaultValue = "updated by omp backend") String engagementFileCommitMessage; + @ConfigProperty(name = "status.file") + String statusFile; @Inject Jsonb jsonb; @@ -119,17 +123,22 @@ public Engagement update(String customerName, String projectName, Engagement eng } //Status comes from gitlab so it does not need to to be sync'd - public Engagement updateStatus(String customerName, String projectName) { - - Status status = gitApi.getStatus(customerName, projectName); - - Optional optional = get(customerName, projectName); + public Engagement updateStatusAndCommits(Hook hook) { + + Optional optional = get(hook.getCustomerName(), hook.getEngagementName()); if (!optional.isPresent()) { - throw new ResourceNotFoundException("no engagement found. use POST to create resource."); + throw new ResourceNotFoundException("no engagement found. unable to update from hook."); } Engagement persisted = optional.get(); - persisted.setStatus(status); + + if(hook.didFileChange(statusFile)) { + Status status = gitApi.getStatus(hook.getCustomerName(), hook.getEngagementName()); + persisted.setStatus(status); + } + + List commits = gitApi.getCommits(hook.getCustomerName(), hook.getEngagementName()); + persisted.setCommits(commits); // update in db repository.update(persisted); @@ -180,7 +189,7 @@ public List getAll() { */ void deleteAll() { long count = repository.deleteAll(); - LOGGER.info("removed '" + count + "' engagements from the data store."); + LOGGER.info("removed '{}' engagements from the data store.", count); } /** @@ -268,7 +277,7 @@ public Engagement launch(Engagement engagement) { @ConsumeEvent(EventType.Constants.DB_REFRESH_ADDRESS) void consumeDbRefreshRequestedEvent(BackendEvent event) { - if (!event.isForceUpdate() && getAll().size() > 0) { + if (!event.isForceUpdate() && getAll().isEmpty()) { LOGGER.debug( "engagements already exist in db and force is not set. doing nothing for db refresh request."); return; @@ -314,7 +323,7 @@ void sendEngagementsModifiedEvent() { List modifiedList = getModifiedEngagements(); - if (modifiedList.size() == 0) { + if (modifiedList.isEmpty()) { LOGGER.debug("no modified engagements to process"); return; } diff --git a/src/main/java/com/redhat/labs/omp/socket/SocketAuthenticationFilter.java b/src/main/java/com/redhat/labs/omp/socket/SocketAuthenticationFilter.java index 096dffce..8294855f 100644 --- a/src/main/java/com/redhat/labs/omp/socket/SocketAuthenticationFilter.java +++ b/src/main/java/com/redhat/labs/omp/socket/SocketAuthenticationFilter.java @@ -62,7 +62,7 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha } catch (ParseException e) { - LOGGER.debug("failed to parse token {} {}", token, e); + LOGGER.debug("failed to parse token {}", token, e); returnForbiddenError(servletResponse, "Invalid access token"); } diff --git a/src/test/java/com/redhat/labs/omp/model/CommitTest.java b/src/test/java/com/redhat/labs/omp/model/CommitTest.java new file mode 100644 index 00000000..fed6d8de --- /dev/null +++ b/src/test/java/com/redhat/labs/omp/model/CommitTest.java @@ -0,0 +1,38 @@ +package com.redhat.labs.omp.model; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class CommitTest { + private static List CHANGES = new ArrayList<>(); + + + @BeforeAll + static void setUp() { + CHANGES.add("status.json"); + } + + @Test + void testFileChanges() { + + Commit commit = Commit.builder().added(CHANGES).build(); + assertTrue(commit.didFileChange("status.json")); + + commit = Commit.builder().modified(CHANGES).build(); + assertTrue(commit.didFileChange("status.json")); + + commit = Commit.builder().removed(CHANGES).build(); + assertTrue(commit.didFileChange("status.json")); + + commit = Commit.builder().build(); + assertFalse(commit.didFileChange("status.json")); + + } + +} diff --git a/src/test/java/com/redhat/labs/omp/rest/client/MockOMPGitLabAPIService.java b/src/test/java/com/redhat/labs/omp/rest/client/MockOMPGitLabAPIService.java index 9b21d5f6..cb194a0e 100644 --- a/src/test/java/com/redhat/labs/omp/rest/client/MockOMPGitLabAPIService.java +++ b/src/test/java/com/redhat/labs/omp/rest/client/MockOMPGitLabAPIService.java @@ -9,6 +9,7 @@ import org.eclipse.microprofile.rest.client.inject.RestClient; +import com.redhat.labs.omp.model.Commit; import com.redhat.labs.omp.model.Engagement; import com.redhat.labs.omp.model.Status; import com.redhat.labs.omp.model.Version; @@ -95,4 +96,9 @@ public Status getStatus(String customer, String engagement) { return null; } + @Override + public List getCommits(String customer, String engagement) { + return null; + } + } diff --git a/src/test/java/com/redhat/labs/omp/service/EngagementServiceTest.java b/src/test/java/com/redhat/labs/omp/service/EngagementServiceTest.java new file mode 100644 index 00000000..74a0bdc4 --- /dev/null +++ b/src/test/java/com/redhat/labs/omp/service/EngagementServiceTest.java @@ -0,0 +1,57 @@ +package com.redhat.labs.omp.service; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import javax.inject.Inject; + +import org.junit.jupiter.api.Test; + +import com.redhat.labs.omp.exception.InvalidRequestException; +import com.redhat.labs.omp.exception.ResourceNotFoundException; +import com.redhat.labs.omp.model.Engagement; +import com.redhat.labs.omp.model.GitlabProject; +import com.redhat.labs.omp.model.Hook; +import com.redhat.labs.omp.model.Launch; +import com.redhat.labs.omp.model.event.BackendEvent; +import com.redhat.labs.utils.EmbeddedMongoTest; + +import io.quarkus.test.junit.QuarkusTest; + +@EmbeddedMongoTest +@QuarkusTest +class EngagementServiceTest { + + + @Inject + EngagementService engagementService; + + @Test void testUpdateStatusInvalidProject() { + Hook hook = Hook.builder().project(GitlabProject.builder().pathWithNamespace("/nope/nada/iac").build()).build(); + + Exception ex = assertThrows(ResourceNotFoundException.class, ()-> { + engagementService.updateStatusAndCommits(hook); + }); + + assertEquals("no engagement found. unable to update from hook.", ex.getMessage()); + } + + @Test void testAlreadyLaunched() { + Engagement engagement = Engagement.builder().launch(Launch.builder().build()).build(); + + Exception ex = assertThrows(InvalidRequestException.class, ()-> { + engagementService.launch(engagement); + }); + + assertEquals("engagement has already been launched.", ex.getMessage()); + } + + @Test void consumeDbRefreshRequestedEventEmpty() { + BackendEvent be = BackendEvent.builder().forceUpdate(false).build(); + + engagementService.consumeDbRefreshRequestedEvent(be); + + assertFalse(be.isForceUpdate()); + } +}