Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hotfix : 일별 다이어리 조회 DTO 양식 통일 #177

Merged
merged 33 commits into from
Sep 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
b81fadd
Feat : 토큰 업데이트 구현
hyunw9 Aug 28, 2024
fb935b0
Feat : Controller DTO 수정
hyunw9 Aug 28, 2024
8301f15
Test : 회원가입 테스트
hyunw9 Aug 28, 2024
3ce7f12
Feat(batch) : batch 모듈 추가 및 초기 설정
hyunw9 Aug 29, 2024
8a10644
Feat(app) : 일기 시간 조회시 답변 타입도 같이 반환
hyunw9 Aug 29, 2024
0558826
Feat(infra) : batch를 위한 meta DataSource 설정파일
hyunw9 Aug 29, 2024
14661cb
Feat(infra) : Schedule Repository Adapter계층 구현
hyunw9 Aug 29, 2024
ddf6277
Feat(domain) : 도메인 계층 모델 정의
hyunw9 Aug 29, 2024
385e701
Feat(domain) : 답변 작성시 알림 스케줄 이벤트 발행
hyunw9 Aug 29, 2024
b6fe26f
Chore(etc) : 사용하지 않는 파일 제거 및 형식 변경
hyunw9 Aug 29, 2024
df51e4b
Feat(batch) : build.gradle
hyunw9 Aug 29, 2024
10463a2
Feat(batch) : config 추가
hyunw9 Aug 29, 2024
4c40bd2
Feat(batch) : Job 및 Step 구현
hyunw9 Aug 29, 2024
6c4d220
Test(batch) : 일기 작성 알림 테스트
hyunw9 Aug 29, 2024
8e7e501
Feat(domain) : schedule 엔티티 구현
hyunw9 Aug 29, 2024
d57cb49
Feat(infra) : adapter 계층 구현
hyunw9 Aug 29, 2024
4ba1030
Chore : 기타 파일 수정
hyunw9 Aug 29, 2024
2a5e8cb
Merge branch 'prod' into Feat/#167
hyunw9 Aug 29, 2024
d77d684
Feat(domain) : 도메인 계층 알람 전략 구현
hyunw9 Sep 1, 2024
7056aa1
Feat(domain) : Alarm Creation Event & Message
hyunw9 Sep 1, 2024
d19185c
Feat(domain) : Schedule 및 Repository
hyunw9 Sep 1, 2024
ac52fb3
Feat(domain) : alarm publisher 및 이벤트 정의
hyunw9 Sep 1, 2024
79ad28e
Feat(domain) : 이벤트 발행 DTO 이름 변경
hyunw9 Sep 1, 2024
bed2d14
Feat(infra) : 의존성 추가
hyunw9 Sep 1, 2024
d5e04cb
Feat(infra) : MultiDataSource 설정 및 MultiTransactionManager 설정
hyunw9 Sep 1, 2024
853b12a
Feat(infra) : Adapter 메서드 명 변경
hyunw9 Sep 1, 2024
6e7e242
Feat(infra) : 스케줄링 정보 등록 및 예약 구현
hyunw9 Sep 1, 2024
28c5a51
Feat(batch) : 배치 미활용으로 인한 임시 보류
hyunw9 Sep 1, 2024
3cf7e90
Merge branch 'prod' into Feat/#167
hyunw9 Sep 1, 2024
a8cfcb2
Chore : 컨벤션 및 변수명 수정
hyunw9 Sep 1, 2024
c1a372f
HotFix : 일별 일기 조회 DTO통일을 위한 조회 로직
hyunw9 Sep 1, 2024
e8c84c3
Feat : 삭제시 삭제 이력 추가 반환
hyunw9 Sep 1, 2024
eac47c6
Fix : Spring Data JPA 메서드 명 수정
hyunw9 Sep 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ subprojects {

}

