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

[Feat/#180-new-relic] new relic 설정 (테스트) #182

Closed
wants to merge 42 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
f45e4ce
Fix: 순간포착 게시물 업로드 #177
5jisoo Feb 9, 2025
7037b45
Fix: dockerfile 수정
dudrhy12 Feb 9, 2025
a20a07e
Fix: dockerfile 수정
dudrhy12 Feb 9, 2025
0040798
Fix: new relic 의존성 설정
dudrhy12 Feb 9, 2025
87de8c2
Fix: 명시적 의존성 추가
dudrhy12 Feb 9, 2025
af6e2f7
Fix: 권한 부여
dudrhy12 Feb 9, 2025
d181f53
Fix: script 수정
dudrhy12 Feb 9, 2025
d568da0
Feat: 순간 포착 알림 생성 #177
5jisoo Feb 9, 2025
4d3406d
Fix: 테스크 명시
dudrhy12 Feb 9, 2025
37b728e
feat: actuator, prometheus 의존성 추가 #179
yeahjinjeong Feb 9, 2025
d0bed8b
Feat: 순간 포착 알림 res dto
5jisoo Feb 10, 2025
e520f49
Docs: 순간포착 알림 문서화 #177
5jisoo Feb 10, 2025
4fdfae3
Fix: list type casting error 해결 #177
5jisoo Feb 10, 2025
28644af
Test: 순간포착 알림 전송 테스트 #177
5jisoo Feb 10, 2025
33836e1
[Feat/#179-prometheus-grafana] Prometheus 컨테이너 실행
yeahjinjeong Feb 11, 2025
fe54ecc
update: acuator properties #179
yeahjinjeong Feb 11, 2025
90a5019
Update dev-server.yml
yeahjinjeong Feb 11, 2025
96a8b45
Update dev-server.yml
yeahjinjeong Feb 11, 2025
741da69
Update dev-server.yml
yeahjinjeong Feb 11, 2025
8101e15
Update dev-server.yml
yeahjinjeong Feb 11, 2025
646e79f
Fix: 배포파일 수정
dudrhy12 Feb 11, 2025
e3af8d0
Typo: 들여쓰기 수정
dudrhy12 Feb 12, 2025
374cd61
Fix: 환경변수 설정
dudrhy12 Feb 12, 2025
87c8d76
Fix: 환경변수 설정
dudrhy12 Feb 12, 2025
35247b5
Fix: 트리거 설정
dudrhy12 Feb 12, 2025
f6830e0
Merge branch 'test/#180-new-relic-test' into feat/#180-new-relic
dudrhy12 Feb 12, 2025
4c596fe
Refactor: 이미지파일 저장방식 변경 #187
5jisoo Feb 12, 2025
8700552
Update Dockerfile
yeahjinjeong Feb 13, 2025
5864b5b
Fix: 포트번호 수정
dudrhy12 Feb 13, 2025
689bf16
Merge branch 'feat/#180-new-relic' of https://github.com/SMWU-POCHAK/…
dudrhy12 Feb 13, 2025
74785ba
Refactor: 중복 쿼리 호출 정리 #177
5jisoo Feb 15, 2025
723a72d
Refactor: 쿼리 호출 insert 1번으로 수정 #188
5jisoo Feb 15, 2025
d7174c6
Merge pull request #183 from SMWU-POCHAK/feat/#177-moment-post
5jisoo Feb 15, 2025
f07027c
Merge branch 'develop' into refactor/#187-image-url
5jisoo Feb 15, 2025
a2e0961
Update dev-server.yml
yeahjinjeong Feb 15, 2025
480bc5e
Merge pull request #184 from SMWU-POCHAK/feature/#179-prometheus-grafana
yeahjinjeong Feb 15, 2025
01eaece
Chore: merge conflict 해결 #187
5jisoo Feb 15, 2025
5a04efc
Merge pull request #188 from SMWU-POCHAK/refactor/#187-image-url
5jisoo Feb 15, 2025
3a14064
Fix: npe 발생 수정 #177
5jisoo Feb 15, 2025
ce1bd11
Merge pull request #191 from SMWU-POCHAK/hotfix/#177-npe-error
5jisoo Feb 15, 2025
cf2612f
Merge branch 'develop' into feat/#180-new-relic
dudrhy12 Feb 17, 2025
8d14523
Revert: yml 파일 원복
dudrhy12 Feb 17, 2025
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
9 changes: 2 additions & 7 deletions .github/workflows/dev-server.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,11 @@ name: dev server

env:
JASYPT_KEY: ${{ secrets.JASYPT_KEY }}
NEW_RELIC_LICENSE_KEY: ${{ secrets.NEW_RELIC_LICENSE_KEY }}

on:
push:
branches:
- develop
- test/#180-new-relic-test
pull_request:
branches:
- develop
- test/#180-new-relic-test
branches: [ develop ]

jobs:
build:
Expand Down
8 changes: 6 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
FROM openjdk:17-jdk
WORKDIR /app
COPY build/libs/*.jar app.jar
EXPOSE 3000
COPY newrelic/ /app/newrelic/
EXPOSE 5000

ARG SPRING_PROFILES_ACTIVE
ARG JASYPT_KEY
ARG NEW_RELIC_LICENSE_KEY

ENV SPRING_PROFILES_ACTIVE=${SPRING_PROFILES_ACTIVE:-DEV}
ENV JASYPT_KEY=${JASYPT_KEY:-pw}
ENV NEW_RELIC_LICENSE_KEY=${NEW_RELIC_LICENSE_KEY}

CMD java -javaagent:/newrelic/newrelic.jar -Duser.timezone=Asia/Seoul -jar app.jar

CMD java -javaagent:/app/newrelic/newrelic.jar -Duser.timezone=Asia/Seoul -jar app.jar
19 changes: 18 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
testImplementation("org.springframework.boot:spring-boot-starter-test") {
exclude group: "com.vaadin.external.google", module: "android-json"
}
Expand Down Expand Up @@ -77,6 +78,7 @@ dependencies {
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
runtimeOnly 'io.micrometer:micrometer-registry-prometheus'
testCompileOnly 'org.projectlombok:lombok:1.18.34'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.34'

Expand Down Expand Up @@ -141,7 +143,6 @@ bootJar {
dependsOn copyDocument
}

// -plain.jar 제거
jar {
enabled = false
}
Expand Down Expand Up @@ -206,4 +207,20 @@ sonarqube {
property "sonar.host.url", "https://sonarcloud.io"
property "sonar.login", "${System.getenv('SONAR_TOKEN')}"
}
}

tasks.named('compileJava') {
dependsOn unzipNewrelic
}
tasks.named('processResources') {
dependsOn unzipNewrelic
}
tasks.named('processTestResources') {
dependsOn unzipNewrelic
}
tasks.named('compileTestJava') {
dependsOn unzipNewrelic
}
tasks.named('test') {
dependsOn unzipNewrelic
}
3 changes: 3 additions & 0 deletions src/docs/asciidoc/alarm.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ include::{snippets}/get-alarms/query-parameters.adoc[]
|`TAG_APPROVAL`
|누군가 날 게시물에 태그했을 경우 (수락/거절 후 삭제되는 알람)

|`MOMENT_POST`
|내가 팔로우하고 있는 사람이 순간포착 게시물을 올렸을 경우

|===

include::{snippets}/get-alarms/response-body.adoc[]
Expand Down
6 changes: 6 additions & 0 deletions src/docs/asciidoc/post.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ include::{snippets}/get-search-tab/response-fields.adoc[]

include::{snippets}/upload-post/curl-request.adoc[]

- 순간 포착 게시물 (pinnedHandle 추가)
include::{snippets}/upload-moment-post/curl-request.adoc[]

==== request headers
include::{snippets}/upload-post/request-headers.adoc[]

Expand All @@ -66,6 +69,9 @@ include::{snippets}/upload-post/request-parts.adoc[]
==== query params
include::{snippets}/upload-post/query-parameters.adoc[]

- 순간포착 게시물의 경우, pinnedHandle 을 추가로 전달하면 됩니닷~
include::{snippets}/upload-moment-post/query-parameters.adoc[]

=== Response
==== response body
include::{snippets}/upload-post/response-body.adoc[]
Expand Down
2 changes: 1 addition & 1 deletion src/docs/asciidoc/tag.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ ifndef::snippets[]
:snippets: ./build/generated-snippets
endif::[]

== `GET` Approve Tag API
== `POST` Approve Tag API

게시물 수락 API

Expand Down
4 changes: 3 additions & 1 deletion src/main/java/com/apps/pochak/alarm/domain/AlarmType.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ public enum AlarmType {
FOLLOW("이제 친구를 포착해보세요!", "%s님이 회원님을 팔로우하였습니다.", "%s"),
TAGGED_LIKE("새로운 반응을 확인하세요!", "내가 포착된 게시물에 %s님이 좋아요를 눌렀습니다.", "%s"),
OWNER_LIKE("새로운 반응을 확인하세요!", "내 게시물에 %s님이 좋아요를 눌렀습니다.", "%s"),
TAG_APPROVAL("포착된 사진을 확인해보세요!", "%s님이 회원님을 포착했습니다.", "%s");
TAG_APPROVAL("포착된 사진을 확인해보세요!", "%s님이 회원님을 포착했습니다.", "%s"),
MOMENT_POST("새로운 순간, 포착!", "%s님과 %님이 서로를 순간 포착했습니다.", "%s"),
;

private final String title;
private final String body;
Expand Down
61 changes: 61 additions & 0 deletions src/main/java/com/apps/pochak/alarm/domain/PostAlarm.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.apps.pochak.alarm.domain;

import com.apps.pochak.member.domain.Member;
import com.apps.pochak.post.domain.Post;
import jakarta.persistence.Entity;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class PostAlarm extends Alarm {
private Long postId;
private String postImage;

private Long memberId;
private String memberHandle;
private String memberName;
private String memberProfileImage;

public PostAlarm(
final Long id,
final Post post,
final Member receiver,
final AlarmType alarmType
) {
super(id, receiver, alarmType, post.getOwner());
initializeFields(post);
}

public PostAlarm(
final Post post,
final Member receiver,
final AlarmType alarmType
) {
super(receiver, alarmType, post.getOwner());
initializeFields(post);
}

private void initializeFields(final Post post) {
this.postId = post.getId();
this.postImage = post.getPostImage();

Member pinnedMember = post.getPinnedMember();
this.memberId = pinnedMember.getId();
this.memberHandle = pinnedMember.getHandle();
this.memberName = pinnedMember.getName();
this.memberProfileImage = pinnedMember.getProfileImage();
}

@Override
public String getPushNotificationBody() {
return String.format(this.getAlarmType().getBody(), getSender().getName(), memberName);
}

@Override
public String getPushNotificationImage() {
return String.format(this.getAlarmType().getImage(), this.postImage);
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package com.apps.pochak.alarm.dto.response;

import com.apps.pochak.alarm.domain.*;
import com.apps.pochak.alarm.dto.response.alarm_element.CommentAlarmElement;
import com.apps.pochak.alarm.dto.response.alarm_element.FollowAlarmElement;
import com.apps.pochak.alarm.dto.response.alarm_element.LikeAlarmElement;
import com.apps.pochak.alarm.dto.response.alarm_element.TagApprovalAlarmElement;
import com.apps.pochak.alarm.dto.response.alarm_element.*;
import com.apps.pochak.global.util.PageInfo;
import lombok.AllArgsConstructor;
import lombok.Data;
Expand All @@ -31,6 +28,8 @@ public AlarmElements(final Page<Alarm> alarmPage) {
return new CommentAlarmElement((CommentAlarm) alarm);
} else if (alarm instanceof TagAlarm) {
return new TagApprovalAlarmElement((TagAlarm) alarm);
} else if (alarm instanceof PostAlarm) {
return new PostAlarmElement((PostAlarm) alarm);
} else { // like alarm
return new LikeAlarmElement((LikeAlarm) alarm);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.apps.pochak.alarm.dto.response.alarm_element;

import com.apps.pochak.alarm.domain.PostAlarm;
import com.apps.pochak.alarm.dto.response.AlarmElement;
import com.apps.pochak.member.domain.Member;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class PostAlarmElement extends AlarmElement {
private Long ownerId;
private String ownerHandle;
private String ownerName;
private String ownerProfileImage;

private Long memberId;
private String memberHandle;
private String memberName;
private String memberProfileImage;

private Long postId;
private String postImage;

public PostAlarmElement(final PostAlarm alarm) {
super(alarm);
Member sender = alarm.getSender();
this.ownerId = sender.getId();
this.ownerHandle = sender.getHandle();
this.ownerName = sender.getName();
this.ownerProfileImage = sender.getProfileImage();

this.memberId = alarm.getMemberId();
this.memberHandle = alarm.getMemberHandle();
this.memberName = alarm.getMemberName();
this.memberProfileImage = alarm.getMemberProfileImage();

this.postId = alarm.getPostId();
this.postImage = alarm.getPostImage();
}
}
45 changes: 45 additions & 0 deletions src/main/java/com/apps/pochak/alarm/service/PostAlarmService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.apps.pochak.alarm.service;

import com.apps.pochak.alarm.domain.Alarm;
import com.apps.pochak.alarm.domain.AlarmType;
import com.apps.pochak.alarm.domain.PostAlarm;
import com.apps.pochak.alarm.domain.repository.AlarmRepository;
import com.apps.pochak.fcm.service.FCMService;
import com.apps.pochak.follow.domain.Follow;
import com.apps.pochak.follow.domain.repository.FollowRepository;
import com.apps.pochak.post.domain.Post;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

import static com.apps.pochak.global.Constant.DEFAULT_DELETION_SIZE;

@Service
@RequiredArgsConstructor
public class PostAlarmService {
private final AlarmRepository alarmRepository;
private final FollowRepository followRepository;
private final FCMService fcmService;

public void saveMomentPostAlarm(final Post post) {
PageRequest pageRequest = PageRequest.of(0, DEFAULT_DELETION_SIZE);
Page<Follow> commonFollowers;
do {
commonFollowers = followRepository.findCommonFollowers(
post.getOwner(),
post.getPinnedMember(),
pageRequest
);
List<PostAlarm> alarmList = commonFollowers.getContent().stream().map(
f -> new PostAlarm(post, f.getSender(), AlarmType.MOMENT_POST)
).toList();
alarmRepository.saveAll(alarmList);
fcmService.sendPushNotification(new ArrayList<Alarm>(alarmList));
pageRequest = pageRequest.next();
} while (commonFollowers.hasNext());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
import com.apps.pochak.follow.domain.Follow;
import com.apps.pochak.global.api_payload.exception.GeneralException;
import com.apps.pochak.member.domain.Member;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;
import java.util.Optional;

import static com.apps.pochak.global.api_payload.code.status.ErrorStatus.NOT_FOLLOW;
Expand All @@ -33,6 +36,20 @@ default Follow findBySenderAndReceiver(final Member sender, final Member receive
return findFollowBySenderAndReceiver(sender, receiver).orElseThrow(() -> new GeneralException(NOT_FOLLOW));
}

@Query("""
select f from Follow f
join fetch f.sender
where f.receiver = :A
and f.sender in (
select f2.sender from Follow f2
where f2.receiver = :B)
""")
Page<Follow> findCommonFollowers(
@Param("A") final Member memberA,
@Param("B") final Member memberB,
final Pageable pageable
);

@Modifying(clearAutomatically = true)
@Query("""
update Follow f
Expand Down
1 change: 1 addition & 0 deletions src/main/java/com/apps/pochak/global/Constant.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ public class Constant {

public static final int DEFAULT_PAGING_SIZE = 30;
public static final int COMMENT_PAGING_SIZE = 10;
public static final int DEFAULT_DELETION_SIZE = 100;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
public class ValidDuplicateListValidator implements ConstraintValidator<ValidDuplicateList, List<String>> {
@Override
public boolean isValid(final List<String> stringList, final ConstraintValidatorContext constraintValidatorContext) {
if (stringList == null) return true;
final long uniqueCount = stringList.stream().distinct().count();
return uniqueCount == stringList.size();
}
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/com/apps/pochak/global/config/AsyncConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.apps.pochak.global.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

@EnableAsync
@Configuration
public class AsyncConfig implements AsyncConfigurer {
@Bean
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
return executor;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

import static com.apps.pochak.global.api_payload.code.status.ErrorStatus.*;

Expand All @@ -30,11 +29,12 @@ public class CloudStorageService {

public String upload(
final MultipartFile multipartFile,
final DirName dirName
final DirName dirName,
final String subject
) {
if (multipartFile.isEmpty()) throw new GeneralException(NULL_FILE);

String objectName = dirName.getDirName() + "/" + UUID.randomUUID() + "_" + multipartFile.getOriginalFilename();
String objectName = dirName.getDirName() + "/" + subject;
String contentType = multipartFile.getContentType();

try {
Expand Down
Loading
Loading