Skip to content

Commit

Permalink
fix: 블로그 방문자 수, 포스트 조회 수 통계 작업 오류 수정 (#138)
Browse files Browse the repository at this point in the history
* [#136] feat: 블로그 방문자 수 통계 작업 시 시작 시간대와 끝 시간대를 설정할 수 있도록 변경

* [#136] feat: 포스트 조회수 통계 작업 시 시작 시간대와 끝 시간대를 설정할 수 있도록 변경

(cherry picked from commit 8b6ddb5)
  • Loading branch information
shin-mallang committed Dec 10, 2023
1 parent 1530e8c commit a170185
Show file tree
Hide file tree
Showing 8 changed files with 222 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.mallang.statistics.statistic.source.BlogVisitHistory;
import com.mallang.statistics.statistic.source.BlogVisitHistoryRepository;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
Expand All @@ -23,16 +24,20 @@ public class BlogVisitStatisticJob {
private final BlogVisitStatisticRepository blogVisitStatisticRepository;
private final TransactionTemplate transactionTemplate;

public void blogVisitsAggregationJob() {
Map<String, List<BlogVisitHistory>> unprocessedHistories = getUnAggregatedVisitsStep();
public void blogVisitsAggregationJob(LocalDateTime startInclude, LocalDateTime endExclude) {
Map<String, List<BlogVisitHistory>> unprocessedHistories = getUnAggregatedVisitsStep(startInclude, endExclude);
Map<String, Map<LocalDate, List<BlogVisitHistory>>> historiesGroupedByDateByPostId =
groupingViewByDateStep(unprocessedHistories);
aggregateVisitsStep(historiesGroupedByDateByPostId);
}

private Map<String, List<BlogVisitHistory>> getUnAggregatedVisitsStep() {
return blogVisitHistoryRepository.findAll()
.stream()
private Map<String, List<BlogVisitHistory>> getUnAggregatedVisitsStep(
LocalDateTime startInclude,
LocalDateTime endExclude
) {
return blogVisitHistoryRepository.findWithCreatedDateBetweenIncludeStartAndExcludeEnd(
startInclude, endExclude
).stream()
.collect(groupingBy(BlogVisitHistory::getBlogName));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ public void runTask() {
LocalDateTime now = LocalDateTime.now();
log.info("블로그 방문수 통계 작업 실행 [실행시간: {}]", now);
JobExecution history = new JobExecution("blogVisitsAggregationJob", now);
jobHistoryRecorder.record(history, blogVisitStatisticJob::blogVisitsAggregationJob);
LocalDateTime startInclude = now.minusHours(2);
LocalDateTime endExclude = now.minusHours(1);
jobHistoryRecorder.record(history, () ->
blogVisitStatisticJob.blogVisitsAggregationJob(startInclude, endExclude)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.mallang.statistics.statistic.source.PostViewHistory;
import com.mallang.statistics.statistic.source.PostViewHistoryRepository;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
Expand All @@ -24,15 +25,18 @@ public class PostViewStatisticJob {
private final PostViewStatisticRepository postViewStatisticRepository;
private final TransactionTemplate transactionTemplate;

public void postViewsAggregationJob() {
Map<PostId, List<PostViewHistory>> unprocessedHistories = getUnAggregatedViewsStep();
public void postViewsAggregationJob(LocalDateTime startInclude, LocalDateTime endExclude) {
Map<PostId, List<PostViewHistory>> unprocessedHistories = getUnAggregatedViewsStep(startInclude, endExclude);
Map<PostId, Map<LocalDate, List<PostViewHistory>>> historiesGroupedByDateByPostId =
groupingViewByDateStep(unprocessedHistories);
aggregateViewsStep(historiesGroupedByDateByPostId);
}

private Map<PostId, List<PostViewHistory>> getUnAggregatedViewsStep() {
return postViewHistoryRepository.findAll()
private Map<PostId, List<PostViewHistory>> getUnAggregatedViewsStep(
LocalDateTime startInclude,
LocalDateTime endExclude
) {
return postViewHistoryRepository.findWithCreatedDateBetweenIncludeStartAndExcludeEnd(startInclude, endExclude)
.stream()
.collect(groupingBy(PostViewHistory::getPostId));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ public void runTask() {
LocalDateTime now = LocalDateTime.now();
log.info("포스트 조회수 통계 작업 실행 [실행시간: {}]", now);
JobExecution history = new JobExecution("postViewStatisticJob", now);
jobHistoryRecorder.record(history, postViewStatisticJob::postViewsAggregationJob);
LocalDateTime startInclude = now.minusHours(2);
LocalDateTime endExclude = now.minusHours(1);
jobHistoryRecorder.record(history,
() -> postViewStatisticJob.postViewsAggregationJob(startInclude, endExclude));
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
package com.mallang.statistics.statistic.source;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface BlogVisitHistoryRepository extends JpaRepository<BlogVisitHistory, Long> {

Optional<BlogVisitHistory> findFirstByUuidAndBlogNameOrderByCreatedDateDesc(UUID uuid, String blogName);

@Query("SELECT h FROM BlogVisitHistory h WHERE h.createdDate >= :startInclude AND h.createdDate < :endExclude")
List<BlogVisitHistory> findWithCreatedDateBetweenIncludeStartAndExcludeEnd(
@Param("startInclude") LocalDateTime startInclude,
@Param("endExclude") LocalDateTime endExclude
);
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
package com.mallang.statistics.statistic.source;

import com.mallang.post.domain.PostId;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface PostViewHistoryRepository extends JpaRepository<PostViewHistory, Long> {


Optional<PostViewHistory> findFirstByUuidAndPostIdOrderByCreatedDateDesc(UUID uuid, PostId postId);

@Query("SELECT h FROM PostViewHistory h WHERE h.createdDate >= :startInclude AND h.createdDate < :endExclude")
List<PostViewHistory> findWithCreatedDateBetweenIncludeStartAndExcludeEnd(
@Param("startInclude") LocalDateTime startInclude,
@Param("endExclude") LocalDateTime endExclude
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@ExtendWith(DataClearExtension.class)
@DisplayName("블로그 방문자수 통계 작업 (BlogVisitStatisticJob) 은(는)")
@SuppressWarnings("NonAsciiCharacters")
@DisplayNameGeneration(ReplaceUnderscores.class)
@ExtendWith(DataClearExtension.class)
@SpringBootTest
class BlogVisitStatisticJobTest {

Expand All @@ -40,14 +40,101 @@ class BlogVisitStatisticJobTest {
private final String blog2Name = "blog2name";

@Test
void 집계되지_않은_모든_조회_이력을_가져와_블로그별로_그리고_일자별로_개수를_집계한다() {
void 특정_시간대에_포함되지_않으면_집계하지_않는다() {
// given
LocalDateTime 시간_2000년_10월_4일_10시_0분 = LocalDateTime.of(2000, 10, 4, 10, 0);
LocalDateTime 시간_2000년_10월_4일_10시_59분 = LocalDateTime.of(2000, 10, 4, 10, 59);
LocalDateTime 시간_2000년_10월_4일_11시_0분 = LocalDateTime.of(2000, 10, 4, 11, 0);
blogVisitHistoryRepository.save(new BlogVisitHistory(
randomUUID(),
blog1Name,
"",
"",
시간_2000년_10월_4일_10시_0분
));
blogVisitHistoryRepository.save(new BlogVisitHistory(
randomUUID(),
blog1Name,
"",
"",
시간_2000년_10월_4일_10시_59분
));
BlogVisitHistory exclude = blogVisitHistoryRepository.save(new BlogVisitHistory(
randomUUID(),
blog1Name,
"",
"",
시간_2000년_10월_4일_11시_0분
));

// when
blogVisitStatisticJob.blogVisitsAggregationJob(시간_2000년_10월_4일_10시_0분, 시간_2000년_10월_4일_11시_0분);

// then
assertThat(blogVisitHistoryRepository.findAll().get(0).getId())
.isEqualTo(exclude.getId());
List<BlogVisitStatistic> all = blogVisitStatisticRepository.findAll();
assertThat(all).hasSize(1);
assertThat(all.get(0).getCount()).isEqualTo(2);
}

@Test
void 시작시간은_포함되며_끝시간은_포함되지_않는다() {
// given
LocalDateTime 시간_2000년_10월_4일_10시_0분 = LocalDateTime.of(2000, 10, 4, 10, 0);
LocalDateTime 시간_2000년_10월_4일_11시_0분 = LocalDateTime.of(2000, 10, 4, 11, 0);
LocalDateTime 시간_2000년_10월_4일_12시_0분 = LocalDateTime.of(2000, 10, 4, 12, 0);
BlogVisitHistory 시간_2000년_10월_4일_10시_0분_이력 = blogVisitHistoryRepository.save(
new BlogVisitHistory(
randomUUID(),
blog1Name,
"",
"",
시간_2000년_10월_4일_10시_0분
));
BlogVisitHistory 시간_2000년_10월_4일_11시_0분_이력 = blogVisitHistoryRepository.save(
new BlogVisitHistory(
randomUUID(),
blog1Name,
"",
"",
시간_2000년_10월_4일_11시_0분
));

// when
blogVisitStatisticJob.blogVisitsAggregationJob(시간_2000년_10월_4일_10시_0분, 시간_2000년_10월_4일_11시_0분);

// then
assertThat(blogVisitHistoryRepository.findById(시간_2000년_10월_4일_11시_0분_이력.getId())).isPresent();
assertThat(blogVisitHistoryRepository.findById(시간_2000년_10월_4일_10시_0분_이력.getId())).isEmpty();
assertThat(blogVisitStatisticRepository.findAll())
.hasSize(1)
.element(0)
.extracting(BlogVisitStatistic::getCount)
.isEqualTo(1);

// when
blogVisitStatisticJob.blogVisitsAggregationJob(시간_2000년_10월_4일_11시_0분, 시간_2000년_10월_4일_12시_0분);

// then
assertThat(blogVisitHistoryRepository.findById(시간_2000년_10월_4일_11시_0분_이력.getId())).isEmpty();
assertThat(blogVisitStatisticRepository.findAll())
.hasSize(1)
.element(0)
.extracting(BlogVisitStatistic::getCount)
.isEqualTo(2);
}

@Test
void 특정_시간대의_집계되지_않은_모든_조회_이력을_가져와_블로그별로_그리고_일자별로_개수를_집계한다() {
// given
LocalDateTime 시간_2000년_10월_4일_10시_0분 = LocalDateTime.of(2000, 10, 4, 10, 0);
LocalDateTime 시간_2000년_10월_4일_10시_59분 = LocalDateTime.of(2000, 10, 4, 10, 59);
LocalDateTime 시간_2000년_10월_4일_11시_0분 = LocalDateTime.of(2000, 10, 4, 11, 0);
LocalDateTime 시간_2000년_10월_5일_0시_30분 = LocalDateTime.of(2000, 10, 5, 0, 30);
LocalDateTime 시간_2000년_10월_5일_1시_22분 = LocalDateTime.of(2000, 10, 5, 1, 22);
LocalDateTime 시간_2001년_10월_19일_20시_2분 = LocalDateTime.of(2001, 10, 19, 20, 2);
LocalDateTime 시간_2001년_10월_20일 = LocalDateTime.of(2001, 10, 20, 0, 0, 0);
blogVisitHistoryRepository.save(new BlogVisitHistory(randomUUID(), blog1Name, "", "", 시간_2000년_10월_4일_10시_0분));
blogVisitHistoryRepository.save(new BlogVisitHistory(randomUUID(), blog1Name, "", "", 시간_2000년_10월_4일_10시_59분));
blogVisitHistoryRepository.save(new BlogVisitHistory(randomUUID(), blog1Name, "", "", 시간_2000년_10월_4일_11시_0분));
Expand All @@ -61,7 +148,7 @@ class BlogVisitStatisticJobTest {
blogVisitHistoryRepository.save(new BlogVisitHistory(randomUUID(), blog2Name, "", "", 시간_2000년_10월_4일_10시_0분));

// when
blogVisitStatisticJob.blogVisitsAggregationJob();
blogVisitStatisticJob.blogVisitsAggregationJob(시간_2000년_10월_4일_10시_0분, 시간_2001년_10월_20일);

// then
assertThat(blogVisitHistoryRepository.findAll()).isEmpty();
Expand Down Expand Up @@ -100,7 +187,7 @@ class BlogVisitStatisticJobTest {
LocalDateTime 시간_2000년_10월_4일_11시_0분 = LocalDateTime.of(2000, 10, 4, 11, 0);
blogVisitHistoryRepository.save(new BlogVisitHistory(randomUUID(), blog1Name, "", "", 시간_2000년_10월_4일_10시_0분));
blogVisitHistoryRepository.save(new BlogVisitHistory(randomUUID(), blog1Name, "", "", 시간_2000년_10월_4일_10시_59분));
blogVisitStatisticJob.blogVisitsAggregationJob();
blogVisitStatisticJob.blogVisitsAggregationJob(시간_2000년_10월_4일_10시_0분, 시간_2000년_10월_4일_11시_0분);

LocalDate 시간_2000년_10월_4일 = LocalDate.of(2000, 10, 4);
Optional<BlogVisitStatistic> statistic = blogVisitStatisticRepository
Expand All @@ -110,10 +197,11 @@ class BlogVisitStatisticJobTest {
assertThat(postViewStatistic.getBlogName()).isEqualTo(blog1Name);
assertThat(postViewStatistic.getStatisticDate()).isEqualTo(시간_2000년_10월_4일);
assertThat(postViewStatistic.getCount()).isEqualTo(2);
LocalDateTime 시간_2000년_10월_5일 = LocalDateTime.of(2000, 10, 5, 0, 0, 0);

// when
blogVisitHistoryRepository.save(new BlogVisitHistory(randomUUID(), blog1Name, "", "", 시간_2000년_10월_4일_11시_0분));
blogVisitStatisticJob.blogVisitsAggregationJob();
blogVisitStatisticJob.blogVisitsAggregationJob(시간_2000년_10월_4일_10시_0분, 시간_2000년_10월_5일);

// then
assertThat(blogVisitHistoryRepository.findAll()).isEmpty();
Expand Down
Loading

0 comments on commit a170185

Please sign in to comment.