Skip to content

Commit

Permalink
Merge pull request #93 from TeamSobokSobok/feature/#92-MessageQueue
Browse files Browse the repository at this point in the history
[Feat]: 푸시알림 및 안쓰는 파일 삭제
  • Loading branch information
dev-Crayon authored Feb 28, 2024
2 parents 3ada81f + a5d7276 commit fea0ec9
Show file tree
Hide file tree
Showing 25 changed files with 227 additions and 171 deletions.
2 changes: 2 additions & 0 deletions src/main/java/io/sobok/SobokSobok/SobokSobokApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableFeignClients
@EnableJpaAuditing
@EnableScheduling
public class SobokSobokApplication {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import io.sobok.SobokSobok.auth.domain.Role;
import io.sobok.SobokSobok.auth.domain.SocialInfo;
import io.sobok.SobokSobok.auth.domain.SocialType;
import io.sobok.SobokSobok.auth.domain.User;
import io.sobok.SobokSobok.auth.infrastructure.UserRepository;
import io.sobok.SobokSobok.auth.ui.dto.SocialLoginRequest;
Expand All @@ -12,7 +11,6 @@
import io.sobok.SobokSobok.exception.ErrorCode;
import io.sobok.SobokSobok.exception.model.ConflictException;
import io.sobok.SobokSobok.exception.model.NotFoundException;
import io.sobok.SobokSobok.external.kakao.KakaoService;
import io.sobok.SobokSobok.security.jwt.Jwt;
import io.sobok.SobokSobok.security.jwt.JwtProvider;
import lombok.RequiredArgsConstructor;
Expand All @@ -23,8 +21,6 @@
@RequiredArgsConstructor
public class SocialService {

private final KakaoService kakaoService;

private final UserRepository userRepository;

private final JwtProvider jwtProvider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
public record SocialLoginResponse(

String accessToken,

String refreshToken
String refreshToken,
Boolean isNew
) {
}
43 changes: 24 additions & 19 deletions src/main/java/io/sobok/SobokSobok/config/FCMConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import com.google.auth.oauth2.GoogleCredentials;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.messaging.FirebaseMessaging;
import com.google.firebase.messaging.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand All @@ -13,35 +14,39 @@
import java.io.InputStream;
import java.util.List;

@Slf4j
@Configuration
public class FCMConfig {

@Value("${firebase.admin-sdk}")
String adminSdkFileName;
@Value("${fcm.key.path}")
private String SERVICE_ACCOUNT_PATH;

@Bean
FirebaseMessaging firebaseMessaging() throws IOException {
ClassPathResource resource = new ClassPathResource("firebase/" + adminSdkFileName);
FirebaseMessaging firebaseMessaging() {
FirebaseApp firebaseApp = getOrCreateFirebaseApp();
return FirebaseMessaging.getInstance(firebaseApp);
}

InputStream refreshToken = resource.getInputStream();
private FirebaseApp getOrCreateFirebaseApp() {
List<FirebaseApp> firebaseApps = FirebaseApp.getApps();
return firebaseApps.stream()
.filter(fApp -> FirebaseApp.DEFAULT_APP_NAME.equals(fApp.getName()))
.findFirst()
.orElseGet(this::initializeFirebaseApp);
}

FirebaseApp firebaseApp = null;
List<FirebaseApp> firebaseAppList = FirebaseApp.getApps();

if (firebaseAppList != null && !firebaseAppList.isEmpty()) {
for (FirebaseApp app : firebaseAppList) {
if (app.getName().equals(FirebaseApp.DEFAULT_APP_NAME)) {
firebaseApp = app;
}
}
} else {
private FirebaseApp initializeFirebaseApp() {
try {
InputStream serviceAccount = new ClassPathResource(SERVICE_ACCOUNT_PATH).getInputStream();
FirebaseOptions options = FirebaseOptions.builder()
.setCredentials(GoogleCredentials.fromStream(refreshToken))
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.build();

firebaseApp = FirebaseApp.initializeApp(options);
return FirebaseApp.initializeApp(options);
} catch (IOException e) {
log.error("Firebase App 초기화에 실패했습니다.");
throw new IllegalArgumentException("Invalid firebase service account");
}

return FirebaseMessaging.getInstance(firebaseApp);
}
}
4 changes: 2 additions & 2 deletions src/main/java/io/sobok/SobokSobok/config/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import io.sobok.SobokSobok.security.filter.JwtCustomFilter;
import io.sobok.SobokSobok.security.jwt.JwtProvider;
import lombok.RequiredArgsConstructor;
//import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
Expand Down Expand Up @@ -50,7 +50,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
.headers(header -> header.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin))
.formLogin(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(request -> request
// .requestMatchers(PathRequest.toH2Console()).permitAll()
.requestMatchers(PathRequest.toH2Console()).permitAll()
.requestMatchers(
Stream
.of(WHITE_LIST)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

Expand All @@ -25,6 +27,22 @@ protected ResponseEntity<ApiResponse<Void>> handleHttpMessageNotReadableExceptio
);
}

@ExceptionHandler(MissingServletRequestParameterException.class)
protected ResponseEntity<ApiResponse<Void>> handleMissingServletRequestParameterException(final MissingServletRequestParameterException exception) {
return new ResponseEntity<>(
ApiResponse.error(ErrorCode.NOT_EXIST_PARAMETER),
HttpStatus.BAD_REQUEST
);
}

@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
protected ResponseEntity<ApiResponse<Void>> handleHttpRequestMethodNotSupportedException(final HttpRequestMethodNotSupportedException exception) {
return new ResponseEntity<>(
ApiResponse.error(ErrorCode.NOT_SUPPORTED_METHOD),
HttpStatus.BAD_REQUEST
);
}

/**
* external Error
*/
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/io/sobok/SobokSobok/exception/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
public enum ErrorCode {

// common
NOT_EXIST_PARAMETER(HttpStatus.BAD_REQUEST, "필수 파라미터 값이 없습니다."),
NOT_SUPPORTED_METHOD(HttpStatus.BAD_REQUEST, "사용할 수 없는 HTTP method입니다."),
INVALID_REQUEST_BODY(HttpStatus.BAD_REQUEST, "잘못된 Request body입니다."),
BAD_REQUEST_EXCEPTION(HttpStatus.BAD_REQUEST, "잘못된 형식의 요청입니다."),
FILE_SAVE_EXCEPTION(HttpStatus.INTERNAL_SERVER_ERROR, "파일 생성에 실패했습니다."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,45 +7,36 @@
import io.sobok.SobokSobok.auth.application.util.UserServiceUtil;
import io.sobok.SobokSobok.auth.domain.User;
import io.sobok.SobokSobok.auth.infrastructure.UserRepository;
import io.sobok.SobokSobok.exception.ErrorCode;
import io.sobok.SobokSobok.exception.model.NotFoundException;
import io.sobok.SobokSobok.external.firebase.dto.FCMNotificationRequest;
import io.sobok.SobokSobok.external.firebase.dto.PushNotificationRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
@Slf4j
public class FCMNotificationService {
public class FCMPushService {

private final FirebaseMessaging firebaseMessaging;

private final UserRepository userRepository;

public void sendNotificationByDeviceToken(FCMNotificationRequest request) {
public void sendNotificationByToken(PushNotificationRequest request) {

User user = UserServiceUtil.findUserById(userRepository, request.userId());

if (user.getDeviceToken() == null) {
throw new NotFoundException(ErrorCode.EMPTY_DEVICE_TOKEN);
}

Notification notification = Notification.builder()
.setTitle(request.title())
.setBody(request.body())
.setImage(request.image())
.build();

Message message = Message.builder()
.setToken(user.getDeviceToken())
.setNotification(notification)
.putAllData(request.data())
.build();

try {
firebaseMessaging.send(message);
} catch (FirebaseMessagingException e) {
log.error("푸시알림 전송에 실패했습니다. userId: " + user.getId() + "\n" + e.getMessage());;
throw new IllegalArgumentException("푸시알림 전송에 실패했습니다. userId: " + request.userId() + "\n" + e.getMessage());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
import java.util.Map;

@Builder
public record FCMNotificationRequest(
public record PushNotificationRequest(


Long userId,
String title,
Expand Down

This file was deleted.

41 changes: 0 additions & 41 deletions src/main/java/io/sobok/SobokSobok/external/kakao/KakaoService.java

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit fea0ec9

Please sign in to comment.