Search in sources :

Example 11 with ProgrammingExerciseParticipation

use of de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseParticipation in project Artemis by ls1intum.

the class ResultResource method getParticipationWithResults.

@Nullable
private ProgrammingExerciseParticipation getParticipationWithResults(String planKey) {
    // we have to support template, solution and student build plans here
    if (planKey.endsWith("-" + BuildPlanType.TEMPLATE.getName())) {
        return templateProgrammingExerciseParticipationRepository.findByBuildPlanIdWithResults(planKey).orElse(null);
    } else if (planKey.endsWith("-" + BuildPlanType.SOLUTION.getName())) {
        return solutionProgrammingExerciseParticipationRepository.findByBuildPlanIdWithResults(planKey).orElse(null);
    }
    List<ProgrammingExerciseStudentParticipation> participations = programmingExerciseStudentParticipationRepository.findByBuildPlanId(planKey);
    ProgrammingExerciseStudentParticipation participation = null;
    if (!participations.isEmpty()) {
        participation = participations.get(0);
        if (participations.size() > 1) {
            // in the rare case of multiple participations, take the latest one.
            for (ProgrammingExerciseStudentParticipation otherParticipation : participations) {
                if (otherParticipation.getInitializationDate().isAfter(participation.getInitializationDate())) {
                    participation = otherParticipation;
                }
            }
        }
    }
    return participation;
}
Also used : ProgrammingExerciseStudentParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation) Nullable(javax.annotation.Nullable)

Example 12 with ProgrammingExerciseParticipation

use of de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseParticipation in project ArTEMiS by ls1intum.

the class ResultResource method getParticipationWithResults.

@Nullable
private ProgrammingExerciseParticipation getParticipationWithResults(String planKey) {
    // we have to support template, solution and student build plans here
    if (planKey.endsWith("-" + BuildPlanType.TEMPLATE.getName())) {
        return templateProgrammingExerciseParticipationRepository.findByBuildPlanIdWithResults(planKey).orElse(null);
    } else if (planKey.endsWith("-" + BuildPlanType.SOLUTION.getName())) {
        return solutionProgrammingExerciseParticipationRepository.findByBuildPlanIdWithResults(planKey).orElse(null);
    }
    List<ProgrammingExerciseStudentParticipation> participations = programmingExerciseStudentParticipationRepository.findByBuildPlanId(planKey);
    ProgrammingExerciseStudentParticipation participation = null;
    if (!participations.isEmpty()) {
        participation = participations.get(0);
        if (participations.size() > 1) {
            // in the rare case of multiple participations, take the latest one.
            for (ProgrammingExerciseStudentParticipation otherParticipation : participations) {
                if (otherParticipation.getInitializationDate().isAfter(participation.getInitializationDate())) {
                    participation = otherParticipation;
                }
            }
        }
    }
    return participation;
}
Also used : ProgrammingExerciseStudentParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation) Nullable(javax.annotation.Nullable)

Example 13 with ProgrammingExerciseParticipation

use of de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseParticipation in project ArTEMiS by ls1intum.

the class ResultResource method getResultDetails.

/**
 * GET /participations/:participationId/results/:resultId/details : get the build result details from CI service for the "id" result.
 * This method is only invoked if the result actually includes details (e.g. feedback or build errors)
 *
 * @param participationId  the id of the participation to the result
 * @param resultId the id of the result to retrieve. If the participation related to the result is not a StudentParticipation or ProgrammingExerciseParticipation, the endpoint will return forbidden!
 * @return the ResponseEntity with status 200 (OK) and with body the result, status 404 (Not Found) if the result does not exist or 403 (forbidden) if the user does not have permissions to access the participation.
 */