tasks.withType<BootJar> {
enabled = false;
}
// tasks.withType<BootJar> {
// enabled = false;
// }
tasks.withType<Jar> {
enabled = true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
import java.util.List;

public record DiaryResponse(
List<DiaryContent> diaries
List<DiaryContent> diaries,
boolean isDeleted
) {
public static DiaryResponse of(List<DiaryContent> diaries) {
return new DiaryResponse(diaries);
}

public static DiaryResponse of(List<DiaryContent> diaries, boolean isDeleted) {
return new DiaryResponse(diaries, isDeleted);
}
}

Original file line number Diff line number Diff line change
@@ -1,59 +1,60 @@
package com.clody.clodyapi.diary.mapper;

import com.clody.clodyapi.diary.controller.dto.response.DiaryCreatedResponse;
import com.clody.clodyapi.diary.controller.dto.response.DiaryCreatedTimeResponse;
import com.clody.clodyapi.diary.controller.dto.response.DiaryResponse;
import com.clody.domain.diary.dto.DiaryContent;
import com.clody.domain.diary.dto.DiaryDateInfo;
import com.clody.domain.diary.dto.DiaryDeletionInfo;
import com.clody.domain.diary.dto.DiaryDomainInfo;
import com.clody.domain.diary.dto.response.DiaryListGetResponse;
import com.clody.domain.diary.dto.response.DiaryCalenderGetResponse;
import com.clody.domain.diary.dto.response.DiaryCreatedInfo;
import com.clody.domain.diary.dto.response.DiaryDayInfo;
import com.clody.domain.diary.dto.response.DiaryListInfo;
import com.clody.domain.reply.ReplyType;
import com.clody.support.security.util.JwtUtil;
import java.time.LocalDateTime;
import java.util.List;

public class DiaryMapper {

public static DiaryResponse toDiaryResponse(List<DiaryContent> diaryContentList) {
return DiaryResponse.of(diaryContentList);
}

public static DiaryCreatedResponse toDiaryCreatedResponse(DiaryDomainInfo domainInfo) {
ReplyType type = domainInfo.replyType();
LocalDateTime createdAt = domainInfo.diaryList().getFirst().getCreatedAt();
return DiaryCreatedResponse.of(createdAt, type);
}

public static DiaryDeletionInfo toDiaryDeletionInfo(int year, int month, int date) {
Long userId = JwtUtil.getLoginMemberId();
return DiaryDeletionInfo.of(userId, year, month, date);
}

public static DiaryDateInfo toDiaryDateInfo(int year, int month, int date) {
return DiaryDateInfo.of(year, month, date);
}
package com.clody.clodyapi.diary.mapper;

import com.clody.clodyapi.diary.controller.dto.response.DiaryCreatedResponse;
import com.clody.clodyapi.diary.controller.dto.response.DiaryCreatedTimeResponse;
import com.clody.clodyapi.diary.controller.dto.response.DiaryResponse;
import com.clody.domain.diary.dto.DiaryContent;
import com.clody.domain.diary.dto.DiaryDateInfo;
import com.clody.domain.diary.dto.DiaryDeletionInfo;
import com.clody.domain.diary.dto.DiaryDomainInfo;
import com.clody.domain.diary.dto.response.DiaryListGetResponse;
import com.clody.domain.diary.dto.response.DiaryCalenderGetResponse;
import com.clody.domain.diary.dto.response.DiaryCreatedInfo;
import com.clody.domain.diary.dto.response.DiaryDayInfo;
import com.clody.domain.diary.dto.response.DiaryListInfo;
import com.clody.domain.reply.ReplyType;
import com.clody.support.security.util.JwtUtil;
import java.time.LocalDateTime;
import java.util.List;

public class DiaryMapper {

public static DiaryResponse toDiaryResponse(List<DiaryContent> diaryContentList,
boolean userHasDeletedDiary) {
return DiaryResponse.of(diaryContentList, userHasDeletedDiary);
}

public static DiaryCreatedResponse toDiaryCreatedResponse(DiaryDomainInfo domainInfo) {
ReplyType type = domainInfo.replyType();
LocalDateTime createdAt = domainInfo.diaryList().getFirst().getCreatedAt();
return DiaryCreatedResponse.of(createdAt, type);
}

public static DiaryDeletionInfo toDiaryDeletionInfo(int year, int month, int date) {
Long userId = JwtUtil.getLoginMemberId();
return DiaryDeletionInfo.of(userId, year, month, date);
}

public static DiaryDateInfo toDiaryDateInfo(int year, int month, int date) {
return DiaryDateInfo.of(year, month, date);
}

public static DiaryCreatedTimeResponse toDiaryCreatedTimeResponse(DiaryCreatedInfo info) {
return DiaryCreatedTimeResponse.of(info.HH(), info.MM(), info.SS(), info.replyType());
}

public static DiaryListGetResponse toDiaryListResponse(DiaryListInfo diaryListInfo) {

int totalCloverCount = diaryListInfo.totalCloverCount();
List<DiaryDayInfo> diaries = diaryListInfo.diaries();
return DiaryListGetResponse.of(totalCloverCount, diaries);
}

public static DiaryCalenderGetResponse toDiaryCalendarResponse(DiaryListInfo diaryListInfo) {

int totalCloverCount = diaryListInfo.totalCloverCount();
List<DiaryDayInfo> diaries = diaryListInfo.diaries();
return DiaryCalenderGetResponse.of(totalCloverCount, diaries);
}

public static DiaryCreatedTimeResponse toDiaryCreatedTimeResponse(DiaryCreatedInfo info) {
return DiaryCreatedTimeResponse.of(info.HH(), info.MM(), info.SS(), info.replyType());
}

public static DiaryListGetResponse toDiaryListResponse(DiaryListInfo diaryListInfo){

int totalCloverCount = diaryListInfo.totalCloverCount();
List<DiaryDayInfo> diaries = diaryListInfo.diaries();
return DiaryListGetResponse.of(totalCloverCount, diaries);
}

public static DiaryCalenderGetResponse toDiaryCalendarResponse(DiaryListInfo diaryListInfo){

int totalCloverCount = diaryListInfo.totalCloverCount();
List<DiaryDayInfo> diaries = diaryListInfo.diaries();
return DiaryCalenderGetResponse.of(totalCloverCount, diaries);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public DiaryResponse deleteDiary(final int year, final int month, final int date
//Mapper에서 변환
DiaryDeletionInfo diaryDeletionInfo = DiaryMapper.toDiaryDeletionInfo(year, month, date);
diaryCommandService.removeDiarySoft(diaryDeletionInfo);
return DiaryResponse.of(List.of());
return DiaryResponse.of(List.of(),true);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public DiaryCreatedTimeResponse getCreatedTime(int year, int month, int date) {
public DiaryResponse getDiary(final int year, final int month, final int date) {
DiaryDateInfo diaryDateInfo = DiaryMapper.toDiaryDateInfo(year, month, date);
List<DiaryContent> diaryContentList = diaryQueryService.getDiary(diaryDateInfo);
return DiaryMapper.toDiaryResponse(diaryContentList);
boolean userHasDeletedDiary = diaryQueryService.isUserHasDeletedDiary(diaryDateInfo);
return DiaryMapper.toDiaryResponse(diaryContentList, userHasDeletedDiary);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ public class UserControllerImpl implements UserController {
private final UserUpdateUsecase userUpdateUsecase;
private final UserDeletionUsecase userDeletionUsecase;



@Override
@GetMapping("/user/info")
public ResponseEntity<ApiResponse<UserInfoGetResponse>> getUserInfo() {
Expand Down
19 changes: 16 additions & 3 deletions clody-batch/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
import io.spring.gradle.dependencymanagement.dsl.DependencyManagementExtension
import org.gradle.internal.impldep.org.junit.experimental.categories.Categories.CategoryFilter.include
import org.springframework.boot.gradle.tasks.bundling.BootJar

plugins {
java
id("org.springframework.boot") version "3.3.0"
// id("io.spring.dependency-management") version "1.1.5"

}

group = "com.clody"
version = "0.0.1-SNAPSHOT"
group = "com.clody-batch"
version = "1.0.0"

java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}


repositories {
mavenCentral()
}

dependencies {
implementation(project(":clody-domain"))
implementation(project(":clody-infra"))
// implementation(project(":clody-infra"))
// implementation(project(":clody-support"))
implementation("org.springframework.boot:spring-boot-starter-batch")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.batch:spring-batch-test")
Expand All @@ -40,6 +45,14 @@ tasks.withType<Test> {
useJUnitPlatform()
}

tasks.named<BootJar>("bootJar") {
enabled = true
}

tasks.named<Jar>("jar") {
enabled = true
}

the<DependencyManagementExtension>().apply {
imports {
mavenBom("org.springframework.cloud:spring-cloud-dependencies:${property("springCloudDependenciesVersion")}")
Expand Down
Empty file modified clody-batch/gradle/wrapper/gradle-wrapper.properties
100644 → 100755
Empty file.
Empty file modified clody-batch/gradlew
100644 → 100755
Empty file.
Empty file modified clody-batch/gradlew.bat
100644 → 100755
Empty file.
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
package com.clody.clodybatch;

import lombok.extern.slf4j.Slf4j;
import static com.clody.clodybatch.config.BatchConfig.BATCH_DATASOURCE;
import static com.clody.clodybatch.config.BatchConfig.BATCH_TRANSACTION_MANAGER;

import com.clody.clodybatch.config.BatchConfig;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.support.DefaultBatchConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.Import;

@EnableBatchProcessing
@Import({BatchConfig.class})
@EnableBatchProcessing(dataSourceRef = BATCH_DATASOURCE, transactionManagerRef = BATCH_TRANSACTION_MANAGER)
@SpringBootApplication
@Slf4j
@ConditionalOnMissingBean(value = DefaultBatchConfiguration.class, annotation = EnableBatchProcessing.class)
public class ClodyBatchApplication {

public static void main(String[] args) {
int exit = SpringApplication.exit(SpringApplication.run(ClodyBatchApplication.class, args));
log.info("exit = {}", exit);
System.exit(exit);
System.setProperty("spring.config.name","application-batch");
SpringApplication springApplication = new SpringApplicationBuilder(ClodyBatchApplication.class).web(
WebApplicationType.NONE).build();
springApplication.run(args);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.clody.clodybatch.config;

import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.support.DefaultBatchConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;

@ConditionalOnMissingBean(value = DefaultBatchConfiguration.class, annotation = EnableBatchProcessing.class)
public class BatchAutoConfiguration {
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,75 @@
package com.clody.clodybatch.config;

import com.clody.infra.meta.JpaScheduleMetaRepository;
import com.clody.meta.Schedule;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Collections;
import org.springframework.batch.core.configuration.support.DefaultBatchConfiguration;
import org.springframework.batch.item.data.RepositoryItemReader;
import com.zaxxer.hikari.HikariDataSource;
import java.util.Collection;
import javax.sql.DataSource;
import lombok.RequiredArgsConstructor;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.explore.JobExplorer;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.batch.BatchDataSource;
import org.springframework.boot.autoconfigure.batch.BatchDataSourceScriptDatabaseInitializer;
import org.springframework.boot.autoconfigure.batch.BatchProperties;
import org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.util.StringUtils;

@Configuration
public class BatchConfig extends DefaultBatchConfiguration {
@RequiredArgsConstructor
@EnableConfigurationProperties(BatchProperties.class)
public class BatchConfig {

public static final String BATCH_DATASOURCE = "batchDataSource";
public static final String BATCH_TRANSACTION_MANAGER = "batchTransactionManager";

@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.batch.job", name = "enabled", havingValue = "true", matchIfMissing = true)
public JobLauncherApplicationRunner jobLauncherApplicationRunner(JobLauncher jobLauncher, JobExplorer jobExplorer,
JobRepository jobRepository, BatchProperties properties, Collection<Job> jobs) {
JobLauncherApplicationRunner runner = new JobLauncherApplicationRunner(jobLauncher, jobExplorer, jobRepository);
String jobNames = properties.getJob().getName();
if (StringUtils.hasText(jobNames)) {
if (jobs.stream().map(Job::getName).noneMatch(s -> s.equals(jobNames))){
throw new IllegalArgumentException(jobNames + "는 등록되지 않은 job name입니다. job name을 확인하세요.");
}
runner.setJobName(jobNames);
}
return runner;
}

@Bean
public RepositoryItemReader<Schedule> metaScheduleReader(
JpaScheduleMetaRepository scheduleMetaRepository){
RepositoryItemReader<Schedule> reader = new RepositoryItemReader<>();
reader.setRepository(scheduleMetaRepository);
reader.setMethodName("findByNotificationTime");
reader.setArguments(Collections.singletonList(LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS)));
reader.setPageSize(10);
return reader;
@ConditionalOnMissingBean(BatchDataSourceScriptDatabaseInitializer.class)
BatchDataSourceScriptDatabaseInitializer batchDataSourceInitializer(DataSource dataSource,
@BatchDataSource ObjectProvider<DataSource> batchDataSource, BatchProperties properties) {
return new BatchDataSourceScriptDatabaseInitializer(
batchDataSource.getIfAvailable(() -> dataSource),
properties.getJdbc());
}

@Primary
@BatchDataSource
@Bean(BATCH_DATASOURCE)
@ConfigurationProperties(prefix = "spring.datasource.batch.hikari")
public DataSource batchDataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}

@Bean(BATCH_TRANSACTION_MANAGER)
public PlatformTransactionManager batchTransactionManager(
@Qualifier(BATCH_DATASOURCE) DataSource batchDataSource) {
return new DataSourceTransactionManager(batchDataSource);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//package com.clody.clodybatch.config;
//
//import jakarta.annotation.PostConstruct;
//import java.util.Map;
//import lombok.RequiredArgsConstructor;
//import org.springframework.batch.core.Job;
//import org.springframework.context.ApplicationContext;
//import org.springframework.stereotype.Component;
//
//@Component
//@RequiredArgsConstructor
//public class Inspector {
//
// private final ApplicationContext applicationContext;
//
// @PostConstruct
// public void printAllJobs() {
// Map<String, Job> jobs = applicationContext.getBeansOfType(Job.class);
// System.out.println("Registered Jobs:");
// jobs.forEach((name, job) -> System.out.println("Job name: " + name));
// }
//}
Loading
Loading