Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,10 @@ out/
/.nb-gradle/

### VS Code ###
.vscode/
.vscode/

### macOS ###
.DS_Store

### applicaion 제외 ###
src/main/resources/application.yaml
14 changes: 13 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,23 @@ repositories {

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.9.0'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.kafka:spring-kafka'

//Mail
implementation 'org.springframework.boot:spring-boot-starter-mail'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'


runtimeOnly 'com.mysql:mysql-connector-j'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
}

tasks.named('test') {
Expand Down
36 changes: 36 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
version: '3.7'
services:
mysql:
container_name: kuback-mysql
image: mysql:8
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --explicit_defaults_for_timestamp=1
ports:
- 3307:3306
environment:
- MYSQL_DATABASE=kuback
- MYSQL_USER=admin
- MYSQL_PASSWORD=1234
- MYSQL_ROOT_PASSWORD=1234
- TZ=UTC
volumes:
- ./mysql/init:/docker-entrypoint-initdb.d

zookeeper:
image: wurstmeister/zookeeper:3.4.6
ports:
- "2181:2181"

kafka:
image: wurstmeister/kafka:latest
ports:
- "9092:9092"
expose:
- "9093"
environment:
KAFKA_LISTENERS: INSIDE://0.0.0.0:9093,OUTSIDE://0.0.0.0:9092
KAFKA_ADVERTISED_LISTENERS: INSIDE://kafka:9093,OUTSIDE://localhost:9092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
volumes:
- /var/run/docker.sock:/var/run/docker.sock
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@EnableAsync
@SpringBootApplication
public class KubackNotificationApplication {

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.server.kubacknotification.api;

import com.server.kubacknotification.application.service.TestService;
import com.server.kubacknotification.global.common.PaymentMessage;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
public class TestController {

private final TestService testService;

@PostMapping("/payments")
public ResponseEntity<String> sendPaymentMessage(@RequestBody PaymentMessage paymentMessage) {
testService.publishPaymentMessage(paymentMessage);
return ResponseEntity.ok("Payment message sent successfully");
}
}

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.server.kubacknotification.application.service;

import com.server.kubacknotification.global.common.PaymentMessage;
import jakarta.mail.internet.MimeMessage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring6.SpringTemplateEngine;

@Service
@RequiredArgsConstructor
@Slf4j
@Transactional(readOnly = true)
public class EmailService {

private final JavaMailSender javaMailSender;
private final SpringTemplateEngine templateEngine;

// Kafka로부터 PaymentMessage를 수신하고 이메일 발송
@KafkaListener(topics = "payment", groupId = "group1", containerFactory = "paymentMessageKafkaListenerContainerFactory")
public void consumePaymentMessage(PaymentMessage paymentMessage) {
sendPaymentEmail(paymentMessage);
}

@Async
public void sendPaymentEmail(PaymentMessage paymentMessage) {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
try {
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, false, "UTF-8");
mimeMessageHelper.setTo(paymentMessage.getEmail()); // 수신자 이메일을 PaymentMessage의 email 필드로 설정
mimeMessageHelper.setSubject("결제 완료 안내"); // 이메일 제목

// HTML 콘텐츠 생성
String htmlContent = setPaymentContext(paymentMessage);
mimeMessageHelper.setText(htmlContent, true); // HTML 여부 true 설정

javaMailSender.send(mimeMessage);
log.info("Succeeded to send Email to: {}", paymentMessage.getUserId());
} catch (Exception e) {
log.error("Failed to send Email to: {}", paymentMessage.getUserId(), e);
throw new RuntimeException(e);
}
}

// HTML 템플릿에 PaymentMessage 데이터 주입
public String setPaymentContext(PaymentMessage paymentMessage) {
Context context = new Context();
context.setVariable("paymentMessage", paymentMessage);
return templateEngine.process("payment", context); // "payment.html" 템플릿 사용
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.server.kubacknotification.application.service;

import com.server.kubacknotification.global.common.PaymentMessage;
import lombok.RequiredArgsConstructor;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class TestService {

private final KafkaTemplate<String, PaymentMessage> kafkaTemplate;
private static final String TOPIC = "payment";

public void publishPaymentMessage(PaymentMessage paymentMessage) {
// Kafka로 paymentMessage 전송
kafkaTemplate.send(TOPIC, paymentMessage);
}
}
20 changes: 0 additions & 20 deletions src/main/java/com/server/kubacknotification/domain/entity/A.java

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.server.kubacknotification.global.common;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Schema(description = "결제 메시지")
public class PaymentMessage {

@Schema(description = "유저 ID", example = "1")
private Long userId;

@Schema(description = "유저 이메일", example = "@gmail.com")
private String email;

@Schema(description = "유저 이름", example = "문희상")
private String userName;

@Schema(description = "좌석 번호", example = "A12")
private String seatNumber;

@Schema(description = "좌석 등급", example = "VIP")
private String seatGrade;

@Schema(description = "결제 금액", example = "15000")
private String payment;

@Schema(description = "결제 날짜", example = "2024-10-06T14:00:00")
private LocalDateTime payDate;

@Schema(description = "원래 가격", example = "20000")
private String originalPrice;

@Schema(description = "할인 금액", example = "5000")
private String salePrice;

@Schema(description = "최종 결제 금액", example = "15000")
private String finalPrice;
}



Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.server.kubacknotification.global.config;

import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;

import java.util.Properties;

@Configuration
@RequiredArgsConstructor
public class EmailConfig {

private static final String MAIL_SMTP_AUTH = "mail.smtp.auth";
private static final String MAIL_DEBUG = "mail.smtp.debug";
private static final String MAIL_CONNECTION_TIMEOUT = "mail.smtp.connectiontimeout";
private static final String MAIL_SMTP_STARTTLS_ENABLE = "mail.smtp.starttls.enable";

// SMTP 서버
@Value("${spring.mail.host}")
private String host;

// 계정
@Value("${spring.mail.username}")
private String username;

// 비밀번호
@Value("${spring.mail.password}")
private String password;

// 포트번호
@Value("${spring.mail.port}")
private int port;

@Value("${spring.mail.properties.mail.smtp.auth}")
private boolean auth;

@Value("${spring.mail.properties.mail.smtp.debug}")
private boolean debug;

@Value("${spring.mail.properties.mail.smtp.connectiontimeout}")
private int connectionTimeout;

@Value("${spring.mail.properties.mail.starttls.enable}")
private boolean startTlsEnable;

@Bean
public JavaMailSender javaMailService() {
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
javaMailSender.setHost(host);
javaMailSender.setUsername(username);
javaMailSender.setPassword(password);
javaMailSender.setPort(port);

Properties properties = javaMailSender.getJavaMailProperties();
properties.put(MAIL_SMTP_AUTH, auth);
properties.put(MAIL_DEBUG, debug);
properties.put(MAIL_CONNECTION_TIMEOUT, connectionTimeout);
properties.put(MAIL_SMTP_STARTTLS_ENABLE, startTlsEnable);

javaMailSender.setJavaMailProperties(properties);
javaMailSender.setDefaultEncoding("UTF-8");

return javaMailSender;
}

}
Loading