Skip to content

Commit

Permalink
Merge branch 'develop' into chore/architecture-style
Browse files Browse the repository at this point in the history
  • Loading branch information
Strohgelaender authored Sep 12, 2023
2 parents 179202f + 1ddc676 commit de02727
Show file tree
Hide file tree
Showing 35 changed files with 170 additions and 250 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ private static String getClasspathPublicSubPathLocation(String... subPaths) {
*/
private static String getFileSystemPublicSubPathResourceLocation(String... subPaths) {
var userDir = System.getProperty("user.dir");
var morePaths = Stream.concat(Stream.of("public"), Arrays.stream(subPaths)).toList().toArray(new String[1 + subPaths.length]);
var morePaths = Stream.concat(Stream.of("public"), Arrays.stream(subPaths)).toArray(String[]::new);
return "file:" + Path.of(userDir, morePaths) + "/";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public Optional<Path> exportCourse(Course course, String outputDir, List<String>

Optional<Path> exportedCourse = zipExportedExercises(outputDir, exportErrors, notificationTopic, tmpCourseDir, exportedFiles);

log.info("Successfully exported course {}. The zip file is located at: {}", course.getId(), exportedCourse);
log.info("Successfully exported course {}. The zip file is located at: {}", course.getId(), exportedCourse.orElse(null));
return exportedCourse;
}

Expand Down Expand Up @@ -178,7 +178,7 @@ public Optional<Path> exportExam(Exam exam, String outputDir, List<String> expor

Optional<Path> exportedExamPath = zipExportedExercises(outputDir, exportErrors, notificationTopic, tempExamsDir, exportedExercises);

log.info("Successfully exported exam {}. The zip file is located at: {}", exam.getId(), exportedExamPath);
log.info("Successfully exported exam {}. The zip file is located at: {}", exam.getId(), exportedExamPath.orElse(null));
return exportedExamPath;
}

Expand Down Expand Up @@ -356,7 +356,7 @@ private List<Path> exportExercises(String notificationTopic, Set<Exercise> exerc

// Export exercises
for (var exercise : sortedExercises) {
log.info("Exporting exercise {} with id {} ", exercise.getTitle(), exercise.getId());
log.info("Exporting {} exercise {} with id {} ", exercise.getType(), exercise.getTitle(), exercise.getId());

// Notify the user after the progress
currentProgress++;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,7 @@ public StatsForDashboardDTO getStatsForDashboardDTO(Course course) {
*/
@Async
public void archiveCourse(Course course) {
long start = System.nanoTime();
SecurityUtils.setAuthorizationObject();

// Archiving a course is only possible after the course is over
Expand All @@ -746,7 +747,7 @@ public void archiveCourse(Course course) {
}

// This contains possible errors encountered during the archive process
ArrayList<String> exportErrors = new ArrayList<>();
List<String> exportErrors = Collections.synchronizedList(new ArrayList<>());

groupNotificationService.notifyInstructorGroupAboutCourseArchiveState(course, NotificationType.COURSE_ARCHIVE_STARTED, exportErrors);

Expand Down Expand Up @@ -775,6 +776,7 @@ public void archiveCourse(Course course) {
}

groupNotificationService.notifyInstructorGroupAboutCourseArchiveState(course, NotificationType.COURSE_ARCHIVE_FINISHED, exportErrors);
log.info("archive course took {}", TimeLogUtil.formatDurationFrom(start));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import de.tum.in.www1.artemis.repository.plagiarism.PlagiarismResultRepository;
import de.tum.in.www1.artemis.service.metis.conversation.ChannelService;
import de.tum.in.www1.artemis.service.programming.ProgrammingExerciseService;
import de.tum.in.www1.artemis.service.util.TimeLogUtil;

/**
* Service Implementation for managing Exercise.
Expand Down Expand Up @@ -123,8 +124,10 @@ public void delete(long exerciseId, boolean deleteStudentReposBuildPlans, boolea
var exercise = exerciseRepository.findByIdWithCompetenciesElseThrow(exerciseId);
log.info("Request to delete {} with id {}", exercise.getClass().getSimpleName(), exerciseId);

long start = System.nanoTime();
Channel exreciseChannel = channelRepository.findChannelByExerciseId(exerciseId);
channelService.deleteChannel(exreciseChannel);
log.info("Deleting the channel took {}", TimeLogUtil.formatDurationFrom(start));

if (exercise instanceof ModelingExercise modelingExercise) {
log.info("Deleting clusters, elements and cancel scheduled operations of exercise {}", exercise.getId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand Down Expand Up @@ -132,16 +130,16 @@ public void createProgrammingExerciseExport(ProgrammingExercise programmingExerc
repositoryExportOptions.setCombineStudentCommits(false);
repositoryExportOptions.setFilterLateSubmissionsIndividualDueDate(false);
repositoryExportOptions.setExcludePracticeSubmissions(false);
repositoryExportOptions.setNormalizeCodeStyle(true);
repositoryExportOptions.setNormalizeCodeStyle(false);
var listOfProgrammingExerciseParticipations = programmingExercise.getStudentParticipations().stream()
.filter(studentParticipation -> studentParticipation instanceof ProgrammingExerciseStudentParticipation)
.map(studentParticipation -> (ProgrammingExerciseStudentParticipation) studentParticipation).toList();
List<String> exportRepoErrors = new ArrayList<>();

// we use this directory only to clone the repository and don't do this in our current directory because the current directory is part of the final data export
// --> we can delete it after use
var tempRepoWorkingDir = fileService.getTemporaryUniquePath(repoClonePath, 10);
programmingExerciseExportService.exportStudentRepositories(programmingExercise, listOfProgrammingExerciseParticipations, repositoryExportOptions, tempRepoWorkingDir,
exerciseDir, exportRepoErrors);
exerciseDir, Collections.synchronizedList(new ArrayList<>()));

createPlagiarismCaseInfoExport(programmingExercise, exerciseDir, userId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import de.tum.in.www1.artemis.domain.enumeration.ExerciseType;
import de.tum.in.www1.artemis.domain.exam.Exam;
import de.tum.in.www1.artemis.domain.exam.ExerciseGroup;
import de.tum.in.www1.artemis.domain.metis.conversation.Channel;
import de.tum.in.www1.artemis.domain.modeling.ModelingExercise;
import de.tum.in.www1.artemis.domain.quiz.QuizExercise;
import de.tum.in.www1.artemis.repository.*;
Expand Down Expand Up @@ -102,9 +101,7 @@ public Exam importExamWithExercises(Exam examToCopy, long targetCourseId) {

// 2nd: Copy the exercise groups to the exam
copyExerciseGroupsWithExercisesToExam(exerciseGroupsToCopy, examCopied);
Channel createdChannel = channelService.createExamChannel(examCopied, Optional.ofNullable(examToCopy.getChannelName()));
channelService.registerTutorsAndInstructorsToChannel(examCopied.getCourse(), createdChannel);

channelService.createExamChannel(examCopied, Optional.ofNullable(examToCopy.getChannelName()));
return examRepository.findWithExerciseGroupsAndExercisesByIdOrElseThrow(examCopied.getId());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import de.tum.in.www1.artemis.security.Role;
import de.tum.in.www1.artemis.service.AuthorizationCheckService;
import de.tum.in.www1.artemis.service.ParticipationService;
import de.tum.in.www1.artemis.service.metis.conversation.ChannelService;
import de.tum.in.www1.artemis.service.user.UserService;
import de.tum.in.www1.artemis.web.rest.dto.ExamUserDTO;
import de.tum.in.www1.artemis.web.rest.errors.AccessForbiddenException;
Expand Down Expand Up @@ -55,11 +54,9 @@ public class ExamRegistrationService {

private final AuthorizationCheckService authorizationCheckService;

private final ChannelService channelService;

public ExamRegistrationService(ExamUserRepository examUserRepository, ExamRepository examRepository, UserService userService, ParticipationService participationService,
UserRepository userRepository, AuditEventRepository auditEventRepository, CourseRepository courseRepository, StudentExamRepository studentExamRepository,
StudentParticipationRepository studentParticipationRepository, AuthorizationCheckService authorizationCheckService, ChannelService channelService) {
StudentParticipationRepository studentParticipationRepository, AuthorizationCheckService authorizationCheckService) {
this.examRepository = examRepository;
this.userService = userService;
this.userRepository = userRepository;
Expand All @@ -70,7 +67,6 @@ public ExamRegistrationService(ExamUserRepository examUserRepository, ExamReposi
this.studentParticipationRepository = studentParticipationRepository;
this.authorizationCheckService = authorizationCheckService;
this.examUserRepository = examUserRepository;
this.channelService = channelService;
}

/**
Expand Down Expand Up @@ -133,7 +129,6 @@ public List<ExamUserDTO> registerStudentsForExam(Long courseId, Long examId, Lis
}
}
examRepository.save(exam);
channelService.registerUsersToExamChannel(usersAddedToExam, exam);

try {
User currentUser = userRepository.getUserWithGroupsAndAuthorities();
Expand Down Expand Up @@ -202,8 +197,6 @@ public void registerStudentToExam(Course course, Exam exam, User student) {
registeredExamUser = examUserRepository.save(registeredExamUser);
exam.addExamUser(registeredExamUser);
examRepository.save(exam);

channelService.registerUsersToExamChannel(List.of(student.getLogin()), exam);
}
else {
log.warn("Student {} is already registered for the exam {}", student.getLogin(), exam.getId());
Expand Down Expand Up @@ -264,9 +257,6 @@ public void unregisterStudentFromExam(Exam exam, boolean deleteParticipationsAnd
examRepository.save(exam);
examUserRepository.delete(registeredExamUser);

// Remove the student from exam channel
channelService.deregisterUsersFromExamChannel(Set.of(student), exam.getId());

// The student exam might already be generated, then we need to delete it
Optional<StudentExam> optionalStudentExam = studentExamRepository.findWithExercisesByUserIdAndExamId(student.getId(), exam.getId());
optionalStudentExam.ifPresent(studentExam -> removeStudentExam(studentExam, deleteParticipationsAndSubmission));
Expand Down Expand Up @@ -306,10 +296,6 @@ public void unregisterAllStudentFromExam(Exam exam, boolean deleteParticipations
examRepository.save(exam);
examUserRepository.deleteAllById(registeredExamUsers.stream().map(ExamUser::getId).toList());

var students = userRepository.getStudents(exam.getCourse());

channelService.deregisterUsersFromExamChannel(students, exam.getId());

// remove all students exams
Set<StudentExam> studentExams = studentExamRepository.findAllWithoutTestRunsWithExercisesByExamId(exam.getId());
studentExams.forEach(studentExam -> removeStudentExam(studentExam, deleteParticipationsAndSubmission));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1187,15 +1187,16 @@ public StatsForDashboardDTO getStatsForExamAssessmentDashboard(Course course, Lo
*/
@Async
public void archiveExam(Exam exam) {
long start = System.nanoTime();
SecurityUtils.setAuthorizationObject();

// Archiving a course is only possible after the exam is over
// Archiving an exam is only possible after the exam is over
if (ZonedDateTime.now().isBefore(exam.getEndDate())) {
return;
}

// This contains possible errors encountered during the archive process
ArrayList<String> exportErrors = new ArrayList<>();
List<String> exportErrors = Collections.synchronizedList(new ArrayList<>());

groupNotificationService.notifyInstructorGroupAboutExamArchiveState(exam, NotificationType.EXAM_ARCHIVE_STARTED, exportErrors);

Expand Down Expand Up @@ -1224,6 +1225,7 @@ public void archiveExam(Exam exam) {
}

groupNotificationService.notifyInstructorGroupAboutExamArchiveState(exam, NotificationType.EXAM_ARCHIVE_FINISHED, exportErrors);
log.info("archive exam took {}", TimeLogUtil.formatDurationFrom(start));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@ public CompletableFuture<Integer> startExercises(Long examId) {
generatedParticipations.size(), startedAt, lock);
return null;
}))
.toList().toArray(new CompletableFuture<?>[studentExams.size()]);
.toArray(CompletableFuture[]::new);
return CompletableFuture.allOf(futures).thenApply((emtpy) -> {
threadPool.shutdown();
sendAndCacheExercisePreparationStatus(examId, finishedExamsCounter.get(), failedExamsCounter.get(), studentExams.size(), generatedParticipations.size(), startedAt,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import javax.validation.Valid;
import javax.validation.constraints.NotNull;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

Expand All @@ -25,7 +24,6 @@
import de.tum.in.www1.artemis.repository.UserRepository;
import de.tum.in.www1.artemis.repository.metis.ConversationParticipantRepository;
import de.tum.in.www1.artemis.repository.metis.conversation.ChannelRepository;
import de.tum.in.www1.artemis.security.SecurityUtils;
import de.tum.in.www1.artemis.service.metis.conversation.errors.ChannelNameDuplicateException;
import de.tum.in.www1.artemis.web.rest.errors.BadRequestAlertException;
import de.tum.in.www1.artemis.web.rest.metis.conversation.dtos.ChannelDTO;
Expand Down Expand Up @@ -158,52 +156,6 @@ public Channel createChannel(Course course, Channel channel, Optional<User> crea
return savedChannel;
}

/**
* Adds all course students to the given channel asynchronously
*
* @param course the course to add the students from
* @param channel the channel to add the students to
*/
@Async
public void registerCourseStudentsToChannelAsynchronously(Course course, Channel channel) {
if (channel == null) {
return;
}
SecurityUtils.setAuthorizationObject();
registerUsersToChannel(true, false, false, List.of(), course, channel);
}

/**
* Adds tutors and instructors to the given channel asynchronously
*
* @param course the course to add the tutors and instructors from
* @param channel the exam channel to add the users to
*/
@Async
public void registerTutorsAndInstructorsToChannel(Course course, Channel channel) {
if (channel == null || !course.getCourseInformationSharingConfiguration().isMessagingEnabled()) {
return;
}
SecurityUtils.setAuthorizationObject();
registerUsersToChannel(false, true, true, List.of(), course, channel);
}

/**
* Adds users to the channel of the given exam asynchronously
*
* @param users list of user logins to register for the exam channel
* @param exam exam to which channel the users should be added
*/
@Async
public void registerUsersToExamChannel(List<String> users, Exam exam) {
Channel channel = channelRepository.findChannelByExamId(exam.getId());
if (channel == null) {
return;
}
SecurityUtils.setAuthorizationObject();
registerUsersToChannel(false, false, false, users, exam.getCourse(), channel);
}

/**
* Register users to the newly created channel
*
Expand Down Expand Up @@ -293,7 +245,7 @@ public void unarchiveChannel(Long channelId) {
}

/**
* Creates a channel for a lecture and sets the channel name of the lecture accordingly. Also adds all course members asynchronously.
* Creates a channel for a lecture and sets the channel name of the lecture accordingly.
*
* @param lecture the lecture to create the channel for
* @param channelName the name of the channel
Expand All @@ -308,7 +260,7 @@ public Channel createLectureChannel(Lecture lecture, Optional<String> channelNam
}

/**
* Creates a channel for a course exercise and sets the channel name of the exercise accordingly. Also adds all course members asynchronously.
* Creates a channel for a course exercise and sets the channel name of the exercise accordingly.
*
* @param exercise the exercise to create the channel for
* @param channelName the name of the channel
Expand All @@ -324,7 +276,7 @@ public Channel createExerciseChannel(Exercise exercise, Optional<String> channel
}

/**
* Creates a channel for a real exam and sets the channel name of the exam accordingly. Also adds all course members asynchronously.
* Creates a channel for a real exam and sets the channel name of the exam accordingly.
*
* @param exam the exam to create the channel for
* @param channelName the name of the channel
Expand All @@ -336,7 +288,6 @@ public Channel createExamChannel(Exam exam, Optional<String> channelName) {
}
Channel channelToCreate = createDefaultChannel(channelName, "exam-", exam.getTitle());
channelToCreate.setIsPublic(false);
channelToCreate.setIsCourseWide(false);
channelToCreate.setExam(exam);
Channel createdChannel = createChannel(exam.getCourse(), channelToCreate, Optional.of(userRepository.getUserWithGroupsAndAuthorities()));
exam.setChannelName(createdChannel.getName());
Expand Down Expand Up @@ -391,21 +342,6 @@ public Channel updateExamChannel(Exam originalExam, Exam updatedExam) {
return updateChannelName(channel, updatedExam.getChannelName());
}

/**
* Removes users from an exam channel
*
* @param users users to remove from the channel
* @param examId id of the exam the channel belongs to
*/
public void deregisterUsersFromExamChannel(Set<User> users, Long examId) {
Channel channel = channelRepository.findChannelByExamId(examId);
if (channel == null) {
return;
}

conversationService.deregisterUsersFromAConversation(channel.getCourse(), users, channel);
}

private Channel updateChannelName(Channel channel, String newChannelName) {

// Update channel name if necessary
Expand Down
Loading

0 comments on commit de02727

Please sign in to comment.