@GetMapping("participations/{participationId}/results/{resultId}/details")
@PreAuthorize("hasRole('USER')")
public ResponseEntity<List<Feedback>> getResultDetails(@PathVariable Long participationId, @PathVariable Long resultId) {
    log.debug("REST request to get Result : {}", resultId);
    Result result = resultRepository.findByIdWithEagerFeedbacksElseThrow(resultId);
    Participation participation = result.getParticipation();
    if (!participation.getId().equals(participationId)) {
        throw new BadRequestAlertException("participationId of the path doesnt match the participationId of the participation corresponding to the result " + resultId + " !", "participationId", "400");
    }
    // The permission check depends on the participation type (normal participations vs. programming exercise participations).
    if (participation instanceof StudentParticipation) {
        if (!authCheckService.canAccessParticipation((StudentParticipation) participation)) {
            throw new AccessForbiddenException("participation", participationId);
        }
    } else if (participation instanceof ProgrammingExerciseParticipation) {
        if (!programmingExerciseParticipationService.canAccessParticipation((ProgrammingExerciseParticipation) participation)) {
            throw new AccessForbiddenException("participation", participationId);
        }
    } else {
        // This would be the case that a new participation type is introduced, without this the user would have access to it regardless of the permissions.
        throw new AccessForbiddenException("participation", participationId);
    }
    return new ResponseEntity<>(resultService.getFeedbacksForResult(result), HttpStatus.OK);
}
Also used : BadRequestAlertException(de.tum.in.www1.artemis.web.rest.errors.BadRequestAlertException) Participation(de.tum.in.www1.artemis.domain.participation.Participation) ProgrammingExerciseStudentParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation) ProgrammingExerciseParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseParticipation) StudentParticipation(de.tum.in.www1.artemis.domain.participation.StudentParticipation) ResponseEntity(org.springframework.http.ResponseEntity) ProgrammingExerciseParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseParticipation) ProgrammingExerciseStudentParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation) StudentParticipation(de.tum.in.www1.artemis.domain.participation.StudentParticipation) AccessForbiddenException(de.tum.in.www1.artemis.web.rest.errors.AccessForbiddenException) PreAuthorize(org.springframework.security.access.prepost.PreAuthorize)

Example 14 with ProgrammingExerciseParticipation

use of de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseParticipation in project ArTEMiS by ls1intum.

the class BitbucketService method getPushDate.

@Override
public ZonedDateTime getPushDate(ProgrammingExerciseParticipation participation, String commitHash, Object eventObject) {
    // If the event object is supplied we try to retrieve the push date from there to save one call
    if (eventObject != null) {
        JsonNode node = new ObjectMapper().convertValue(eventObject, JsonNode.class);
        String dateString = node.get("date").asText(null);
        if (dateString != null) {
            try {
                return ZonedDateTime.parse(dateString, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ"));
            } catch (DateTimeParseException e) {
            // If parsing fails for some reason we ignore the exception and try to get it via the direct request.
            }
        }
    }
    boolean isLastPage = false;
    final int perPage = 40;
    int start = 0;
    while (!isLastPage) {
        try {
            UriComponents builder = UriComponentsBuilder.fromUri(bitbucketServerUrl.toURI()).pathSegment("rest", "api", "latest", "projects", participation.getProgrammingExercise().getProjectKey(), "repos", urlService.getRepositorySlugFromRepositoryUrl(participation.getVcsRepositoryUrl()), "ref-change-activities").queryParam("start", start).queryParam("limit", perPage).queryParam("ref", "refs/heads/" + defaultBranch).build();
            final var response = restTemplate.exchange(builder.toUri(), HttpMethod.GET, null, BitbucketChangeActivitiesDTO.class);
            if (response.getStatusCode() != HttpStatus.OK || response.getBody() == null) {
                throw new BitbucketException("Unable to get push date for participation " + participation.getId() + "\n" + response.getBody());
            }
            final var changeActivities = response.getBody().getValues();
            final var activityOfPush = changeActivities.stream().filter(activity -> commitHash.equals(activity.getRefChange().getToHash())).findFirst();
            if (activityOfPush.isPresent()) {
                return Instant.ofEpochMilli(activityOfPush.get().getCreatedDate()).atZone(ZoneOffset.UTC);
            }
            isLastPage = response.getBody().getLastPage();
            start += perPage;
        } catch (URISyntaxException e) {
            throw new BitbucketException("Unable to get push date for participation " + participation.getId(), e);
        }
    }
    throw new BitbucketException("Unable to find push date result for participation " + participation.getId() + " and hash " + commitHash);
}
Also used : UriComponentsBuilder(org.springframework.web.util.UriComponentsBuilder) org.springframework.http(org.springframework.http) PasswordService(de.tum.in.www1.artemis.service.user.PasswordService) de.tum.in.www1.artemis.repository(de.tum.in.www1.artemis.repository) URL(java.net.URL) ParameterizedTypeReference(org.springframework.core.ParameterizedTypeReference) URISyntaxException(java.net.URISyntaxException) ZonedDateTime(java.time.ZonedDateTime) LoggerFactory(org.slf4j.LoggerFactory) BitbucketException(de.tum.in.www1.artemis.exception.BitbucketException) GitService(de.tum.in.www1.artemis.service.connectors.GitService) HashMap(java.util.HashMap) VersionControlRepositoryPermission(de.tum.in.www1.artemis.service.connectors.VersionControlRepositoryPermission) Value(org.springframework.beans.factory.annotation.Value) VersionControlException(de.tum.in.www1.artemis.exception.VersionControlException) ProgrammingExerciseStudentParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation) AbstractVersionControlService(de.tum.in.www1.artemis.service.connectors.AbstractVersionControlService) Service(org.springframework.stereotype.Service) ProgrammingExerciseParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseParticipation) Map(java.util.Map) Qualifier(org.springframework.beans.factory.annotation.Qualifier) JsonNode(com.fasterxml.jackson.databind.JsonNode) URI(java.net.URI) ZoneOffset(java.time.ZoneOffset) Nullable(javax.annotation.Nullable) RestTemplate(org.springframework.web.client.RestTemplate) Logger(org.slf4j.Logger) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) de.tum.in.www1.artemis.service.connectors.bitbucket.dto(de.tum.in.www1.artemis.service.connectors.bitbucket.dto) Set(java.util.Set) Instant(java.time.Instant) NotNull(javax.validation.constraints.NotNull) ApplicationContext(org.springframework.context.ApplicationContext) Profile(org.springframework.context.annotation.Profile) HttpClientErrorException(org.springframework.web.client.HttpClientErrorException) DateTimeParseException(java.time.format.DateTimeParseException) List(java.util.List) de.tum.in.www1.artemis.domain(de.tum.in.www1.artemis.domain) ConnectorHealth(de.tum.in.www1.artemis.service.connectors.ConnectorHealth) DateTimeFormatter(java.time.format.DateTimeFormatter) UrlService(de.tum.in.www1.artemis.service.UrlService) StringUtils(org.springframework.util.StringUtils) UriComponents(org.springframework.web.util.UriComponents) DateTimeParseException(java.time.format.DateTimeParseException) UriComponents(org.springframework.web.util.UriComponents) BitbucketException(de.tum.in.www1.artemis.exception.BitbucketException) JsonNode(com.fasterxml.jackson.databind.JsonNode) URISyntaxException(java.net.URISyntaxException) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper)

