Skip to content

Commit

Permalink
Merge pull request #154 from dnd-side-project/dev
Browse files Browse the repository at this point in the history
#147 ํ…Œ์ŠคํŠธ ๋ฐ ์ธ๋ฑ์Šค ์ƒ์„ฑ
  • Loading branch information
eun-seong authored Jun 10, 2024
2 parents 094ec5f + 2939496 commit 06b70ba
Show file tree
Hide file tree
Showing 23 changed files with 430 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ public enum ApplicationErrorType {
*/
NOT_FOUND_SURVEY(HttpStatus.NOT_FOUND, "์กด์žฌํ•˜์ง€ ์•Š๋Š” ์„ค๋ฌธ์ž…๋‹ˆ๋‹ค."),
QUESTION_ANSWER_COUNT_NOT_EQUAL(HttpStatus.INTERNAL_SERVER_ERROR, "๋ฌธํ•ญ๊ณผ ๋‹ต๋ณ€์˜ ๊ฐœ์ˆ˜๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."),

INVALID_BORROWING_LIMIT(HttpStatus.BAD_REQUEST, "๋นŒ๋ฆด ์ˆ˜ ์žˆ๋Š” ๋ˆ์€ 0 ์ด์ƒ 10์–ต ์ดํ•˜์ž…๋‹ˆ๋‹ค."),
INVALID_SURVEY_OWNER(HttpStatus.CONFLICT, "์„ค๋ฌธ ์†Œ์œ ์ž๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค."),

/**
* Filter Error Type
Expand All @@ -71,10 +71,10 @@ public enum ApplicationErrorType {


@Getter
private HttpStatus httpStatus;
private final HttpStatus httpStatus;

@Getter
private String message;
private final String message;

public int getStatusCode() {
return httpStatus.value();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.dnd.namuiwiki.common.exception;

import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;

import java.lang.reflect.Method;

@Slf4j
public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {

@Override
public void handleUncaughtException(Throwable ex, Method method, Object... params) {
log.error("AsyncException message={}, declaringClass={}, methodName={}", ex.getMessage(), method.getDeclaringClass(), method.getName(), ex);

for (Object param : params) {
log.error("Parameter value - {}, declaringClass={}, methodName={}", param, method.getDeclaringClass(), method.getName());
}
}

}
38 changes: 38 additions & 0 deletions src/main/java/com/dnd/namuiwiki/config/AsyncConfiguration.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.dnd.namuiwiki.config;

import com.dnd.namuiwiki.common.exception.AsyncExceptionHandler;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

@EnableAsync
@Configuration
public class AsyncConfiguration implements AsyncConfigurer {

@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(4);
executor.setQueueCapacity(50);
executor.setThreadNamePrefix("Async-");
executor.initialize();
return executor;
}

@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return asyncExceptionHandler();
}

@Bean
public AsyncExceptionHandler asyncExceptionHandler() {
return new AsyncExceptionHandler();
}

}
28 changes: 28 additions & 0 deletions src/main/java/com/dnd/namuiwiki/config/CacheConfiguration.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.dnd.namuiwiki.config;

import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.List;

@EnableCaching
@Configuration
public class CacheConfiguration {

@Bean
CacheManager cacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
List<Cache> caches = new ArrayList<>();
caches.add(new ConcurrentMapCache("questions"));
caches.add(new ConcurrentMapCache("question"));
cacheManager.setCaches(caches);
return cacheManager;
}

}
19 changes: 19 additions & 0 deletions src/main/java/com/dnd/namuiwiki/config/EventConfiguration.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.dnd.namuiwiki.config;

import com.dnd.namuiwiki.domain.statistic.StatisticsService;
import com.dnd.namuiwiki.domain.survey.SurveyEventHandler;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@RequiredArgsConstructor
public class EventConfiguration {
private final StatisticsService statisticsService;

@Bean
public SurveyEventHandler surveyEventHandler() {
return new SurveyEventHandler(statisticsService);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.dnd.namuiwiki.domain.dashboard;

import com.dnd.namuiwiki.domain.survey.model.entity.Answer;
import com.dnd.namuiwiki.domain.survey.type.Period;
import com.dnd.namuiwiki.domain.survey.type.Relation;
import com.dnd.namuiwiki.domain.user.entity.User;

import java.util.List;

public interface DashboardCustomRepository {
void updateDashboard(User owner, Period period, Relation relation, List<Answer> answers);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.dnd.namuiwiki.domain.dashboard;

import com.dnd.namuiwiki.domain.dashboard.model.entity.Dashboard;
import com.dnd.namuiwiki.domain.survey.model.entity.Answer;
import com.dnd.namuiwiki.domain.survey.type.Period;
import com.dnd.namuiwiki.domain.survey.type.Relation;
import com.dnd.namuiwiki.domain.user.entity.User;
import lombok.RequiredArgsConstructor;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.List;

@RequiredArgsConstructor
public class DashboardCustomRepositoryImpl implements DashboardCustomRepository {
private final MongoTemplate mongoTemplate;

@Override
public void updateDashboard(User owner, Period period, Relation relation, List<Answer> answers) {
Query query = Query.query(Criteria.where("user").is(owner)
.and("period").is(period)
.and("relation").is(relation));

Update update = new Update();

FindAndModifyOptions options = new FindAndModifyOptions().returnNew(true);

for (Answer answer : answers) {
update.inc(String.format("statistics.statistics.%s.totalCount", answer.getQuestion().getId()));

if (answer.getType().isOption()) {
update.inc(String.format("statistics.statistics.%s.legends.%s.count",
answer.getQuestion().getId(), answer.getAnswer().toString()));
}
}

mongoTemplate.findAndModify(query, update, options, Dashboard.class);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import java.util.Optional;

public interface DashboardRepository extends MongoRepository<Dashboard, String> {
public interface DashboardRepository extends MongoRepository<Dashboard, String>, DashboardCustomRepository {
Optional<Dashboard> findByUserAndPeriodAndRelation(User user, Period period, Relation relation);
boolean existsByUserAndPeriodAndRelation(User user, Period period, Relation relation);
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public void calculate(Statistics statistics) {
for (Legend legend : legends) {
if (totalCount == 0) {
rank.add(new RatioDto(legend.getText(), 0));
continue;
}
int percentage = (int) (legend.getCount() * 100 / totalCount);
optionPercentage += percentage;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public void calculate(Statistics statistics) {
for (Legend legend : legends) {
if (totalCount == 0) {
rank.add(new RatioDto(legend.getText(), 0));
continue;
}
int percentage = (int) (legend.getCount() * 100 / totalCount);
optionPercentage += percentage;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public void calculate(Statistics statistics) {
for (Legend legend : legends) {
if (totalCount == 0) {
rank.add(new RatioDto(legend.getText(), 0));
continue;
}
int percentage = (int) (legend.getCount() * 100 / totalCount);
optionPercentage += percentage;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import lombok.Builder;
import lombok.Getter;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.CompoundIndex;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.DocumentReference;

Expand All @@ -17,6 +18,7 @@
@Getter
@Builder
@Document("dashboards")
@CompoundIndex(def = "{ 'user': 1, 'period': 1, 'relation': 1 }", unique = true)
public class Dashboard extends BaseTimeEntity {

@Id
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
package com.dnd.namuiwiki.domain.question;

import com.dnd.namuiwiki.domain.question.entity.Question;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.lang.NonNull;

import java.util.List;
import java.util.Optional;

public interface QuestionRepository extends MongoRepository<Question, String> {

@NonNull
@Cacheable("questions")
List<Question> findAll();

@NonNull
@Cacheable("question")
Optional<Question> findById(@NonNull String id);

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class Question extends BaseTimeEntity {
private Long surveyOrder;
private boolean reasonRequired;

@DocumentReference
@DocumentReference(collection = "options")
private Map<String, Option> options;

public Optional<Option> getOption(String optionId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,12 @@ public void updateStatistics(Survey survey) {
Period period = survey.getPeriod();
Relation relation = survey.getRelation();

var statisticalAnswers = survey.getAnswers().stream()
var answers = survey.getAnswers().stream()
.filter(answer -> answer.getQuestion().getDashboardType().getStatisticsType().isNotNone())
.toList();

updateDashboards(owner, period, relation, statisticalAnswers);
updateBorrowingLimitStatistic(period, relation, statisticalAnswers);

updateDashboards(owner, period, relation, answers);
updateBorrowingLimitStatistic(period, relation, answers);
}

public PopulationStatistic getPopulationStatistic(Period period, Relation relation, QuestionName questionName) {
Expand All @@ -50,25 +49,26 @@ public PopulationStatistic getPopulationStatistic(Period period, Relation relati
.build());
}

private void updateDashboards(User owner, Period period, Relation relation, List<Answer> statisticalAnswers) {
updateDashboardByCategory(owner, null, null, statisticalAnswers);
updateDashboardByCategory(owner, period, null, statisticalAnswers);
updateDashboardByCategory(owner, null, relation, statisticalAnswers);
private void updateDashboards(User owner, Period period, Relation relation, List<Answer> answers) {
updateDashboard(owner, null, null, answers);
updateDashboard(owner, period, null, answers);
updateDashboard(owner, null, relation, answers);
}

private void updateDashboard(User owner, Period period, Relation relation, List<Answer> answers) {
insertDashboardIfNotExist(owner, period, relation, answers);
dashboardRepository.updateDashboard(owner, period, relation, answers);
}

private void updateDashboardByCategory(User owner, Period period, Relation relation, List<Answer> answers) {
Dashboard dashboard = dashboardRepository.findByUserAndPeriodAndRelation(owner, period, relation)
.orElseGet(() -> {
Dashboard newDashboard = Dashboard.builder()
.user(owner)
.period(period)
.relation(relation)
.statistics(Statistics.from(answers.stream().map(Answer::getQuestion).toList()))
.build();
return dashboardRepository.save(newDashboard);
});
dashboard.updateStatistics(answers);
dashboardRepository.save(dashboard);
private void insertDashboardIfNotExist(User owner, Period period, Relation relation, List<Answer> answers) {
if (!dashboardRepository.existsByUserAndPeriodAndRelation(owner, period, relation)) {
dashboardRepository.save(Dashboard.builder()
.user(owner)
.period(period)
.relation(relation)
.statistics(Statistics.from(answers.stream().map(Answer::getQuestion).toList()))
.build());
}
}

private void updateBorrowingLimitStatistic(Period period, Relation relation, List<Answer> answers) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,11 @@ public ResponseEntity<?> getReceivedSurveys(
}

@GetMapping("/{surveyId}")
public ResponseEntity<?> getSurvey(@PathVariable("surveyId") String surveyId) {
var response = surveyService.getSurvey(surveyId);
public ResponseEntity<?> getSurvey(
@JwtAuthorization TokenUserInfoDto tokenUserInfoDto,
@PathVariable("surveyId") String surveyId
) {
var response = surveyService.getSurvey(surveyId, tokenUserInfoDto);
return ResponseDto.ok(response);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.dnd.namuiwiki.domain.survey;

import com.dnd.namuiwiki.domain.statistic.StatisticsService;
import com.dnd.namuiwiki.domain.survey.model.dto.SurveyCreatedEvent;
import com.dnd.namuiwiki.domain.survey.model.entity.Survey;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;

@Slf4j
@RequiredArgsConstructor
public class SurveyEventHandler {
private final StatisticsService statisticsService;

@Async
@EventListener
public void handleSurveySuccessEvent(SurveyCreatedEvent event) {
Survey survey = event.getSurvey();
log.info("SurveyEventHandler.handleSurveySuccessEvent: surveyId={}", survey.getId());

statisticsService.updateStatistics(survey);
}

}
Loading

0 comments on commit 06b70ba

Please sign in to comment.