Skip to content

Commit

Permalink
release v1.3.0
Browse files Browse the repository at this point in the history
release v1.3.0
  • Loading branch information
onschan authored Oct 19, 2022
2 parents ea466fb + 21de034 commit 3fb989d
Show file tree
Hide file tree
Showing 143 changed files with 2,619 additions and 2,109 deletions.
32 changes: 5 additions & 27 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ sourceCompatibility = '11'

configurations {
asciidoctorExtensions
cucumberRuntime.extendsFrom(implementation, testImplementation, runtimeOnly)
}

repositories {
Expand All @@ -31,6 +30,9 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'

// websocket
implementation 'org.springframework.boot:spring-boot-starter-websocket'

// webflux
implementation 'org.springframework.boot:spring-boot-starter-webflux'

Expand Down Expand Up @@ -59,11 +61,6 @@ dependencies {
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
testImplementation 'org.springframework.restdocs:spring-restdocs-restassured'

//cucumber
testImplementation 'io.cucumber:cucumber-java:6.10.4'
testImplementation 'io.cucumber:cucumber-spring:6.10.4'
testImplementation 'io.cucumber:cucumber-junit-platform-engine:6.10.4'

// slack
implementation 'com.squareup.okhttp3:okhttp:4.10.0'
implementation 'com.slack.api:slack-app-backend:1.22.2'
Expand Down Expand Up @@ -109,8 +106,8 @@ task createDocument(type: Copy) {
task displaceDocument(type: Copy) {
dependsOn asciidoctor

from ("${asciidoctor.outputDir}")
into ("build/resources/main/static")
from("${asciidoctor.outputDir}")
into("build/resources/main/static")
}

bootJar {
Expand All @@ -125,25 +122,6 @@ jacocoTestReport {
}
}

task cucumber() {
dependsOn assemble, compileTestJava
doLast {
javaexec {
main = "io.cucumber.core.cli.Main"
classpath = configurations.cucumberRuntime + sourceSets.main.output + sourceSets.test.output
args = [
'--plugin', 'pretty',
'--plugin', 'html:build/reports/cucumber/cucumber-report.html',
'--glue', 'com.woowacourse.gongcheck',
'src/test/resources/features']
}
}
}

build {
dependsOn cucumber
}

sonarqube {
properties {
property "sonar.projectKey", "woowacourse-teams_2022-gong-check_AYKm4KvOS_3Pe1LEsoLu"
Expand Down
10 changes: 10 additions & 0 deletions backend/src/docs/asciidoc/hosts.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,17 @@
== 호스트

=== 호스트 비밀번호 변경

operation::hosts/spacePassword_update/success[snippets='http-request,http-response']

=== 입장코드 조회

operation::hosts/entranceCode[snippets='http-request,http-response,response-fields']

=== 호스트 프로필 조회

operation::hosts/profile[snippets='http-request,http-response,response-fields']

=== 호스트 프로필 변경

operation::hosts/profile/change[snippets='http-request,http-response,request-fields']
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.fasterxml.jackson.annotation.JsonProperty;
import com.woowacourse.gongcheck.core.domain.host.Host;
import com.woowacourse.gongcheck.core.domain.host.Nickname;
import lombok.Getter;

@Getter
Expand Down Expand Up @@ -31,6 +32,7 @@ public Host toHost() {
return Host.builder()
.githubId(getGithubId())
.imageUrl(imageUrl)
.nickname(new Nickname(loginName))
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ public void addInterceptors(final InterceptorRegistry registry) {
registry.addInterceptor(authenticationInterceptor)
.addPathPatterns("/api/**")
.excludePathPatterns("/api/hosts/*/enter")
.excludePathPatterns("/api/login");
.excludePathPatterns("/api/login")
.excludePathPatterns("/api/hosts/*/profile");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.woowacourse.gongcheck.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws-connect")
.setAllowedOriginPatterns("*");
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.woowacourse.gongcheck.core.application;

import com.woowacourse.gongcheck.auth.application.EntranceCodeProvider;
import com.woowacourse.gongcheck.core.application.response.HostProfileResponse;
import com.woowacourse.gongcheck.core.domain.host.Host;
import com.woowacourse.gongcheck.core.domain.host.HostRepository;
import com.woowacourse.gongcheck.core.domain.host.Nickname;
import com.woowacourse.gongcheck.core.domain.host.SpacePassword;
import com.woowacourse.gongcheck.core.presentation.request.HostProfileChangeRequest;
import com.woowacourse.gongcheck.core.presentation.request.SpacePasswordChangeRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -30,4 +33,16 @@ public String createEntranceCode(final Long hostId) {
Host host = hostRepository.getById(hostId);
return entranceCodeProvider.createEntranceCode(host.getId());
}

public HostProfileResponse findProfile(final String entranceCode) {
Long hostId = entranceCodeProvider.parseId(entranceCode);
Host host = hostRepository.getById(hostId);
return HostProfileResponse.from(host);
}

@Transactional
public void changeProfile(final Long hostId, final HostProfileChangeRequest request) {
Host host = hostRepository.getById(hostId);
host.changeNickname(new Nickname(request.getNickname()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,40 +47,40 @@ public JobService(final HostRepository hostRepository, final SpaceRepository spa
this.runningTaskRepository = runningTaskRepository;
}

public JobsResponse findJobs(final Long hostId, final Long spaceId) {
@Transactional
public Long createJob(final Long hostId, final Long spaceId, final JobCreateRequest request) {
Host host = hostRepository.getById(hostId);
Space space = spaceRepository.getByHostAndId(host, spaceId);
List<Job> jobs = jobRepository.findAllBySpaceHostAndSpace(host, space);
return JobsResponse.from(jobs);
return saveJob(request, space);
}

@Transactional
public Long createJob(final Long hostId, final Long spaceId, final JobCreateRequest request) {
public JobsResponse findJobs(final Long hostId, final Long spaceId) {
Host host = hostRepository.getById(hostId);
Space space = spaceRepository.getByHostAndId(host, spaceId);
return saveJob(request, space);
List<Job> jobs = jobRepository.findAllBySpaceHostAndSpace(host, space);
return JobsResponse.from(jobs);
}

@Transactional
public void removeJob(final Long hostId, final Long jobId) {
public void updateJob(final Long hostId, final Long jobId, final JobCreateRequest request) {
Host host = hostRepository.getById(hostId);
Job job = jobRepository.getBySpaceHostAndId(host, jobId);
List<Section> sections = sectionRepository.findAllByJob(job);
List<Task> tasks = taskRepository.findAllBySectionIn(sections);

deleteJob(jobId, sections, tasks);
job.changeName(new Name(request.getName()));
deleteSectionsAndTasks(sections, tasks);
createSectionsAndTasks(request.getSections(), job);
}

@Transactional
public void updateJob(final Long hostId, final Long jobId, final JobCreateRequest request) {
public void removeJob(final Long hostId, final Long jobId) {
Host host = hostRepository.getById(hostId);
Job job = jobRepository.getBySpaceHostAndId(host, jobId);
List<Section> sections = sectionRepository.findAllByJob(job);
List<Task> tasks = taskRepository.findAllBySectionIn(sections);

job.changeName(new Name(request.getName()));
deleteSectionsAndTasks(sections, tasks);
createSectionsAndTasks(request.getSections(), job);
deleteJob(jobId, sections, tasks);
}

public SlackUrlResponse findSlackUrl(final Long hostId, final Long jobId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import com.woowacourse.gongcheck.core.domain.submission.Submission;
import com.woowacourse.gongcheck.core.domain.submission.SubmissionRepository;
import com.woowacourse.gongcheck.core.domain.task.RunningTaskRepository;
import com.woowacourse.gongcheck.core.domain.task.RunningTaskSseEmitterContainer;
import com.woowacourse.gongcheck.core.domain.task.RunningTasks;
import com.woowacourse.gongcheck.core.domain.task.TaskRepository;
import com.woowacourse.gongcheck.core.domain.task.Tasks;
Expand All @@ -23,7 +22,6 @@
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

@Service
Expand All @@ -37,38 +35,28 @@ public class SubmissionService {
private final RunningTaskRepository runningTaskRepository;
private final SubmissionRepository submissionRepository;
private final NotificationService notificationService;
private final RunningTaskSseEmitterContainer runningTaskSseEmitterContainer;

public SubmissionService(final HostRepository hostRepository, final JobRepository jobRepository,
final SpaceRepository spaceRepository, final TaskRepository taskRepository,
final RunningTaskRepository runningTaskRepository,
final SubmissionRepository submissionRepository,
final NotificationService notificationService,
final RunningTaskSseEmitterContainer runningTaskSseEmitterContainer) {
final NotificationService notificationService) {
this.hostRepository = hostRepository;
this.jobRepository = jobRepository;
this.spaceRepository = spaceRepository;
this.taskRepository = taskRepository;
this.runningTaskRepository = runningTaskRepository;
this.submissionRepository = submissionRepository;
this.notificationService = notificationService;
this.runningTaskSseEmitterContainer = runningTaskSseEmitterContainer;
}

@Transactional(isolation = Isolation.SERIALIZABLE)
public void submitJobCompletion(final Long hostId, final Long jobId,
final SubmissionRequest request) {
Host host = hostRepository.getById(hostId);
Job job = jobRepository.getBySpaceHostAndId(host, jobId);
@Transactional
public void submitJobCompletion(Long jobId, SubmissionRequest request) {
Job job = jobRepository.getById(jobId);
saveSubmissionAndClearRunningTasks(request, job);
if (job.hasUrl()) {
sendNotification(request, job);
}
runningTaskSseEmitterContainer.publishSubmitEvent(jobId);
}

private void sendNotification(final SubmissionRequest request, final Job job) {
notificationService.sendMessage(SubmissionCreatedResponse.of(request.getAuthor(), job));
}

public SubmissionsResponse findPage(final Long hostId, final Long spaceId, final Pageable pageable) {
Expand All @@ -79,6 +67,10 @@ public SubmissionsResponse findPage(final Long hostId, final Long spaceId, final
return SubmissionsResponse.from(submissions);
}

private void sendNotification(final SubmissionRequest request, final Job job) {
notificationService.sendMessage(SubmissionCreatedResponse.of(request.getAuthor(), job));
}

private void saveSubmissionAndClearRunningTasks(final SubmissionRequest request, final Job job) {
Tasks tasks = new Tasks(taskRepository.findAllBySectionJob(job));
validateRunning(tasks);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,28 +61,53 @@ public void createNewRunningTasks(final Long hostId, final Long jobId) {
runningTaskRepository.saveAll(tasks.createRunningTasks());
}

@Transactional
public JobActiveResponse isJobActivated(final Long hostId, final Long jobId) {
Tasks tasks = findTasksByHostIdAndJobId(hostId, jobId);
return JobActiveResponse.from(existsAnyRunningTaskIn(tasks));
}

@Transactional
public SseEmitter connectRunningTasks(final Long hostId, final Long jobId) {
RunningTasksResponse runningTasks = findExistingRunningTasks(hostId, jobId);
return runningTaskSseEmitterContainer.createEmitterWithConnectionEvent(jobId, runningTasks);
}

@Transactional
public void flipRunningTask(Long taskId) {
Task task = taskRepository.getById(taskId);
RunningTask runningTask = task.getRunningTask();
if (runningTask == null) {
String message = String.format("현재 진행 중인 작업이 아닙니다. taskId = %d", taskId);
throw new BusinessException(message, ErrorCode.R002);
}
runningTask.flipCheckedStatus();
}

// runningTaskRepository.existsByTaskIdIn() 메서드, Lock 거는 조회 분리되면 readOnly transaction으로 변경해야함.
@Transactional
public RunningTasksResponse showRunningTasks(final Long jobId) {
Job job = jobRepository.getById(jobId);
Tasks tasks = new Tasks(taskRepository.findAllBySectionJob(job));

if (!existsAnyRunningTaskIn(tasks)) {
String message = String.format("현재 진행중인 RunningTask가 없습니다. jobId = %d", jobId);
throw new BusinessException(message, ErrorCode.R001);
}
return RunningTasksResponse.from(tasks);
}

@Transactional
public void flipRunningTask(final Long hostId, final Long taskId) {
Host host = hostRepository.getById(hostId);
Task task = taskRepository.getBySectionJobSpaceHostAndId(host, taskId);
RunningTask runningTask = runningTaskRepository.findByTaskId(task.getId())
.orElseThrow(() -> {
String message = String.format("현재 진행 중인 작업이 아닙니다. hostId = %d, taskId = %d", hostId, taskId);
throw new BusinessException(message, ErrorCode.R002);
});
RunningTask runningTask = task.getRunningTask();
if (runningTask == null) {
String message = String.format("현재 진행 중인 작업이 아닙니다. hostId = %d, taskId = %d", hostId, taskId);
throw new BusinessException(message, ErrorCode.R002);
}

runningTask.flipCheckedStatus();

Long jobId = task.getSection().getJob().getId();
RunningTasksResponse runningTasks = findExistingRunningTasks(hostId, jobId);

Expand All @@ -95,21 +120,16 @@ public TasksResponse findTasks(final Long hostId, final Long jobId) {
}

@Transactional
public void checkRunningTasksInSection(final Long hostId, final Long sectionId) {
Host host = hostRepository.getById(hostId);
Section section = sectionRepository.getByJobSpaceHostAndId(host, sectionId);
Long jobId = section.getJob().getId();
public void checkRunningTasksInSection(final Long sectionId) {
Section section = sectionRepository.getById(sectionId);
Tasks tasks = new Tasks(taskRepository.findAllBySection(section));

if (!existsAnyRunningTaskIn(tasks)) {
String message = String.format("현재 진행중인 RunningTask가 없습니다 hostId = %d, sectionId = %d", hostId, sectionId);
String message = String.format("현재 진행중인 RunningTask가 없습니다, sectionId = %d", sectionId);
throw new BusinessException(message, ErrorCode.R002);
}
RunningTasks runningTasks = tasks.getRunningTasks();
runningTasks.check();

Tasks allTasks = new Tasks(taskRepository.findAllBySectionJob(section.getJob()));
runningTaskSseEmitterContainer.publishFlipEvent(jobId, RunningTasksResponse.from(allTasks));
}

private RunningTasksResponse findExistingRunningTasks(final Long hostId, final Long jobId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class EntranceCodeResponse {
private EntranceCodeResponse() {
}

private EntranceCodeResponse(String entranceCode) {
private EntranceCodeResponse(final String entranceCode) {
this.entranceCode = entranceCode;
}

Expand Down
Loading

0 comments on commit 3fb989d

Please sign in to comment.