Skip to content

Commit

Permalink
Merge pull request #58 from lotteon2/develop
Browse files Browse the repository at this point in the history
release
  • Loading branch information
ssjy4974 authored Jan 26, 2024
2 parents 46873d8 + b7bb43d commit 4cfa4db
Show file tree
Hide file tree
Showing 12 changed files with 170 additions and 39 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ dependencies {

implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.4.RELEASE'
implementation 'org.springframework.cloud:spring-cloud-aws-messaging:2.2.4.RELEASE'
implementation 'org.quartz-scheduler:quartz:2.3.2'

developmentOnly 'org.springframework.boot:spring-boot-devtools'

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.dailyon.auctionservice.chat.scheduler;

import com.dailyon.auctionservice.facade.BidFacade;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.SchedulerException;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class AuctionActivationJob implements Job {

@Override
public void execute(JobExecutionContext context) {
// JobDataMap에서 auctionId 가져오기
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
String auctionId = jobDataMap.getString("auctionId");
// auctionId를 사용하여 Job 실행
ApplicationContext applicationContext = null;
try {
applicationContext =
(ApplicationContext) context.getScheduler().getContext().get("applicationContext");
} catch (SchedulerException e) {
e.printStackTrace();
}
BidFacade bidFacade = applicationContext.getBean(BidFacade.class);
bidFacade.start(auctionId).subscribe();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,80 @@
import com.dailyon.auctionservice.service.AuctionService;
import com.dailyon.auctionservice.service.BidService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.quartz.*;
import org.springframework.scheduling.SchedulingException;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component;
import reactor.core.Disposable;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

@Slf4j
@Configuration
@Component
@EnableScheduling
public class ChatScheduler implements SchedulingConfigurer {

private final ThreadPoolTaskScheduler taskScheduler;
private final ChatHandler chatHandler;
private final AuctionService auctionService;
private final BidService bidService;
private SchedulerFactoryBean schedulerFactoryBean;
private long countdown = 1 * 30 * 1000;
private Disposable jobDisposable;

public ChatScheduler(
ChatHandler chatHandler, AuctionService auctionService, BidService bidService) {
ChatHandler chatHandler,
AuctionService auctionService,
BidService bidService,
SchedulerFactoryBean schedulerFactoryBean) {
taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.initialize();
this.chatHandler = chatHandler;
this.auctionService = auctionService;
this.bidService = bidService;
this.schedulerFactoryBean = schedulerFactoryBean;
}

@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setTaskScheduler(taskScheduler);
}

public void scheduleJob(LocalDateTime startTime, String auctionId)
throws SchedulingException, SchedulerException {
Date startAt = Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant());

// JobDataMap에 auctionId 저장
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("auctionId", auctionId);

JobDetail jobDetail =
JobBuilder.newJob(AuctionActivationJob.class)
.withIdentity("auctionActivationJob")
.usingJobData(jobDataMap) // JobDataMap 사용
.build();

Trigger trigger =
TriggerBuilder.newTrigger()
.withIdentity("auctionActivationTrigger")
.startAt(startAt)
.build();

Scheduler scheduler = schedulerFactoryBean.getScheduler();
scheduler.scheduleJob(jobDetail, trigger);

scheduler.start();
}

public void startJob(String auctionId) {
countdown = 3 * 60 * 1000;
if (this.jobDisposable == null || this.jobDisposable.isDisposed()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.dailyon.auctionservice.config;

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
import org.springframework.stereotype.Component;

@Component
public final class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory
implements ApplicationContextAware {

@Autowired private AutowireCapableBeanFactory beanFactory;

@Override
public void setApplicationContext(final ApplicationContext context) {
beanFactory = context.getAutowireCapableBeanFactory();
}

@Override
protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
final Object job =
beanFactory.autowire(
Class.forName(bundle.getJobDetail().getJobClass().getName()),
AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR,
true);
return job;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ public void setDynamoDB() {
CreateTableRequest createAuction =
dynamoDBMapper
.generateCreateTableRequest(Auction.class)
.withProvisionedThroughput(new ProvisionedThroughput(10L, 10L));
.withProvisionedThroughput(new ProvisionedThroughput(1L, 1L));

CreateTableRequest createBidHistory =
dynamoDBMapper
.generateCreateTableRequest(BidHistory.class)
.withProvisionedThroughput(new ProvisionedThroughput(100L, 100L));
.withProvisionedThroughput(new ProvisionedThroughput(1L, 1L));

CreateTableRequest createAuctionHistory =
dynamoDBMapper
Expand All @@ -46,7 +46,7 @@ public void setDynamoDB() {
.getGlobalSecondaryIndexes()
.forEach(
idx ->
idx.withProvisionedThroughput(new ProvisionedThroughput(1000L, 1000L))
idx.withProvisionedThroughput(new ProvisionedThroughput(1L, 1L))
.withProjection(new Projection().withProjectionType("ALL")));
createAuctionHistory
.getGlobalSecondaryIndexes()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.dailyon.auctionservice.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

@Configuration
public class SchedulerConfig {

@Autowired private ApplicationContext applicationContext;

@Bean
public SchedulerFactoryBean schedulerFactoryBean() {
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();

AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
jobFactory.setApplicationContext(applicationContext);
schedulerFactoryBean.setApplicationContextSchedulerContextKey("applicationContext");
schedulerFactoryBean.setJobFactory(jobFactory);

return schedulerFactoryBean;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ public Mono<Sinks.EmitResult> sendMessage(ChatPayload chatMessage) {
.doOnSuccess(
emitResult -> {
if (emitResult.isFailure()) {
log.error("emit result : {}", emitResult);
}
});
}
Expand All @@ -91,6 +90,7 @@ public Mono<Void> broadCast(ChatPayload chatPayload) {
}

public Mono<Void> broadCastStart(ChatPayload payload) {
log.info("start payload : {}", payload.getData());
return objectStringConverter
.objectToString(payload)
.flatMap(redisChatMessagePublisher::publishChatMessage)
Expand Down

This file was deleted.

43 changes: 31 additions & 12 deletions src/main/java/com/dailyon/auctionservice/facade/AuctionFacade.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.dailyon.auctionservice.facade;

import com.dailyon.auctionservice.chat.scheduler.ChatScheduler;
import com.dailyon.auctionservice.chat.util.JwtUtil;
import com.dailyon.auctionservice.common.webclient.client.ProductClient;
import com.dailyon.auctionservice.document.Auction;
Expand All @@ -9,33 +10,48 @@
import com.dailyon.auctionservice.dto.response.ReadAuctionPageResponse;
import com.dailyon.auctionservice.service.AuctionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.SchedulerException;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.Map;

@Slf4j
@Component
@RequiredArgsConstructor
public class AuctionFacade {
private final AuctionService auctionService;
private final ProductClient productClient;
private final ChatScheduler scheduler;
private final JwtUtil jwtUtil;

public Mono<CreateAuctionResponse> createAuction(
String memberId, String role, CreateAuctionRequest createAuctionRequest) {
String memberId, String role, CreateAuctionRequest createAuctionRequest) {
return productClient
.createProduct(memberId, role, createAuctionRequest.getProductRequest())
.flatMap(response -> {
Auction auction = null;
try {
.flatMap(
response -> {
Auction auction = null;
try {
auction = auctionService.create(createAuctionRequest, response);
} catch (Exception e) {
String auctionId = auction.getId();
Auction finalAuction = auction;
return Mono.fromRunnable(
() -> {
try {
scheduler.scheduleJob(finalAuction.getStartAt(), auctionId);
} catch (SchedulerException e) {
log.error(e.getMessage());
}
})
.thenReturn(CreateAuctionResponse.create(auction, response));
} catch (Exception e) {
productClient.deleteProducts(memberId, role, response.getProductId());
}
return Mono.just(CreateAuctionResponse.create(auction, response));
});
return Mono.error(e);
}
});
}

public ReadAuctionPageResponse readAuctionsForAdmin(Pageable pageable) {
Expand Down Expand Up @@ -68,9 +84,12 @@ public Mono<ReadAuctionDetailResponse> readAuctionDetail(String auctionId) {
}

public Mono<Void> deleteAuction(String memberId, String role, String auctionId) {
return Mono.just(auctionService.readAuction(auctionId))
.flatMap(auction -> productClient.deleteProducts(memberId, role, auction.getAuctionProductId())
.then(Mono.fromRunnable(() -> auctionService.delete(auction))));
return Mono.just(auctionService.readAuction(auctionId))
.flatMap(
auction ->
productClient
.deleteProducts(memberId, role, auction.getAuctionProductId())
.then(Mono.fromRunnable(() -> auctionService.delete(auction))));
}

public String createToken(Long memberId) {
Expand Down
12 changes: 3 additions & 9 deletions src/main/java/com/dailyon/auctionservice/facade/BidFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.dailyon.auctionservice.chat.response.ChatCommand;
import com.dailyon.auctionservice.chat.response.ChatPayload;
import com.dailyon.auctionservice.chat.scheduler.ChatScheduler;
import com.dailyon.auctionservice.controller.ChatHandler;
import com.dailyon.auctionservice.document.Auction;
import com.dailyon.auctionservice.dto.request.CreateBidRequest;
Expand All @@ -23,7 +22,6 @@ public class BidFacade {
private final BidService bidService;
private final AuctionService auctionService;
private final ChatHandler chatHandler;
private final ChatScheduler scheduler;

public Mono<Long> createBid(CreateBidRequest request, String memberId) {
Auction auction = auctionService.readAuction(request.getAuctionId());
Expand All @@ -42,22 +40,18 @@ public Mono<Long> createBid(CreateBidRequest request, String memberId) {
}

public Mono<Void> start(String auctionId) {
ChatPayload<Object> payload = ChatPayload.of(ChatCommand.START, "start");
ChatPayload<Object> payload = ChatPayload.of(ChatCommand.START, auctionId);
return auctionService
.startAuction(auctionId)
.flatMap(
auction -> {
scheduler.startJob(auctionId);
return chatHandler.broadCastStart(payload);
});
.flatMap(auction -> chatHandler.broadCastStart(payload));
}

public Mono<Void> end(String auctionId) {
return auctionService
.endAuction(auctionId)
.flatMap(
auction -> {
ChatPayload<Object> payload = ChatPayload.of(ChatCommand.AUCTION_CLOSE, "end");
ChatPayload<Object> payload = ChatPayload.of(ChatCommand.AUCTION_CLOSE, auctionId);
return chatHandler.broadCast(payload).then();
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.dailyon.auctionservice.dto.request.CreateAuctionRequest;
import com.dailyon.auctionservice.repository.AuctionRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
Expand All @@ -18,6 +19,7 @@

import static com.dailyon.auctionservice.dto.response.ReadAuctionDetailResponse.ReadAuctionResponse;

@Slf4j
@Service
@RequiredArgsConstructor
public class AuctionService {
Expand Down Expand Up @@ -160,6 +162,7 @@ public Mono<Auction> startAuction(String auctionId) {
}

public Mono<Auction> endAuction(String auctionId) {
log.info("auctionId {}", auctionId);
return Mono.justOrEmpty(auctionRepository.findById(auctionId))
.switchIfEmpty(Mono.error(new RuntimeException("존재하지 않는 경매입니다")))
.flatMap(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,6 @@ private Flux<AuctionHistory> createAuctionHistories(
return bidders.map(
tuple -> {
BidInfo value = tuple.getValue();
log.info("asdasd {} :", tuple.getValue().getMemberId());
return value.createAuctionHistory(
auction, product, tuple.getScore().longValue(), auctionWinnerBid, isSuccessful);
});
Expand Down

0 comments on commit 4cfa4db

Please sign in to comment.