Example 15 with ProgrammingExerciseParticipation

use of de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseParticipation in project ArTEMiS by ls1intum.

the class ProgrammingSubmissionIntegrationTest method triggerFailedBuildEmptyLatestPendingSubmission.

@Test
@WithMockUser(username = "student1", roles = "USER")
void triggerFailedBuildEmptyLatestPendingSubmission() throws Exception {
    bambooRequestMockProvider.enableMockingOfRequests();
    doReturn(COMMIT_HASH_OBJECT_ID).when(gitService).getLastCommitHash(any());
    String login = "student1";
    StudentParticipation participation = database.addStudentParticipationForProgrammingExercise(exercise, login);
    bambooRequestMockProvider.mockTriggerBuild((ProgrammingExerciseParticipation) participation);
    doReturn(Optional.empty()).when(programmingSubmissionService).getLatestPendingSubmission(anyLong(), anyBoolean());
    String url = "/api/programming-submissions/" + participation.getId() + "/trigger-failed-build";
    request.postWithoutLocation(url, null, HttpStatus.NOT_FOUND, new HttpHeaders());
}
Also used : HttpHeaders(org.springframework.http.HttpHeaders) ProgrammingExerciseStudentParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation) StudentParticipation(de.tum.in.www1.artemis.domain.participation.StudentParticipation) WithMockUser(org.springframework.security.test.context.support.WithMockUser) AbstractSpringIntegrationBambooBitbucketJiraTest(de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Aggregations

ProgrammingExerciseStudentParticipation (de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation)16 StudentParticipation (de.tum.in.www1.artemis.domain.participation.StudentParticipation)12 ProgrammingExerciseParticipation (de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseParticipation)10 Test (org.junit.jupiter.api.Test)10 WithMockUser (org.springframework.security.test.context.support.WithMockUser)10 AbstractSpringIntegrationBambooBitbucketJiraTest (de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest)8 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)8 HttpHeaders (org.springframework.http.HttpHeaders)8 ProgrammingSubmission (de.tum.in.www1.artemis.domain.ProgrammingSubmission)4 ProgrammingLanguage (de.tum.in.www1.artemis.domain.enumeration.ProgrammingLanguage)4 Participation (de.tum.in.www1.artemis.domain.participation.Participation)4 AccessForbiddenException (de.tum.in.www1.artemis.web.rest.errors.AccessForbiddenException)4 Nullable (javax.annotation.Nullable)4 NotNull (javax.validation.constraints.NotNull)4 ResponseEntity (org.springframework.http.ResponseEntity)4 PreAuthorize (org.springframework.security.access.prepost.PreAuthorize)4 JsonNode (com.fasterxml.jackson.databind.JsonNode)2 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)2 AbstractSpringIntegrationJenkinsGitlabTest (de.tum.in.www1.artemis.AbstractSpringIntegrationJenkinsGitlabTest)2 de.tum.in.www1.artemis.domain (de.tum.in.www1.artemis.domain)2