From f720bcda572744b79bfafbf240d8295a6f93da1c Mon Sep 17 00:00:00 2001 From: bellmin Date: Sat, 4 Jan 2025 20:53:47 +0900 Subject: [PATCH 001/138] =?UTF-8?q?refactor(api):=20Exception=20=EC=BB=A8?= =?UTF-8?q?=EB=B2=A4=EC=85=98=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 개발자가 실수 : IllegalStateException - 사용자가 실수 : IllegalArgumentException --- .../java/com/whoz_in/domain/member/model/AccountType.java | 2 +- .../java/com/whoz_in/domain/member/model/SocialProvider.java | 2 +- .../oauth2/CustomOAuth2AccessTokenResponseClient.java | 2 +- .../whoz_in/main_api/shared/utils/OAuth2UserInfoStore.java | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/domain/src/main/java/com/whoz_in/domain/member/model/AccountType.java b/modules/domain/src/main/java/com/whoz_in/domain/member/model/AccountType.java index cb7bb754..a4ad6566 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/member/model/AccountType.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/member/model/AccountType.java @@ -17,7 +17,7 @@ public static AccountType findAccountType(String accountType){ return Arrays.stream(AccountType.values()) .filter(at -> at.name().equals(accountType)) .findFirst() - .orElseThrow(() -> new IllegalArgumentException("no account type")); + .orElseThrow(() -> new IllegalStateException("no account type")); } } diff --git a/modules/domain/src/main/java/com/whoz_in/domain/member/model/SocialProvider.java b/modules/domain/src/main/java/com/whoz_in/domain/member/model/SocialProvider.java index db51f754..e903f128 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/member/model/SocialProvider.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/member/model/SocialProvider.java @@ -19,7 +19,7 @@ public static SocialProvider findSocialProvider(String socialProvider){ return Arrays.stream(SocialProvider.values()) .filter(provider -> provider.getProviderName().equals(socialProvider)) .findFirst() - .orElseThrow(() -> new IllegalArgumentException("no social provider")); + .orElseThrow(() -> new IllegalStateException("no social provider")); } } diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/oauth2/CustomOAuth2AccessTokenResponseClient.java b/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/oauth2/CustomOAuth2AccessTokenResponseClient.java index e4ad8e1f..72f9a3ad 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/oauth2/CustomOAuth2AccessTokenResponseClient.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/oauth2/CustomOAuth2AccessTokenResponseClient.java @@ -51,7 +51,7 @@ public OAuth2AccessTokenResponse getTokenResponse(OAuth2AuthorizationCodeGrantRe private OAuth2AccessTokenResponse handle(String registrationId, Map tokenResponse) { if(registrationId==null){ - throw new IllegalArgumentException("등록되지 않은 OAuth 제공자"); + throw new IllegalStateException("등록되지 않은 OAuth 제공자"); } // TODO: OAuth Provider 가 많아지면 Switch-Case 로 가능 diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/utils/OAuth2UserInfoStore.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/utils/OAuth2UserInfoStore.java index 0eefdf5a..3e730a3f 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/utils/OAuth2UserInfoStore.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/utils/OAuth2UserInfoStore.java @@ -65,7 +65,7 @@ public static void ensureNotExpired(String hashedKey){ long expiredTime = Long.parseLong(hashedKey.split(OAUTH2_TOKEN_KEY_DELIMITER)[1]); if (Instant.now().getEpochSecond() > expiredTime) - throw new IllegalArgumentException("만료된 Social Id Key"); + throw new IllegalArgumentException("만료된 UserInfo Key"); } public static void ensureCorrectKey(String unknownKey){ @@ -113,7 +113,7 @@ private String hashing(OAuth2UserInfo userInfo, long expiredTime){ return hexString.toString(); } catch (NoSuchAlgorithmException e){ - throw new IllegalArgumentException("존재하지 않는 알고리즘"); + throw new IllegalStateException("존재하지 않는 알고리즘"); } } From fd9aeaec79aff41bfb5de7de7af09f64bdb42eac Mon Sep 17 00:00:00 2001 From: bellmin Date: Sun, 5 Jan 2025 18:05:52 +0900 Subject: [PATCH 002/138] =?UTF-8?q?feat(domain):=20Active=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=EC=9D=B8=20Device=EC=97=90=20=EA=B4=80=EB=A0=A8?= =?UTF-8?q?=EB=90=9C=20=EC=9D=B8=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ActiveDeviceFinder : Active 상태인 Device를 판별하고 찾는 역할 - ActiveDeviceRepository : Active 상태인 Device를 저장하는 역할 - ActiveTimeCalculator : Active 상태와 관련된 시간을 계산하는 역할 --- .../device/active/ActiveDeviceFinder.java | 12 +++++++++ .../device/active/ActiveDeviceRepository.java | 27 +++++++++++++++++++ .../device/active/ActiveTimeCalculator.java | 12 +++++++++ 3 files changed, 51 insertions(+) create mode 100644 modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveDeviceFinder.java create mode 100644 modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveDeviceRepository.java create mode 100644 modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveTimeCalculator.java diff --git a/modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveDeviceFinder.java b/modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveDeviceFinder.java new file mode 100644 index 00000000..bb729514 --- /dev/null +++ b/modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveDeviceFinder.java @@ -0,0 +1,12 @@ +package com.whoz_in.domain.device.active; + +/** + * 주기적으로 Active 상태인 Device 들을 찾는 친구 + * void find() : Active 상태인 Device 를 찾아서 ActiveDeviceRepository 에 저장 + * Active 상태인지 판별하는 로직이 들어가 있다. + */ +public interface ActiveDeviceFinder { + + void find(); + +} diff --git a/modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveDeviceRepository.java b/modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveDeviceRepository.java new file mode 100644 index 00000000..f34ac73f --- /dev/null +++ b/modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveDeviceRepository.java @@ -0,0 +1,27 @@ +package com.whoz_in.domain.device.active; + +import com.whoz_in.domain.device.model.Device; +import com.whoz_in.domain.device.model.DeviceId; +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +/** + * 구현에 따라 달라지므로 interface + * 일반 DeviceRepository 와 역할이 너무 비슷한가? + * ActiveDeviceRepository 의 역할 + * 1. Active 상태인 Device 들을 저장한다. (내부 구현은 동시성 문제를 해결해야 한다.) + * 2. Active 상태인 Device 들을 조회한다. + */ +public interface ActiveDeviceRepository { + + List findAll(); + Optional findByDeviceId(DeviceId deviceId); + boolean existsByDeviceId(DeviceId deviceId); + void deleteByDeviceId(DeviceId deviceId); + void save(Device device); + void saveAll(Collection devices); + default List getAll(){ return findAll(); } + default Optional get(DeviceId deviceId){ return findByDeviceId(deviceId); } + +} diff --git a/modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveTimeCalculator.java b/modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveTimeCalculator.java new file mode 100644 index 00000000..fae66364 --- /dev/null +++ b/modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveTimeCalculator.java @@ -0,0 +1,12 @@ +package com.whoz_in.domain.device.active; + + +/** + * Active 상태인 Device 들의 누적 접속 시간, 연속 접속 시간을 계산한다. + */ +public interface ActiveTimeCalculator { + + void calculateContinuousTime(); + void calculateTotalTime(); + +} From e186fe57b7f0a45ce475d57e0f94ba4830ec5e09 Mon Sep 17 00:00:00 2001 From: bellmin Date: Sun, 5 Jan 2025 19:45:22 +0900 Subject: [PATCH 003/138] =?UTF-8?q?feat(main-api):=20application=20Event?= =?UTF-8?q?=20=EA=B4=80=EB=A0=A8=20=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Events : 이벤트 관련 static 유틸 - EventConfiguration : 이벤트와 관련된 설정 클래스 - Event : 이벤트의 최상위 계층 인터페이스 --- .../whoz_in/main_api/shared/event/Event.java | 4 ++++ .../shared/event/EventConfiguration.java | 17 +++++++++++++++++ .../whoz_in/main_api/shared/event/Events.java | 19 +++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/shared/event/Event.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/shared/event/EventConfiguration.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/shared/event/Events.java diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/event/Event.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/event/Event.java new file mode 100644 index 00000000..b525dd72 --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/event/Event.java @@ -0,0 +1,4 @@ +package com.whoz_in.main_api.shared.event; + +public interface Event { +} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/event/EventConfiguration.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/event/EventConfiguration.java new file mode 100644 index 00000000..08f7b7fd --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/event/EventConfiguration.java @@ -0,0 +1,17 @@ +package com.whoz_in.main_api.shared.event; + +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@RequiredArgsConstructor +public class EventConfiguration { + + private final ApplicationEventPublisher publisher; + @Bean + public InitializingBean eventInitializer(){return () -> Events.setEventPublisher(publisher);}; + +} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/event/Events.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/event/Events.java new file mode 100644 index 00000000..c320c58b --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/event/Events.java @@ -0,0 +1,19 @@ +package com.whoz_in.main_api.shared.event; + +import org.springframework.context.ApplicationEventPublisher; + +public class Events { + + private static ApplicationEventPublisher publisher; + + static void setEventPublisher(ApplicationEventPublisher context) { + publisher = context; + } + + public static void raise(Event event) { + if(publisher!=null) + publisher.publishEvent(event); + } + + +} From 5094c78373b523a6e839c700b55afc8e508501a4 Mon Sep 17 00:00:00 2001 From: bellmin Date: Sun, 5 Jan 2025 21:08:00 +0900 Subject: [PATCH 004/138] =?UTF-8?q?feat(main-api):=20ActiveDevice=20?= =?UTF-8?q?=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ActiveDeviceFinded : ActiveDevice를 찾은 이벤트 - ActiveDeviceEventHandler : ActiveDevice와 관련된 이벤트를 처리하는 핸들러 --- .../event/ActiveDeviceEventHandler.java | 23 +++++++++++++++++++ .../active/event/ActiveDeviceFinded.java | 22 ++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/event/ActiveDeviceEventHandler.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/event/ActiveDeviceFinded.java diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/event/ActiveDeviceEventHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/event/ActiveDeviceEventHandler.java new file mode 100644 index 00000000..5c62ab33 --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/event/ActiveDeviceEventHandler.java @@ -0,0 +1,23 @@ +package com.whoz_in.main_api.shared.domain.device.active.event; + +import com.whoz_in.domain.device.active.ActiveDeviceRepository; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +@Component +public class ActiveDeviceEventHandler { + + private final ActiveDeviceRepository repository; + + public ActiveDeviceEventHandler(ActiveDeviceRepository repository){ + this.repository = repository; + } + + @Async + @EventListener(ActiveDeviceFinded.class) + public void onActiveDeviceFinded(ActiveDeviceFinded event) { + repository.saveAll(event.getDevices()); + } + +} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/event/ActiveDeviceFinded.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/event/ActiveDeviceFinded.java new file mode 100644 index 00000000..6fd0d6dc --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/event/ActiveDeviceFinded.java @@ -0,0 +1,22 @@ +package com.whoz_in.main_api.shared.domain.device.active.event; + +import com.whoz_in.domain.device.model.Device; +import com.whoz_in.main_api.shared.event.Event; +import java.util.List; +import lombok.Getter; + +@Getter +public class ActiveDeviceFinded implements Event { + + private final List devices; + + public ActiveDeviceFinded(List devices) { + this.devices = devices; + } + + public static ActiveDeviceFinded of(List devices) { + return new ActiveDeviceFinded(devices); + } + + +} From 072c6a1e71bca8a716067d1ab3bdfb0ec7c1197a Mon Sep 17 00:00:00 2001 From: bellmin Date: Sun, 5 Jan 2025 21:27:07 +0900 Subject: [PATCH 005/138] =?UTF-8?q?feat(main-api):=20DeviceRepository=20?= =?UTF-8?q?=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - findAll 메소드 추가 --- .../java/com/whoz_in/domain/device/DeviceRepository.java | 2 ++ .../com/whoz_in/domain_jpa/device/DeviceJpaRepository.java | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/modules/domain/src/main/java/com/whoz_in/domain/device/DeviceRepository.java b/modules/domain/src/main/java/com/whoz_in/domain/device/DeviceRepository.java index 63a09745..d15bc9ad 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/device/DeviceRepository.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/device/DeviceRepository.java @@ -1,7 +1,9 @@ package com.whoz_in.domain.device; import com.whoz_in.domain.device.model.Device; +import java.util.List; public interface DeviceRepository { void save(Device device); + List findAll(); } diff --git a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceJpaRepository.java b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceJpaRepository.java index 1abad2bb..9791e563 100644 --- a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceJpaRepository.java +++ b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceJpaRepository.java @@ -2,6 +2,7 @@ import com.whoz_in.domain.device.DeviceRepository; import com.whoz_in.domain.device.model.Device; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; @@ -14,4 +15,9 @@ public class DeviceJpaRepository implements DeviceRepository { public void save(Device device) { repository.save(converter.from(device)); } + + @Override + public List findAll() { + return repository.findAll().stream().map(converter::to).toList(); + } } From 7616d720e0b255670dabb9be50defe4a4d63cb37 Mon Sep 17 00:00:00 2001 From: bellmin Date: Sun, 5 Jan 2025 21:47:01 +0900 Subject: [PATCH 006/138] =?UTF-8?q?feat(main-api):=20ActiveDevice=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20Response=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ActiveDeviceListResponse : Active 상태인 기기들 정보의 응답 - ActiveDeviceResponse : Active 상태인 기기 정보의 응답 --- .../device/application/ActiveDeviceListResponse.java | 9 +++++++++ .../device/application/ActiveDeviceResponse.java | 12 ++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDeviceListResponse.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDeviceResponse.java diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDeviceListResponse.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDeviceListResponse.java new file mode 100644 index 00000000..94a4b6a1 --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDeviceListResponse.java @@ -0,0 +1,9 @@ +package com.whoz_in.main_api.query.device.application; + +import com.whoz_in.main_api.query.shared.application.Response; +import java.util.List; + +public record ActiveDeviceListResponse( + List responses +) implements Response { +} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDeviceResponse.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDeviceResponse.java new file mode 100644 index 00000000..0bbc7295 --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDeviceResponse.java @@ -0,0 +1,12 @@ +package com.whoz_in.main_api.query.device.application; + +import com.whoz_in.main_api.query.shared.application.Response; + +public record ActiveDeviceResponse( + String deviceId, + String memberId, + String memberName, + String continuousActiveTime, + String totalActiveTime +) implements Response { +} From fe19d03a6532d8505de1f0427d35d4366af9aefa Mon Sep 17 00:00:00 2001 From: bellmin Date: Sun, 5 Jan 2025 23:04:26 +0900 Subject: [PATCH 007/138] =?UTF-8?q?feat(api-query-jpa):=20Device=20?= =?UTF-8?q?=EC=97=94=ED=8B=B0=ED=8B=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - DeviceRepository 추가 - Device 엔티티 추가 (임시) --- .../whoz_in/api_query_jpa/device/Device.java | 27 +++++++++++++++++++ .../device/DeviceRepository.java | 11 ++++++++ 2 files changed, 38 insertions(+) create mode 100644 modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/Device.java create mode 100644 modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceRepository.java diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/Device.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/Device.java new file mode 100644 index 00000000..83aebcef --- /dev/null +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/Device.java @@ -0,0 +1,27 @@ +package com.whoz_in.api_query_jpa.device; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import java.util.UUID; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.Immutable; +import org.hibernate.annotations.Subselect; + +@Entity +@Getter +@Subselect("SELECT " + + "device.id as deviceId, " + + "device.memberId as onwer " + + "FROM DeviceEntity device " +) +@Immutable +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Device { + + @Id + private UUID deviceId; + private UUID memberId; + +} diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceRepository.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceRepository.java new file mode 100644 index 00000000..f7963222 --- /dev/null +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceRepository.java @@ -0,0 +1,11 @@ +package com.whoz_in.api_query_jpa.device; + +import java.util.Optional; +import java.util.UUID; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface DeviceRepository extends JpaRepository { + + Optional findByDeviceId(UUID deviceId); + +} From 9f6498ee2c55ba6e4f77b0552557c7867ae7c2a8 Mon Sep 17 00:00:00 2001 From: bellmin Date: Sun, 5 Jan 2025 23:37:16 +0900 Subject: [PATCH 008/138] =?UTF-8?q?feat(api-query-jpa):=20MemberRepository?= =?UTF-8?q?=20=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - device의 주인을 찾는 메소드 - device들의 주인을 찾는 메소드 --- .../whoz_in/api_query_jpa/member/MemberRepository.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/member/MemberRepository.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/member/MemberRepository.java index 2e975529..e73aef95 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/member/MemberRepository.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/member/MemberRepository.java @@ -1,11 +1,20 @@ package com.whoz_in.api_query_jpa.member; +import java.util.List; import java.util.Optional; import java.util.UUID; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; @Repository public interface MemberRepository extends JpaRepository { Optional findByLoginId(String loginId); + Optional findByMemberId(UUID memberId); + + @Query("SELECT m FROM Member m WHERE m.id IN (SELECT d.memberId FROM Device d WHERE d.deviceId = :deviceId)") + Optional findByDeviceId(UUID deviceId); + + @Query("SELECT m FROM Member m WHERE m.id IN (SELECT d.memberId FROM Device d WHERE d.deviceId IN (:deviceIds))") + List findByDeviceIds(List deviceIds); } From 653405704ccfa33dfec5d57c6d5e45535caf00d5 Mon Sep 17 00:00:00 2001 From: bellmin Date: Sun, 5 Jan 2025 23:40:29 +0900 Subject: [PATCH 009/138] =?UTF-8?q?feat(api-query-jpa):=20activeDevice=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=EB=90=9C=20view=20,=20viewer=20=EC=A0=95?= =?UTF-8?q?=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ActiveDeviceViewer : query DB에서 ActiveDevice 를 조회하는 Viewer - ActiveDevice : query DB에서 조회한 ActiveDevice 클래스 --- .../query/device/application/ActiveDevice.java | 14 ++++++++++++++ .../device/application/ActiveDeviceViewer.java | 15 +++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDevice.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDeviceViewer.java diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDevice.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDevice.java new file mode 100644 index 00000000..cf001ede --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDevice.java @@ -0,0 +1,14 @@ +package com.whoz_in.main_api.query.device.application; + +import com.whoz_in.main_api.query.shared.application.View; +import java.time.LocalDateTime; +import java.util.UUID; + +// Active 상태인 기기를 나타내는 View +// 접속 시작 시간, 접속 종료 시간 +public record ActiveDevice( + UUID deviceId, + UUID memberId, + LocalDateTime connectedTime, + LocalDateTime disconnectedTime +) implements View { } diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDeviceViewer.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDeviceViewer.java new file mode 100644 index 00000000..d5cea902 --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDeviceViewer.java @@ -0,0 +1,15 @@ +package com.whoz_in.main_api.query.device.application; + +import com.whoz_in.main_api.query.shared.application.Viewer; +import java.util.List; +import java.util.Optional; + +public interface ActiveDeviceViewer extends Viewer { + + Optional findByDeviceId(String deviceId); + List findAll(); + default ActiveDevice getByDeviceId(String deviceId) { + return findByDeviceId(deviceId).orElseThrow(()->new IllegalArgumentException("No ActiveDevice Find")); + } + +} From d1bbb6cbcdcd6a33a7b3fadc5ce0a83fcec427a9 Mon Sep 17 00:00:00 2001 From: bellmin Date: Sun, 5 Jan 2025 23:50:57 +0900 Subject: [PATCH 010/138] =?UTF-8?q?delete(main-api):=20main=20api=EC=97=90?= =?UTF-8?q?=20=EC=9E=88=EB=8A=94=20ActiveDeviceEventHandler=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../event/ActiveDeviceEventHandler.java | 23 ------------------- 1 file changed, 23 deletions(-) delete mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/event/ActiveDeviceEventHandler.java diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/event/ActiveDeviceEventHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/event/ActiveDeviceEventHandler.java deleted file mode 100644 index 5c62ab33..00000000 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/event/ActiveDeviceEventHandler.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.whoz_in.main_api.shared.domain.device.active.event; - -import com.whoz_in.domain.device.active.ActiveDeviceRepository; -import org.springframework.context.event.EventListener; -import org.springframework.scheduling.annotation.Async; -import org.springframework.stereotype.Component; - -@Component -public class ActiveDeviceEventHandler { - - private final ActiveDeviceRepository repository; - - public ActiveDeviceEventHandler(ActiveDeviceRepository repository){ - this.repository = repository; - } - - @Async - @EventListener(ActiveDeviceFinded.class) - public void onActiveDeviceFinded(ActiveDeviceFinded event) { - repository.saveAll(event.getDevices()); - } - -} From a0a4370f004999d32e646f6eedf80a7f2324bd08 Mon Sep 17 00:00:00 2001 From: bellmin Date: Sun, 5 Jan 2025 23:51:38 +0900 Subject: [PATCH 011/138] =?UTF-8?q?feat(api-query-jpa):=20api-query-jpa=20?= =?UTF-8?q?=EB=AA=A8=EB=93=88=EC=97=90=20ActiveDeviceEventHandler=20?= =?UTF-8?q?=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../event/ActiveDeviceEventHandler.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java new file mode 100644 index 00000000..77653e09 --- /dev/null +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java @@ -0,0 +1,29 @@ +package com.whoz_in.api_query_jpa.device.event; + +import com.whoz_in.api_query_jpa.device.ActiveDeviceEntity; +import com.whoz_in.api_query_jpa.device.ActiveDeviceRepository; +import com.whoz_in.domain.device.model.Device; +import com.whoz_in.main_api.shared.domain.device.active.event.ActiveDeviceFinded; +import java.time.LocalDateTime; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class ActiveDeviceEventHandler { + + private final ActiveDeviceRepository activeDeviceRepository; + + @EventListener(ActiveDeviceFinded.class) + public void handle(ActiveDeviceFinded event) { + List devices = event.getDevices(); + List entities = devices.stream() + .map(device -> ActiveDeviceEntity.create(device.getId(), LocalDateTime.now())) // TODO: active Time 을 이 시점으로 설정해도 될까? + .toList(); + + activeDeviceRepository.saveAll(entities); + } + +} From 8ddc7e0e5a978cdca4319e1c128afdec565c1517 Mon Sep 17 00:00:00 2001 From: bellmin Date: Sun, 5 Jan 2025 23:53:16 +0900 Subject: [PATCH 012/138] =?UTF-8?q?feat(api-query-jpa):=20ActiveDeviceEnti?= =?UTF-8?q?ty=20=EC=A0=95=EC=9D=98=20=EB=B0=8F=20=EB=A0=88=ED=8F=AC?= =?UTF-8?q?=EC=A7=80=ED=86=A0=EB=A6=AC=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - api-query-jpa 모듈에서 사용할 조회용 엔티티 --- .../device/ActiveDeviceEntity.java | 47 +++++++++++++++++++ .../device/ActiveDeviceRepository.java | 11 +++++ 2 files changed, 58 insertions(+) create mode 100644 modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java create mode 100644 modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceRepository.java diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java new file mode 100644 index 00000000..0cee9ba5 --- /dev/null +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java @@ -0,0 +1,47 @@ +package com.whoz_in.api_query_jpa.device; + +import com.whoz_in.domain.device.model.DeviceId; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import java.time.Duration; +import java.time.LocalDateTime; +import java.util.UUID; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ActiveDeviceEntity { + + @Id + private UUID deviceId; + + @Column(nullable = false) + private LocalDateTime activeTime; + + private LocalDateTime inactiveTime; + + private Duration totalActiveTime; + + private ActiveDeviceEntity(UUID deviceId, LocalDateTime activeTime) { + this.deviceId = deviceId; + this.activeTime = activeTime; + } + + public void activeOn(LocalDateTime activeTime){ + this.activeTime = activeTime; + } + + public void isActiveOn(LocalDateTime inactiveTime){ + this.inactiveTime = inactiveTime; + this.totalActiveTime = Duration.between(this.activeTime, this.inactiveTime); + } + + public static ActiveDeviceEntity create(DeviceId deviceId, LocalDateTime activeTime){ + return new ActiveDeviceEntity(deviceId.id(), activeTime); + } + +} diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceRepository.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceRepository.java new file mode 100644 index 00000000..eb515de8 --- /dev/null +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceRepository.java @@ -0,0 +1,11 @@ +package com.whoz_in.api_query_jpa.device; + +import java.util.Optional; +import java.util.UUID; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ActiveDeviceRepository extends JpaRepository { + + Optional findByDeviceId(UUID deviceId); + +} From 3e48fe1dceb3374acc82f9e799bc3ae5a40ed297 Mon Sep 17 00:00:00 2001 From: bellmin Date: Sun, 5 Jan 2025 23:56:12 +0900 Subject: [PATCH 013/138] =?UTF-8?q?feat(api-query-jpa):=20ActiveDeviceJpaV?= =?UTF-8?q?iewer=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - main api 모듈의 ActiveDeviceViewer 구현체 --- .../device/ActiveDeviceJpaViewer.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java new file mode 100644 index 00000000..711fa5d9 --- /dev/null +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java @@ -0,0 +1,56 @@ +package com.whoz_in.api_query_jpa.device; + +import com.whoz_in.api_query_jpa.member.Member; +import com.whoz_in.api_query_jpa.member.MemberRepository; +import com.whoz_in.main_api.query.device.application.ActiveDevice; +import com.whoz_in.main_api.query.device.application.ActiveDeviceViewer; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class ActiveDeviceJpaViewer implements ActiveDeviceViewer { + + private final ActiveDeviceRepository activeDeviceRepository; + private final DeviceRepository deviceRepository; + private final MemberRepository memberRepository; + + @Override + public Optional findByDeviceId(String deviceId) { + ActiveDeviceEntity activeDevice = activeDeviceRepository.findByDeviceId(UUID.fromString(deviceId)).orElse(null); + Member member = memberRepository.findByDeviceId(UUID.fromString(deviceId)).orElse(null); + + if(member == null || activeDevice == null) return Optional.empty(); + + return createOptionalActiveDevice(activeDevice, member); + } + + @Override + public List findAll() { + List entities = activeDeviceRepository.findAll(); + List deviceIds = entities.stream().map(ActiveDeviceEntity::getDeviceId).toList(); + List devices = deviceRepository.findAll(); + List members = memberRepository.findByDeviceIds(deviceIds); + + return entities.stream() + .map(entity-> { + Device device = devices.stream().filter(d -> d.getDeviceId().equals(entity.getDeviceId())).findFirst().orElse(null); + if(device == null) return null; + Member member = members.stream().filter(m -> m.getId().equals(device.getMemberId())).findFirst().orElse(null); + if (member == null) return null; + return createOptionalActiveDevice(entity, member).orElse(null); + }) + .toList(); + } + + private Optional createOptionalActiveDevice(ActiveDeviceEntity entity, Member member){ + return Optional.of(new ActiveDevice( + entity.getDeviceId(), + member.getId(), + entity.getActiveTime(), + entity.getInactiveTime())); + } +} From 0164825774777e090566d7cb10d1aec79a7a0a6c Mon Sep 17 00:00:00 2001 From: bellmin Date: Mon, 6 Jan 2025 19:52:13 +0900 Subject: [PATCH 014/138] =?UTF-8?q?refactor(main-api):=20device/active=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/active/ActiveDevice.java | 14 ++++++++++++ .../application/active/ActiveDeviceList.java | 10 +++++++++ .../active/ActiveDeviceListResponse.java | 9 ++++++++ .../active/ActiveDeviceResponse.java | 12 ++++++++++ .../active/ActiveDeviceViewer.java | 15 +++++++++++++ .../active/event/ActiveDeviceFinded.java | 22 +++++++++++++++++++ 6 files changed, 82 insertions(+) create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceList.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListResponse.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceResponse.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceViewer.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/event/ActiveDeviceFinded.java diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java new file mode 100644 index 00000000..45e28789 --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java @@ -0,0 +1,14 @@ +package com.whoz_in.main_api.query.device.application.active; + +import com.whoz_in.main_api.query.shared.application.View; +import java.time.LocalDateTime; +import java.util.UUID; + +// Active 상태인 기기를 나타내는 View +// 접속 시작 시간, 접속 종료 시간 +public record ActiveDevice( + UUID deviceId, + UUID memberId, + LocalDateTime connectedTime, + LocalDateTime disconnectedTime +) implements View { } diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceList.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceList.java new file mode 100644 index 00000000..422aa46a --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceList.java @@ -0,0 +1,10 @@ +package com.whoz_in.main_api.query.device.application.active; + +import com.whoz_in.main_api.query.shared.application.Query; + +public record ActiveDeviceList( + int page, + int size, + String sortType +) implements Query { +} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListResponse.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListResponse.java new file mode 100644 index 00000000..a38ef436 --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListResponse.java @@ -0,0 +1,9 @@ +package com.whoz_in.main_api.query.device.application.active; + +import com.whoz_in.main_api.query.shared.application.Response; +import java.util.List; + +public record ActiveDeviceListResponse( + List responses +) implements Response { +} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceResponse.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceResponse.java new file mode 100644 index 00000000..3f3bc057 --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceResponse.java @@ -0,0 +1,12 @@ +package com.whoz_in.main_api.query.device.application.active; + +import com.whoz_in.main_api.query.shared.application.Response; + +public record ActiveDeviceResponse( + String deviceId, + String memberId, + String memberName, + String continuousActiveTime, + String totalActiveTime +) implements Response { +} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceViewer.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceViewer.java new file mode 100644 index 00000000..28ed2023 --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceViewer.java @@ -0,0 +1,15 @@ +package com.whoz_in.main_api.query.device.application.active; + +import com.whoz_in.main_api.query.shared.application.Viewer; +import java.util.List; +import java.util.Optional; + +public interface ActiveDeviceViewer extends Viewer { + + Optional findByDeviceId(String deviceId); + List findAll(); + default ActiveDevice getByDeviceId(String deviceId) { + return findByDeviceId(deviceId).orElseThrow(()->new IllegalArgumentException("No ActiveDevice Find")); + } + +} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/event/ActiveDeviceFinded.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/event/ActiveDeviceFinded.java new file mode 100644 index 00000000..ed8d447e --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/event/ActiveDeviceFinded.java @@ -0,0 +1,22 @@ +package com.whoz_in.main_api.query.device.application.active.event; + +import com.whoz_in.domain.device.model.Device; +import com.whoz_in.main_api.shared.event.Event; +import java.util.List; +import lombok.Getter; + +@Getter +public class ActiveDeviceFinded implements Event { + + private final List devices; + + public ActiveDeviceFinded(List devices) { + this.devices = devices; + } + + public static ActiveDeviceFinded of(List devices) { + return new ActiveDeviceFinded(devices); + } + + +} From b1cfcecbe1df15999050e6b0ebcfefb774fb627c Mon Sep 17 00:00:00 2001 From: bellmin Date: Mon, 6 Jan 2025 19:53:22 +0900 Subject: [PATCH 015/138] =?UTF-8?q?delete(main-api):=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=EC=9D=B4=EB=8F=99=EC=97=90=20=EB=94=B0=EB=A5=B8=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../device/application/ActiveDevice.java | 14 ------------ .../application/ActiveDeviceListResponse.java | 9 -------- .../application/ActiveDeviceResponse.java | 12 ---------- .../application/ActiveDeviceViewer.java | 15 ------------- .../active/event/ActiveDeviceFinded.java | 22 ------------------- 5 files changed, 72 deletions(-) delete mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDevice.java delete mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDeviceListResponse.java delete mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDeviceResponse.java delete mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDeviceViewer.java delete mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/event/ActiveDeviceFinded.java diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDevice.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDevice.java deleted file mode 100644 index cf001ede..00000000 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDevice.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.whoz_in.main_api.query.device.application; - -import com.whoz_in.main_api.query.shared.application.View; -import java.time.LocalDateTime; -import java.util.UUID; - -// Active 상태인 기기를 나타내는 View -// 접속 시작 시간, 접속 종료 시간 -public record ActiveDevice( - UUID deviceId, - UUID memberId, - LocalDateTime connectedTime, - LocalDateTime disconnectedTime -) implements View { } diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDeviceListResponse.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDeviceListResponse.java deleted file mode 100644 index 94a4b6a1..00000000 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDeviceListResponse.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.whoz_in.main_api.query.device.application; - -import com.whoz_in.main_api.query.shared.application.Response; -import java.util.List; - -public record ActiveDeviceListResponse( - List responses -) implements Response { -} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDeviceResponse.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDeviceResponse.java deleted file mode 100644 index 0bbc7295..00000000 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDeviceResponse.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.whoz_in.main_api.query.device.application; - -import com.whoz_in.main_api.query.shared.application.Response; - -public record ActiveDeviceResponse( - String deviceId, - String memberId, - String memberName, - String continuousActiveTime, - String totalActiveTime -) implements Response { -} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDeviceViewer.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDeviceViewer.java deleted file mode 100644 index d5cea902..00000000 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/ActiveDeviceViewer.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.whoz_in.main_api.query.device.application; - -import com.whoz_in.main_api.query.shared.application.Viewer; -import java.util.List; -import java.util.Optional; - -public interface ActiveDeviceViewer extends Viewer { - - Optional findByDeviceId(String deviceId); - List findAll(); - default ActiveDevice getByDeviceId(String deviceId) { - return findByDeviceId(deviceId).orElseThrow(()->new IllegalArgumentException("No ActiveDevice Find")); - } - -} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/event/ActiveDeviceFinded.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/event/ActiveDeviceFinded.java deleted file mode 100644 index 6fd0d6dc..00000000 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/event/ActiveDeviceFinded.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.whoz_in.main_api.shared.domain.device.active.event; - -import com.whoz_in.domain.device.model.Device; -import com.whoz_in.main_api.shared.event.Event; -import java.util.List; -import lombok.Getter; - -@Getter -public class ActiveDeviceFinded implements Event { - - private final List devices; - - public ActiveDeviceFinded(List devices) { - this.devices = devices; - } - - public static ActiveDeviceFinded of(List devices) { - return new ActiveDeviceFinded(devices); - } - - -} From adaa5b1add2eaa1760010fd4632c0e94d1a6398c Mon Sep 17 00:00:00 2001 From: bellmin Date: Tue, 7 Jan 2025 16:05:49 +0900 Subject: [PATCH 016/138] =?UTF-8?q?refactor(api-query-jpa):=20findAll=20?= =?UTF-8?q?=EB=A9=94=EC=86=8C=EB=93=9C=20=ED=95=84=ED=84=B0=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Objects.nonNull 메소드로 null인 요소 배제 --- .../whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java index 711fa5d9..b793c5fa 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java @@ -2,9 +2,10 @@ import com.whoz_in.api_query_jpa.member.Member; import com.whoz_in.api_query_jpa.member.MemberRepository; -import com.whoz_in.main_api.query.device.application.ActiveDevice; -import com.whoz_in.main_api.query.device.application.ActiveDeviceViewer; +import com.whoz_in.main_api.query.device.application.active.ActiveDevice; +import com.whoz_in.main_api.query.device.application.active.ActiveDeviceViewer; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.UUID; import lombok.RequiredArgsConstructor; @@ -43,6 +44,7 @@ public List findAll() { if (member == null) return null; return createOptionalActiveDevice(entity, member).orElse(null); }) + .filter(Objects::nonNull) .toList(); } From 8b047174cdbe2f4dfaa13828a42f45c88e797d82 Mon Sep 17 00:00:00 2001 From: bellmin Date: Tue, 7 Jan 2025 16:38:03 +0900 Subject: [PATCH 017/138] =?UTF-8?q?refactor(domain):=20ActiveDeviceFinder?= =?UTF-8?q?=20=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=B6=94=EA=B0=80=20=EB=B0=8F?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - find -> activeDeviceFind - inActiveDeviceFind 메소드 추가 --- .../com/whoz_in/domain/device/active/ActiveDeviceFinder.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveDeviceFinder.java b/modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveDeviceFinder.java index bb729514..dbe18760 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveDeviceFinder.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveDeviceFinder.java @@ -7,6 +7,7 @@ */ public interface ActiveDeviceFinder { - void find(); + void activeDeviceFind(); + void inActiveDeviceFind(); } From 5391f51bc09020f39defa9875a60915a79e527bd Mon Sep 17 00:00:00 2001 From: bellmin Date: Tue, 7 Jan 2025 16:38:51 +0900 Subject: [PATCH 018/138] =?UTF-8?q?feat(main-api):=20ActiveDeviceFinder=20?= =?UTF-8?q?=EC=9D=B8=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 임시적으로 구현 - 추후 리팩토링 예정 - 스프링 스케줄러 사용 --- .../active/SpringActiveDeviceFinder.java | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringActiveDeviceFinder.java diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringActiveDeviceFinder.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringActiveDeviceFinder.java new file mode 100644 index 00000000..d8c0d9bd --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringActiveDeviceFinder.java @@ -0,0 +1,137 @@ +package com.whoz_in.main_api.shared.domain.device.active; + +import com.whoz_in.domain.device.DeviceRepository; +import com.whoz_in.domain.device.active.ActiveDeviceFinder; +import com.whoz_in.domain.device.model.Device; +import com.whoz_in.domain.network_log.MonitorLog; +import com.whoz_in.domain.network_log.MonitorLogRepository; +import com.whoz_in.main_api.query.device.application.active.ActiveDevice; +import com.whoz_in.main_api.query.device.application.active.ActiveDeviceViewer; +import com.whoz_in.main_api.query.device.application.active.event.ActiveDeviceFinded; +import com.whoz_in.main_api.query.device.application.active.event.InActiveDeviceFinded; +import com.whoz_in.main_api.shared.event.Events; +import java.time.Duration; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +// 이 클래스는 ActiveDevice 를 찾기보단, ActiveDevice 와 InActiveDevice 를 모두 찾고 판별한다. +// 그리고 찾은 기기들을 저장하는 이벤트를 발생시킨다. +// View 랑 Aggregate 를 같이 사용하는 게 맞을까 +@Component("SpringActiveDeviceFinder") +public class SpringActiveDeviceFinder implements ActiveDeviceFinder { + + private final DeviceRepository deviceRepository; + private final MonitorLogRepository monitorLogRepository; + private final ActiveDeviceViewer activeDeviceViewer; + private final Map deviceByMac; + private final Map deviceById; + + private static final Duration MEASURE = Duration.ofMinutes(10); // 측정 시간 5분 + + public SpringActiveDeviceFinder( + DeviceRepository deviceRepository, + MonitorLogRepository monitorLogRepository, + ActiveDeviceViewer activeDeviceViewer + ){ + this.deviceRepository = deviceRepository; + this.monitorLogRepository = monitorLogRepository; + this.activeDeviceViewer = activeDeviceViewer; + this.deviceByMac = createDeviceMapByMac(); + this.deviceById = createDeviceMapById(); + } + + + @Override + @Scheduled(fixedRate = 5000) + public void activeDeviceFind() { + LocalDateTime todayMidnight = LocalDate.now().atTime(LocalTime.of(0, 0, 0)); + + List logs = monitorLogRepository.findByUpdatedAtAfterOrderByUpdatedAtDesc(todayMidnight); // 오늘 자정 이후의 로그들 , 현재 시간으로 바꿔야 할까? + Set uniqueLogs = new HashSet<>(logs); // 중복 제거 + + if (!uniqueLogs.isEmpty()) { + // 실제 판별 로직 + // 판별 로직이 허술하다. 판별하는 decider 를 구현해야 하나 + List activeDevices = uniqueLogs.stream() + .map(log -> deviceByMac.get(log.getMac())) + .filter(Objects::nonNull) + .toList(); + + Events.raise(new ActiveDeviceFinded(activeDevices, uniqueLogs.stream().toList())); + } + } + + @Override + @Scheduled(fixedRate = 5000) + public void inActiveDeviceFind() { + List activeDevices = activeDeviceViewer.findAll(); + + List logs = monitorLogRepository.findAll(); + List monitorLogDeviceIds = logs.stream() + .map(log -> deviceByMac.get(log.getMac())) + .filter(Objects::nonNull) + .map(device -> device.getId().id()) + .toList(); + Map logTimeByDeviceId = logs.stream() + .collect(Collectors.toMap( + log->deviceByMac.get(log.getMac()).getId().id(), + MonitorLog::getUpdatedAt + )); + + + activeDevices = activeDevices.stream() + .filter(activeDevice -> !monitorLogDeviceIds.contains(activeDevice.deviceId())) + .filter(activeDevice -> { + LocalDateTime logCreatedTime = logTimeByDeviceId.get(activeDevice.deviceId()); + LocalDateTime activeDeviceActiveTime = activeDevice.connectedTime(); + + Duration term = Duration.between(logCreatedTime, activeDeviceActiveTime); + + boolean isInActive = term.compareTo(MEASURE) > 0; // 로그 발생 시간과의 차이가 기준치보다 클 경우 InActive + + return isInActive; + })// 모니터 로그에 없는 Device 만 추출 (InActive 후보) + .toList(); + + List inActiveDevices = activeDevices.stream() + .map(activeDevice -> { + UUID id = activeDevice.deviceId(); + return deviceById.get(id); + }) + .toList(); + + Events.raise(new InActiveDeviceFinded(inActiveDevices)); + } + + private Map createDeviceMapById() { + return deviceRepository.findAll().stream() + .collect(Collectors.toMap(device -> device.getId().id(), device -> device)); + } + + private Map createDeviceMapByMac(){ + return deviceRepository.findAll().stream() + .map(this::oneDeviceToMap) + .reduce(new HashMap<>(), (identity, deviceMap) -> { + identity.putAll(deviceMap); + return identity; + }); + } + + // Mac 주소를 Key 로 사용한 Device Map + private Map oneDeviceToMap(Device device) { + return device.getDeviceInfos().stream() + .collect(Collectors.toMap(deviceInfo -> deviceInfo.getMac().toString(), deviceInfo -> device)); + } + +} From 85c739cc1e7685488a3ad0a20b94f31536355d23 Mon Sep 17 00:00:00 2001 From: bellmin Date: Tue, 7 Jan 2025 16:39:53 +0900 Subject: [PATCH 019/138] =?UTF-8?q?feat(api-query-jpa):=20ActiveDeviceEven?= =?UTF-8?q?tHandler=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ActiveDevice 와 관련된 이벤트 핸들러 - ActiveDeviceFinded 이벤트 처리 - InActiveDeviceFinded 이벤트 처리 --- .../event/ActiveDeviceEventHandler.java | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java index 77653e09..16531cd7 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java @@ -3,12 +3,15 @@ import com.whoz_in.api_query_jpa.device.ActiveDeviceEntity; import com.whoz_in.api_query_jpa.device.ActiveDeviceRepository; import com.whoz_in.domain.device.model.Device; -import com.whoz_in.main_api.shared.domain.device.active.event.ActiveDeviceFinded; +import com.whoz_in.main_api.query.device.application.active.event.ActiveDeviceFinded; +import com.whoz_in.main_api.query.device.application.active.event.InActiveDeviceFinded; import java.time.LocalDateTime; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Transactional; @Component @RequiredArgsConstructor @@ -16,8 +19,9 @@ public class ActiveDeviceEventHandler { private final ActiveDeviceRepository activeDeviceRepository; + @Transactional(isolation = Isolation.SERIALIZABLE) @EventListener(ActiveDeviceFinded.class) - public void handle(ActiveDeviceFinded event) { + public void saveActiveDevices(ActiveDeviceFinded event) { List devices = event.getDevices(); List entities = devices.stream() .map(device -> ActiveDeviceEntity.create(device.getId(), LocalDateTime.now())) // TODO: active Time 을 이 시점으로 설정해도 될까? @@ -26,4 +30,18 @@ public void handle(ActiveDeviceFinded event) { activeDeviceRepository.saveAll(entities); } + // 바로 위의 이벤트 핸들러에서 데이터를 수정할 수 있으므로, 격리 수준을 가장 강하게 설정 + @Transactional(isolation = Isolation.SERIALIZABLE) + @EventListener(ActiveDeviceFinded.class) + public void processInActiveDevices(InActiveDeviceFinded event) { + // InActiveDevice 찾는 로직 + List devices = event.getDevices(); + List entities = activeDeviceRepository.findAll(); + + entities.stream() + .filter(activeDevice -> devices.stream() + .anyMatch(device -> device.getId().id().equals(activeDevice.getDeviceId()))) + .forEach(activeDevice -> activeDevice.inActiveOn(LocalDateTime.now())); + } + } From 110f5132669b535cab7d09505ddfc61f4843c67d Mon Sep 17 00:00:00 2001 From: bellmin Date: Tue, 7 Jan 2025 16:40:24 +0900 Subject: [PATCH 020/138] =?UTF-8?q?refactor(api-query-jpa):=20ActiveDevice?= =?UTF-8?q?Entity=20=EB=A9=94=EC=86=8C=EB=93=9C=EB=AA=85=20=EC=98=A4?= =?UTF-8?q?=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 오타 수정 --- .../com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java index 0cee9ba5..03386004 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java @@ -35,9 +35,9 @@ public void activeOn(LocalDateTime activeTime){ this.activeTime = activeTime; } - public void isActiveOn(LocalDateTime inactiveTime){ + public void inActiveOn(LocalDateTime inactiveTime){ this.inactiveTime = inactiveTime; - this.totalActiveTime = Duration.between(this.activeTime, this.inactiveTime); + this.totalActiveTime = this.totalActiveTime.plus(Duration.between(this.activeTime, this.inactiveTime)); } public static ActiveDeviceEntity create(DeviceId deviceId, LocalDateTime activeTime){ From 94fa8e1a7c2c80bf90e2224e1886c2bfb5b16a5d Mon Sep 17 00:00:00 2001 From: bellmin Date: Tue, 7 Jan 2025 16:41:41 +0900 Subject: [PATCH 021/138] =?UTF-8?q?feat(domain-jpa):=20MonitorLogEntityRep?= =?UTF-8?q?ository=20=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - findByUpdatedAtAfterOrderByUpdatedAtDesc : ActiveDevice 들을 찾기 위함 --- .../domain_jpa/monitor/MonitorLogEntityRepository.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/monitor/MonitorLogEntityRepository.java b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/monitor/MonitorLogEntityRepository.java index 0637e4be..5371248b 100644 --- a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/monitor/MonitorLogEntityRepository.java +++ b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/monitor/MonitorLogEntityRepository.java @@ -1,6 +1,11 @@ package com.whoz_in.domain_jpa.monitor; +import java.time.LocalDateTime; +import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; public interface MonitorLogEntityRepository extends JpaRepository { + + List findByUpdatedAtAfterOrderByUpdatedAtDesc(LocalDateTime updatedAt); + } From 28a0a5c3ae8ed222651a0a5348588a4553963934 Mon Sep 17 00:00:00 2001 From: bellmin Date: Tue, 7 Jan 2025 16:42:23 +0900 Subject: [PATCH 022/138] =?UTF-8?q?feat(main-api):=20ActiveDeviceFinded?= =?UTF-8?q?=EC=97=90=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 이벤트 핸들러에서 Log 정보 필요 --- .../application/active/event/ActiveDeviceFinded.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/event/ActiveDeviceFinded.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/event/ActiveDeviceFinded.java index ed8d447e..a9e5dec8 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/event/ActiveDeviceFinded.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/event/ActiveDeviceFinded.java @@ -1,6 +1,8 @@ package com.whoz_in.main_api.query.device.application.active.event; import com.whoz_in.domain.device.model.Device; +import com.whoz_in.domain.network_log.MonitorLog; +import com.whoz_in.main_api.query.device.application.active.ActiveDevice; import com.whoz_in.main_api.shared.event.Event; import java.util.List; import lombok.Getter; @@ -9,14 +11,11 @@ public class ActiveDeviceFinded implements Event { private final List devices; + private final List logs; - public ActiveDeviceFinded(List devices) { + public ActiveDeviceFinded(List devices, List logs) { this.devices = devices; + this.logs = logs; } - public static ActiveDeviceFinded of(List devices) { - return new ActiveDeviceFinded(devices); - } - - } From 072274f8807e450faf600e6d9ba59f08a1bb23f5 Mon Sep 17 00:00:00 2001 From: bellmin Date: Tue, 7 Jan 2025 16:43:30 +0900 Subject: [PATCH 023/138] =?UTF-8?q?feat(domain-jpa):=20MonitorLogRepositor?= =?UTF-8?q?y=20=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EB=B0=8F=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - findAll() : 모니터 로그 전부 조회 - findByUpdatedAtAfterOrderByUpdatedAtDesc : ActiveDevice 찾는 데 필요 --- .../domain/network_log/MonitorLogRepository.java | 5 +++++ .../monitor/MonitorLogJpaRepository.java | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/modules/domain/src/main/java/com/whoz_in/domain/network_log/MonitorLogRepository.java b/modules/domain/src/main/java/com/whoz_in/domain/network_log/MonitorLogRepository.java index 9cbf584d..cd5e85a9 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/network_log/MonitorLogRepository.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/network_log/MonitorLogRepository.java @@ -1,8 +1,13 @@ package com.whoz_in.domain.network_log; +import java.time.LocalDateTime; import java.util.Collection; +import java.util.List; public interface MonitorLogRepository { void save(MonitorLog log); void saveAll(Collection logs); + List findAll(); + List findByUpdatedAtAfterOrderByUpdatedAtDesc(LocalDateTime updatedAt); // 해당 시간 이후의 로그를 가져오기 + // TODO: 이전 로그까지 가져와야 할까? } diff --git a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/monitor/MonitorLogJpaRepository.java b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/monitor/MonitorLogJpaRepository.java index 201cc1f9..a3f0899f 100644 --- a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/monitor/MonitorLogJpaRepository.java +++ b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/monitor/MonitorLogJpaRepository.java @@ -2,7 +2,9 @@ import com.whoz_in.domain.network_log.MonitorLog; import com.whoz_in.domain.network_log.MonitorLogRepository; +import java.time.LocalDateTime; import java.util.Collection; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; @@ -30,4 +32,18 @@ public void saveAll(Collection logs) { jdbcTemplate.batchUpdate(sql, logs, logs.size(), (ps, log) -> ps.setString(1, log.getMac())); } + + @Override + public List findAll() { + return repository.findAll().stream() + .map(converter::to) + .toList(); + } + + @Override + public List findByUpdatedAtAfterOrderByUpdatedAtDesc(LocalDateTime updatedAt) { + return repository.findByUpdatedAtAfterOrderByUpdatedAtDesc(updatedAt).stream() + .map(converter::to) + .toList(); + } } From 7ba0a2bb80a77f55fc8a06a59712e2355711f56e Mon Sep 17 00:00:00 2001 From: bellmin Date: Tue, 7 Jan 2025 16:44:04 +0900 Subject: [PATCH 024/138] =?UTF-8?q?feat(main-api):=20InActiveDeviceFinded?= =?UTF-8?q?=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../active/event/InActiveDeviceFinded.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/event/InActiveDeviceFinded.java diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/event/InActiveDeviceFinded.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/event/InActiveDeviceFinded.java new file mode 100644 index 00000000..ec76b82a --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/event/InActiveDeviceFinded.java @@ -0,0 +1,17 @@ +package com.whoz_in.main_api.query.device.application.active.event; + +import com.whoz_in.domain.device.model.Device; +import com.whoz_in.main_api.shared.event.Event; +import java.util.List; +import lombok.Getter; + +@Getter +public class InActiveDeviceFinded implements Event { + + private final List devices; + + public InActiveDeviceFinded(List devices) { + this.devices = devices; + } + +} From 9e494653d0001a0371f0c0428c5159316494ac4b Mon Sep 17 00:00:00 2001 From: bellmin Date: Tue, 7 Jan 2025 16:54:54 +0900 Subject: [PATCH 025/138] =?UTF-8?q?refactor(domain):=20=EC=9D=B8=ED=84=B0?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=8A=A4=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ActiveDeviceFinder -> DeviceStatusManager --- .../{ActiveDeviceFinder.java => DeviceStatusManager.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename modules/domain/src/main/java/com/whoz_in/domain/device/active/{ActiveDeviceFinder.java => DeviceStatusManager.java} (89%) diff --git a/modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveDeviceFinder.java b/modules/domain/src/main/java/com/whoz_in/domain/device/active/DeviceStatusManager.java similarity index 89% rename from modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveDeviceFinder.java rename to modules/domain/src/main/java/com/whoz_in/domain/device/active/DeviceStatusManager.java index dbe18760..4fa02682 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveDeviceFinder.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/device/active/DeviceStatusManager.java @@ -5,7 +5,7 @@ * void find() : Active 상태인 Device 를 찾아서 ActiveDeviceRepository 에 저장 * Active 상태인지 판별하는 로직이 들어가 있다. */ -public interface ActiveDeviceFinder { +public interface DeviceStatusManager { void activeDeviceFind(); void inActiveDeviceFind(); From fd0dbaa9a107b02de35c3518075f3a5bf581793d Mon Sep 17 00:00:00 2001 From: bellmin Date: Tue, 7 Jan 2025 16:55:36 +0900 Subject: [PATCH 026/138] =?UTF-8?q?refactor(main-api):=20SpringActiveDevic?= =?UTF-8?q?eFinder=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - SpringActiveDeviceFinder -> SpringDeviceStatusManager --- ...eviceFinder.java => SpringDeviceStatusManager.java} | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) rename modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/{SpringActiveDeviceFinder.java => SpringDeviceStatusManager.java} (95%) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringActiveDeviceFinder.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java similarity index 95% rename from modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringActiveDeviceFinder.java rename to modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java index d8c0d9bd..4a05cc58 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringActiveDeviceFinder.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java @@ -1,7 +1,7 @@ package com.whoz_in.main_api.shared.domain.device.active; import com.whoz_in.domain.device.DeviceRepository; -import com.whoz_in.domain.device.active.ActiveDeviceFinder; +import com.whoz_in.domain.device.active.DeviceStatusManager; import com.whoz_in.domain.device.model.Device; import com.whoz_in.domain.network_log.MonitorLog; import com.whoz_in.domain.network_log.MonitorLogRepository; @@ -28,8 +28,8 @@ // 이 클래스는 ActiveDevice 를 찾기보단, ActiveDevice 와 InActiveDevice 를 모두 찾고 판별한다. // 그리고 찾은 기기들을 저장하는 이벤트를 발생시킨다. // View 랑 Aggregate 를 같이 사용하는 게 맞을까 -@Component("SpringActiveDeviceFinder") -public class SpringActiveDeviceFinder implements ActiveDeviceFinder { +@Component("SpringDeviceStatusManager") +public class SpringDeviceStatusManager implements DeviceStatusManager { private final DeviceRepository deviceRepository; private final MonitorLogRepository monitorLogRepository; @@ -37,9 +37,9 @@ public class SpringActiveDeviceFinder implements ActiveDeviceFinder { private final Map deviceByMac; private final Map deviceById; - private static final Duration MEASURE = Duration.ofMinutes(10); // 측정 시간 5분 + private static final Duration MEASURE = Duration.ofMinutes(10); // 측정 시간 10분 - public SpringActiveDeviceFinder( + public SpringDeviceStatusManager( DeviceRepository deviceRepository, MonitorLogRepository monitorLogRepository, ActiveDeviceViewer activeDeviceViewer From 58d11b19a4ca715be2fa793cb5f7551f24b9d386 Mon Sep 17 00:00:00 2001 From: bellmin Date: Tue, 7 Jan 2025 17:15:03 +0900 Subject: [PATCH 027/138] =?UTF-8?q?refactor(main-api,api-query-jpa):=20api?= =?UTF-8?q?-query-jpa=20=EA=B0=80=20domain=20=EC=9D=84=20=EC=9D=98?= =?UTF-8?q?=EC=A1=B4=ED=95=98=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api_query_jpa/device/ActiveDeviceEntity.java | 5 ++--- .../device/event/ActiveDeviceEventHandler.java | 10 +++++----- .../application/active/event/ActiveDeviceFinded.java | 7 +++---- .../application/active/event/InActiveDeviceFinded.java | 6 +++--- .../device/active/SpringDeviceStatusManager.java | 6 ++++-- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java index 03386004..1ddb7912 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java @@ -1,6 +1,5 @@ package com.whoz_in.api_query_jpa.device; -import com.whoz_in.domain.device.model.DeviceId; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Id; @@ -40,8 +39,8 @@ public void inActiveOn(LocalDateTime inactiveTime){ this.totalActiveTime = this.totalActiveTime.plus(Duration.between(this.activeTime, this.inactiveTime)); } - public static ActiveDeviceEntity create(DeviceId deviceId, LocalDateTime activeTime){ - return new ActiveDeviceEntity(deviceId.id(), activeTime); + public static ActiveDeviceEntity create(UUID deviceId, LocalDateTime activeTime){ + return new ActiveDeviceEntity(deviceId, activeTime); } } diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java index 16531cd7..a865088c 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java @@ -2,11 +2,11 @@ import com.whoz_in.api_query_jpa.device.ActiveDeviceEntity; import com.whoz_in.api_query_jpa.device.ActiveDeviceRepository; -import com.whoz_in.domain.device.model.Device; import com.whoz_in.main_api.query.device.application.active.event.ActiveDeviceFinded; import com.whoz_in.main_api.query.device.application.active.event.InActiveDeviceFinded; import java.time.LocalDateTime; import java.util.List; +import java.util.UUID; import lombok.RequiredArgsConstructor; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; @@ -22,9 +22,9 @@ public class ActiveDeviceEventHandler { @Transactional(isolation = Isolation.SERIALIZABLE) @EventListener(ActiveDeviceFinded.class) public void saveActiveDevices(ActiveDeviceFinded event) { - List devices = event.getDevices(); + List devices = event.getDevices(); List entities = devices.stream() - .map(device -> ActiveDeviceEntity.create(device.getId(), LocalDateTime.now())) // TODO: active Time 을 이 시점으로 설정해도 될까? + .map(device -> ActiveDeviceEntity.create(device, LocalDateTime.now())) // TODO: active Time 을 이 시점으로 설정해도 될까? .toList(); activeDeviceRepository.saveAll(entities); @@ -35,12 +35,12 @@ public void saveActiveDevices(ActiveDeviceFinded event) { @EventListener(ActiveDeviceFinded.class) public void processInActiveDevices(InActiveDeviceFinded event) { // InActiveDevice 찾는 로직 - List devices = event.getDevices(); + List devices = event.getDevices(); List entities = activeDeviceRepository.findAll(); entities.stream() .filter(activeDevice -> devices.stream() - .anyMatch(device -> device.getId().id().equals(activeDevice.getDeviceId()))) + .anyMatch(device -> device.equals(activeDevice.getDeviceId()))) .forEach(activeDevice -> activeDevice.inActiveOn(LocalDateTime.now())); } diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/event/ActiveDeviceFinded.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/event/ActiveDeviceFinded.java index a9e5dec8..63ac5234 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/event/ActiveDeviceFinded.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/event/ActiveDeviceFinded.java @@ -1,19 +1,18 @@ package com.whoz_in.main_api.query.device.application.active.event; -import com.whoz_in.domain.device.model.Device; import com.whoz_in.domain.network_log.MonitorLog; -import com.whoz_in.main_api.query.device.application.active.ActiveDevice; import com.whoz_in.main_api.shared.event.Event; import java.util.List; +import java.util.UUID; import lombok.Getter; @Getter public class ActiveDeviceFinded implements Event { - private final List devices; + private final List devices; private final List logs; - public ActiveDeviceFinded(List devices, List logs) { + public ActiveDeviceFinded(List devices, List logs) { this.devices = devices; this.logs = logs; } diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/event/InActiveDeviceFinded.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/event/InActiveDeviceFinded.java index ec76b82a..b81ffabc 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/event/InActiveDeviceFinded.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/event/InActiveDeviceFinded.java @@ -1,16 +1,16 @@ package com.whoz_in.main_api.query.device.application.active.event; -import com.whoz_in.domain.device.model.Device; import com.whoz_in.main_api.shared.event.Event; import java.util.List; +import java.util.UUID; import lombok.Getter; @Getter public class InActiveDeviceFinded implements Event { - private final List devices; + private final List devices; - public InActiveDeviceFinded(List devices) { + public InActiveDeviceFinded(List devices) { this.devices = devices; } diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java index 4a05cc58..f7ef962a 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java @@ -63,9 +63,10 @@ public void activeDeviceFind() { if (!uniqueLogs.isEmpty()) { // 실제 판별 로직 // 판별 로직이 허술하다. 판별하는 decider 를 구현해야 하나 - List activeDevices = uniqueLogs.stream() + List activeDevices = uniqueLogs.stream() .map(log -> deviceByMac.get(log.getMac())) .filter(Objects::nonNull) + .map(device -> device.getId().id()) .toList(); Events.raise(new ActiveDeviceFinded(activeDevices, uniqueLogs.stream().toList())); @@ -104,11 +105,12 @@ public void inActiveDeviceFind() { })// 모니터 로그에 없는 Device 만 추출 (InActive 후보) .toList(); - List inActiveDevices = activeDevices.stream() + List inActiveDevices = activeDevices.stream() .map(activeDevice -> { UUID id = activeDevice.deviceId(); return deviceById.get(id); }) + .map(device -> device.getId().id()) .toList(); Events.raise(new InActiveDeviceFinded(inActiveDevices)); From 9417b2745e86ffe1db6fee408c9d406a65d2ffc1 Mon Sep 17 00:00:00 2001 From: bellmin Date: Tue, 7 Jan 2025 17:16:39 +0900 Subject: [PATCH 028/138] =?UTF-8?q?refactor(api-query-jpa):=20ActiveDevice?= =?UTF-8?q?EventHandler=20=ED=81=B4=EB=9E=98=EC=8A=A4=EB=AA=85=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ActiveDeviceEventHandler -> DeviceStatusEventHandler --- ...iveDeviceEventHandler.java => DeviceStatusEventHandler.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/{ActiveDeviceEventHandler.java => DeviceStatusEventHandler.java} (98%) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java similarity index 98% rename from modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java rename to modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java index a865088c..34b3d398 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java @@ -15,7 +15,7 @@ @Component @RequiredArgsConstructor -public class ActiveDeviceEventHandler { +public class DeviceStatusEventHandler { private final ActiveDeviceRepository activeDeviceRepository; From 42b163ded17fd63e908b71e8b86cf77fa8ab56bc Mon Sep 17 00:00:00 2001 From: bellmin Date: Tue, 7 Jan 2025 17:21:45 +0900 Subject: [PATCH 029/138] =?UTF-8?q?refactor(api-query-jpa):=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=A9=94?= =?UTF-8?q?=EC=86=8C=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - findByMemberId --- .../java/com/whoz_in/api_query_jpa/member/MemberRepository.java | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/member/MemberRepository.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/member/MemberRepository.java index e73aef95..a8baedd0 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/member/MemberRepository.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/member/MemberRepository.java @@ -10,7 +10,6 @@ @Repository public interface MemberRepository extends JpaRepository { Optional findByLoginId(String loginId); - Optional findByMemberId(UUID memberId); @Query("SELECT m FROM Member m WHERE m.id IN (SELECT d.memberId FROM Device d WHERE d.deviceId = :deviceId)") Optional findByDeviceId(UUID deviceId); From 64660c1b921fca6cc905550cfdf32386749f746d Mon Sep 17 00:00:00 2001 From: bellmin Date: Tue, 7 Jan 2025 17:28:33 +0900 Subject: [PATCH 030/138] =?UTF-8?q?feat(main-api):=20=EC=8A=A4=EC=BC=80?= =?UTF-8?q?=EC=A4=84=EB=A7=81=20=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/whoz_in/main_api/config/SchedulerConfig.java | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/config/SchedulerConfig.java diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/config/SchedulerConfig.java b/modules/main-api/src/main/java/com/whoz_in/main_api/config/SchedulerConfig.java new file mode 100644 index 00000000..88e812bc --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/config/SchedulerConfig.java @@ -0,0 +1,9 @@ +package com.whoz_in.main_api.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableScheduling; + +@Configuration +@EnableScheduling +public class SchedulerConfig { +} From c22083a03501fece4dd338557d239bcb4f915d63 Mon Sep 17 00:00:00 2001 From: bellmin Date: Tue, 7 Jan 2025 18:28:08 +0900 Subject: [PATCH 031/138] =?UTF-8?q?delete(domain):=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=9D=B8=ED=84=B0?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ActiveDeviceRepository - ActiveTimeCalculator --- .../device/active/ActiveDeviceRepository.java | 27 ------------------- .../device/active/ActiveTimeCalculator.java | 12 --------- 2 files changed, 39 deletions(-) delete mode 100644 modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveDeviceRepository.java delete mode 100644 modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveTimeCalculator.java diff --git a/modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveDeviceRepository.java b/modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveDeviceRepository.java deleted file mode 100644 index f34ac73f..00000000 --- a/modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveDeviceRepository.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.whoz_in.domain.device.active; - -import com.whoz_in.domain.device.model.Device; -import com.whoz_in.domain.device.model.DeviceId; -import java.util.Collection; -import java.util.List; -import java.util.Optional; - -/** - * 구현에 따라 달라지므로 interface - * 일반 DeviceRepository 와 역할이 너무 비슷한가? - * ActiveDeviceRepository 의 역할 - * 1. Active 상태인 Device 들을 저장한다. (내부 구현은 동시성 문제를 해결해야 한다.) - * 2. Active 상태인 Device 들을 조회한다. - */ -public interface ActiveDeviceRepository { - - List findAll(); - Optional findByDeviceId(DeviceId deviceId); - boolean existsByDeviceId(DeviceId deviceId); - void deleteByDeviceId(DeviceId deviceId); - void save(Device device); - void saveAll(Collection devices); - default List getAll(){ return findAll(); } - default Optional get(DeviceId deviceId){ return findByDeviceId(deviceId); } - -} diff --git a/modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveTimeCalculator.java b/modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveTimeCalculator.java deleted file mode 100644 index fae66364..00000000 --- a/modules/domain/src/main/java/com/whoz_in/domain/device/active/ActiveTimeCalculator.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.whoz_in.domain.device.active; - - -/** - * Active 상태인 Device 들의 누적 접속 시간, 연속 접속 시간을 계산한다. - */ -public interface ActiveTimeCalculator { - - void calculateContinuousTime(); - void calculateTotalTime(); - -} From e387f7f2da1674a36f91fdcce6c9210a022a2e31 Mon Sep 17 00:00:00 2001 From: bellmin Date: Tue, 7 Jan 2025 19:01:57 +0900 Subject: [PATCH 032/138] =?UTF-8?q?delete(api-query-jpa):=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=9D=B8?= =?UTF-8?q?=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ActiveDeviceRepository --- .../api_query_jpa/device/ActiveDeviceRepository.java | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceRepository.java diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceRepository.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceRepository.java deleted file mode 100644 index eb515de8..00000000 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceRepository.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.whoz_in.api_query_jpa.device; - -import java.util.Optional; -import java.util.UUID; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface ActiveDeviceRepository extends JpaRepository { - - Optional findByDeviceId(UUID deviceId); - -} From 378d08a21dc1698f1c0b88a678faa73d37dfd746 Mon Sep 17 00:00:00 2001 From: bellmin Date: Tue, 7 Jan 2025 19:02:59 +0900 Subject: [PATCH 033/138] =?UTF-8?q?refactor(api-query-jpa):=20SubSelect=20?= =?UTF-8?q?=EB=A5=BC=20native=20=EC=BF=BC=EB=A6=AC=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/whoz_in/api_query_jpa/device/Device.java | 12 ++++++------ .../api_query_jpa/device/DeviceRepository.java | 7 +++++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/Device.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/Device.java index 83aebcef..be100637 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/Device.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/Device.java @@ -1,5 +1,6 @@ package com.whoz_in.api_query_jpa.device; +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Id; import java.util.UUID; @@ -11,17 +12,16 @@ @Entity @Getter -@Subselect("SELECT " - + "device.id as deviceId, " - + "device.memberId as onwer " - + "FROM DeviceEntity device " -) +@Subselect("SELECT id , member_id FROM device_entity") @Immutable @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Device { @Id - private UUID deviceId; + @Column(name = "id", nullable = false) + private UUID id; + + @Column(name ="member_id", nullable = false) private UUID memberId; } diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceRepository.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceRepository.java index f7963222..5e8346a5 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceRepository.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceRepository.java @@ -1,11 +1,14 @@ package com.whoz_in.api_query_jpa.device; -import java.util.Optional; +import java.util.List; import java.util.UUID; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; public interface DeviceRepository extends JpaRepository { - Optional findByDeviceId(UUID deviceId); + @Query(nativeQuery = true, + value = "SELECT id , member_id FROM device_entity") + List findAll(); } From 2443cb85f4eb155d15d7182a69aeb44c7b9054bd Mon Sep 17 00:00:00 2001 From: bellmin Date: Tue, 7 Jan 2025 19:05:21 +0900 Subject: [PATCH 034/138] =?UTF-8?q?refactor(api-query-jpa):=20Device=20?= =?UTF-8?q?=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EB=B0=8F=20=EC=88=98=EC=A0=95=EB=90=9C=20=ED=95=84=EB=93=9C=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../whoz_in/api_query_jpa/member/MemberRepository.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/member/MemberRepository.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/member/MemberRepository.java index a8baedd0..4009381a 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/member/MemberRepository.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/member/MemberRepository.java @@ -5,15 +5,16 @@ import java.util.UUID; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @Repository public interface MemberRepository extends JpaRepository { Optional findByLoginId(String loginId); - @Query("SELECT m FROM Member m WHERE m.id IN (SELECT d.memberId FROM Device d WHERE d.deviceId = :deviceId)") - Optional findByDeviceId(UUID deviceId); + @Query("SELECT m FROM Member m WHERE m.id IN (SELECT d.memberId FROM Device d WHERE d.id = :deviceId)") + Optional findByDeviceId(@Param("deviceId") UUID deviceId); - @Query("SELECT m FROM Member m WHERE m.id IN (SELECT d.memberId FROM Device d WHERE d.deviceId IN (:deviceIds))") - List findByDeviceIds(List deviceIds); + @Query("SELECT m FROM Member m WHERE m.id IN (SELECT d.memberId FROM Device d WHERE d.id IN (:deviceIds))") + List findByDeviceIds(@Param("deviceIds") List deviceIds); } From 3224d9b12300898cebd7ef702ad721ceb748d10d Mon Sep 17 00:00:00 2001 From: bellmin Date: Tue, 7 Jan 2025 19:06:42 +0900 Subject: [PATCH 035/138] =?UTF-8?q?refactor(api-query-jpa):=20ActiveDevice?= =?UTF-8?q?=20InMemory=20=EB=8D=B0=EC=9D=B4=ED=84=B0=EB=B2=A0=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4=EB=A1=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - InMemory 적용 - InMemory 엔티티 적용 --- .../device/ActiveDeviceEntity.java | 2 - .../device/ActiveDeviceJpaViewer.java | 4 +- .../InMemoryActiveDeviceRepository.java | 44 +++++++++++++++++++ .../event/DeviceStatusEventHandler.java | 5 ++- 4 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/InMemoryActiveDeviceRepository.java diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java index 1ddb7912..c7320a76 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java @@ -1,7 +1,6 @@ package com.whoz_in.api_query_jpa.device; import jakarta.persistence.Column; -import jakarta.persistence.Entity; import jakarta.persistence.Id; import java.time.Duration; import java.time.LocalDateTime; @@ -10,7 +9,6 @@ import lombok.Getter; import lombok.NoArgsConstructor; -@Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class ActiveDeviceEntity { diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java index b793c5fa..032fc591 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java @@ -15,7 +15,7 @@ @RequiredArgsConstructor public class ActiveDeviceJpaViewer implements ActiveDeviceViewer { - private final ActiveDeviceRepository activeDeviceRepository; + private final InMemoryActiveDeviceRepository activeDeviceRepository; private final DeviceRepository deviceRepository; private final MemberRepository memberRepository; @@ -38,7 +38,7 @@ public List findAll() { return entities.stream() .map(entity-> { - Device device = devices.stream().filter(d -> d.getDeviceId().equals(entity.getDeviceId())).findFirst().orElse(null); + Device device = devices.stream().filter(d -> d.getId().equals(entity.getDeviceId())).findFirst().orElse(null); if(device == null) return null; Member member = members.stream().filter(m -> m.getId().equals(device.getMemberId())).findFirst().orElse(null); if (member == null) return null; diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/InMemoryActiveDeviceRepository.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/InMemoryActiveDeviceRepository.java new file mode 100644 index 00000000..1c7c34ff --- /dev/null +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/InMemoryActiveDeviceRepository.java @@ -0,0 +1,44 @@ +package com.whoz_in.api_query_jpa.device; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; +import org.springframework.stereotype.Repository; + +@Repository +public class InMemoryActiveDeviceRepository { + + private final Map repository; + + public InMemoryActiveDeviceRepository(){ + this.repository = new HashMap<>(); + } + + public UUID save(ActiveDeviceEntity device){ + UUID id = device.getDeviceId(); + repository.put(id, device); + return device.getDeviceId(); + } + + public void saveAll(List devices){ + devices.forEach(this::save); + } + + public List findAll(){ + return repository.values().stream().toList(); + } + + public Optional findByDeviceId(UUID deviceId){ + if(repository.containsKey(deviceId)) + return Optional.of(repository.get(deviceId)); + return Optional.empty(); + } + + public void deleteById(UUID deviceId){ + repository.remove(deviceId); + } + + +} diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java index 34b3d398..c196523a 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java @@ -1,7 +1,7 @@ package com.whoz_in.api_query_jpa.device.event; import com.whoz_in.api_query_jpa.device.ActiveDeviceEntity; -import com.whoz_in.api_query_jpa.device.ActiveDeviceRepository; +import com.whoz_in.api_query_jpa.device.InMemoryActiveDeviceRepository; import com.whoz_in.main_api.query.device.application.active.event.ActiveDeviceFinded; import com.whoz_in.main_api.query.device.application.active.event.InActiveDeviceFinded; import java.time.LocalDateTime; @@ -17,7 +17,8 @@ @RequiredArgsConstructor public class DeviceStatusEventHandler { - private final ActiveDeviceRepository activeDeviceRepository; +// private final ActiveDeviceRepository activeDeviceRepository; + private final InMemoryActiveDeviceRepository activeDeviceRepository; @Transactional(isolation = Isolation.SERIALIZABLE) @EventListener(ActiveDeviceFinded.class) From 64466480f39c7489945b31cd3adcaf1051bc937c Mon Sep 17 00:00:00 2001 From: bellmin Date: Tue, 7 Jan 2025 19:08:42 +0900 Subject: [PATCH 036/138] =?UTF-8?q?comment(api-query-jpa):=20TODO=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - JPA 적용 --- .../com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java | 1 + .../com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java | 1 + .../api_query_jpa/device/event/DeviceStatusEventHandler.java | 1 + 3 files changed, 3 insertions(+) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java index c7320a76..52863913 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java @@ -9,6 +9,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; +// TODO: JPA 적용 @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class ActiveDeviceEntity { diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java index 032fc591..d92181ce 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java @@ -11,6 +11,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; +// TODO : JPA 적용 @Component @RequiredArgsConstructor public class ActiveDeviceJpaViewer implements ActiveDeviceViewer { diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java index c196523a..55eadd1e 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java @@ -18,6 +18,7 @@ public class DeviceStatusEventHandler { // private final ActiveDeviceRepository activeDeviceRepository; + // TODO: JPA 적용 private final InMemoryActiveDeviceRepository activeDeviceRepository; @Transactional(isolation = Isolation.SERIALIZABLE) From 91ff2af79c77beacf3c58b88eea05c7d55456fa4 Mon Sep 17 00:00:00 2001 From: bellmin Date: Tue, 7 Jan 2025 19:09:58 +0900 Subject: [PATCH 037/138] =?UTF-8?q?refactor(main-api):=20=ED=8C=A8?= =?UTF-8?q?=ED=82=A4=EC=A7=80=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/device/active/DeviceFilter.java | 17 +++++++++++++++++ .../device/active/DeviceStatusManager.java | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java rename modules/{domain/src/main/java/com/whoz_in => main-api/src/main/java/com/whoz_in/main_api/shared}/domain/device/active/DeviceStatusManager.java (85%) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java new file mode 100644 index 00000000..fc5d0dd7 --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java @@ -0,0 +1,17 @@ +package com.whoz_in.main_api.shared.domain.device.active; + +import com.whoz_in.domain.device.model.Device; +import java.util.List; + +// Device 들을 받으면, 정해진 기준에 맞춰 거르는 역할이라는 뜻 +public abstract class DeviceFilter { + + public List execute(List devices){ + return devices.stream() + .filter(this::judge) + .toList(); + } + + public abstract boolean judge(Device device); + +} diff --git a/modules/domain/src/main/java/com/whoz_in/domain/device/active/DeviceStatusManager.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceStatusManager.java similarity index 85% rename from modules/domain/src/main/java/com/whoz_in/domain/device/active/DeviceStatusManager.java rename to modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceStatusManager.java index 4fa02682..f8825ce9 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/device/active/DeviceStatusManager.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceStatusManager.java @@ -1,4 +1,4 @@ -package com.whoz_in.domain.device.active; +package com.whoz_in.main_api.shared.domain.device.active; /** * 주기적으로 Active 상태인 Device 들을 찾는 친구 From b09685e3a540d12ac5cbcf08b4d7feaa37d0c492 Mon Sep 17 00:00:00 2001 From: bellmin Date: Wed, 8 Jan 2025 16:59:45 +0900 Subject: [PATCH 038/138] =?UTF-8?q?feat(main-api):=20Active=20InActive=20D?= =?UTF-8?q?evice=EC=9D=98=20=EC=83=81=ED=83=9C=EB=A5=BC=20=ED=8C=90?= =?UTF-8?q?=EB=B3=84=ED=95=98=EB=8A=94=20Device=20=ED=95=84=ED=84=B0=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - abstract 클래스 --- .../domain/device/active/DeviceFilter.java | 55 ++++++++++++++++++- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java index fc5d0dd7..bc22e45e 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java @@ -1,17 +1,68 @@ package com.whoz_in.main_api.shared.domain.device.active; +import com.whoz_in.domain.device.DeviceRepository; import com.whoz_in.domain.device.model.Device; +import com.whoz_in.domain.network_log.MonitorLogRepository; +import com.whoz_in.main_api.query.device.application.active.ActiveDeviceViewer; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; +import org.springframework.stereotype.Component; // Device 들을 받으면, 정해진 기준에 맞춰 거르는 역할이라는 뜻 +@Component public abstract class DeviceFilter { - public List execute(List devices){ + protected final DeviceRepository deviceRepository; + protected final MonitorLogRepository monitorLogRepository; + protected final ActiveDeviceViewer activeDeviceViewer; + + protected final Map deviceByMac; + protected final Map deviceById; + + public DeviceFilter( + DeviceRepository deviceRepository, + MonitorLogRepository monitorLogRepository, + ActiveDeviceViewer activeDeviceViewer + ) { + this.deviceRepository = deviceRepository; + this.monitorLogRepository = monitorLogRepository; + this.activeDeviceViewer = activeDeviceViewer; + this.deviceByMac = createDeviceMapByMac(); + this.deviceById = createDeviceMapById(); + } + + public List execute(){ + List devices = find(); return devices.stream() .filter(this::judge) .toList(); } - public abstract boolean judge(Device device); + private Map createDeviceMapById() { + return deviceRepository.findAll().stream() + .collect(Collectors.toMap(device -> device.getId().id(), device -> device)); + } + + private Map createDeviceMapByMac(){ + return deviceRepository.findAll().stream() + .map(this::oneDeviceToMap) + .reduce(new HashMap<>(), (identity, deviceMap) -> { + identity.putAll(deviceMap); + return identity; + }); + } + + // Mac 주소를 Key 로 사용한 Device Map + private Map oneDeviceToMap(Device device) { + return device.getDeviceInfos().stream() + .collect(Collectors.toMap(deviceInfo -> deviceInfo.getMac().toString(), deviceInfo -> device)); + } + + protected abstract List find(); + protected abstract boolean judge(Device device); + protected abstract void raiseEvent(List devices); } From 38878e7b1c41355f1f78f9a56ba1e064484c16e6 Mon Sep 17 00:00:00 2001 From: bellmin Date: Wed, 8 Jan 2025 17:00:06 +0900 Subject: [PATCH 039/138] =?UTF-8?q?feat(main-api):=20Active=20InActive=20?= =?UTF-8?q?=ED=95=84=ED=84=B0=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../device/active/ActiveDeviceFilter.java | 56 +++++++++++++++++++ .../device/active/InActiveDeviceFilter.java | 34 +++++++++++ 2 files changed, 90 insertions(+) create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java new file mode 100644 index 00000000..36ca18ca --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java @@ -0,0 +1,56 @@ +package com.whoz_in.main_api.shared.domain.device.active; + +import com.whoz_in.domain.device.DeviceRepository; +import com.whoz_in.domain.device.model.Device; +import com.whoz_in.domain.network_log.MonitorLog; +import com.whoz_in.domain.network_log.MonitorLogRepository; +import com.whoz_in.main_api.query.device.application.active.ActiveDeviceViewer; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import org.springframework.stereotype.Component; + +@Component +public class ActiveDeviceFilter extends DeviceFilter { + + public ActiveDeviceFilter( + DeviceRepository deviceRepository, + MonitorLogRepository monitorLogRepository, + ActiveDeviceViewer activeDeviceViewer) { + super(deviceRepository, monitorLogRepository, activeDeviceViewer); + } + + @Override + protected List find() { + LocalDateTime todayMidnight = LocalDate.now().atTime(LocalTime.of(0, 0, 0)); + + List logs = monitorLogRepository.findByUpdatedAtAfterOrderByUpdatedAtDesc(todayMidnight); // 오늘 자정 이후의 로그들 , 현재 시간으로 바꿔야 할까? + Set uniqueLogs = new HashSet<>(logs); // 중복 제거 + + if (!uniqueLogs.isEmpty()) { + // 실제 판별 로직 + // 판별 로직이 허술하다. 판별하는 decider 를 구현해야 하나 + return uniqueLogs.stream() + .map(log -> deviceByMac.get(log.getMac())) + .filter(Objects::nonNull) + .toList(); + + } + + return List.of(); + } + + @Override + protected boolean judge(Device device) { + return false; + } + + @Override + protected void raiseEvent(List devices) { + + } +} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java new file mode 100644 index 00000000..caa4e413 --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java @@ -0,0 +1,34 @@ +package com.whoz_in.main_api.shared.domain.device.active; + +import com.whoz_in.domain.device.DeviceRepository; +import com.whoz_in.domain.device.model.Device; +import com.whoz_in.domain.network_log.MonitorLogRepository; +import com.whoz_in.main_api.query.device.application.active.ActiveDeviceViewer; +import java.util.List; +import org.springframework.stereotype.Component; + +@Component +public class InActiveDeviceFilter extends DeviceFilter{ + + public InActiveDeviceFilter( + DeviceRepository deviceRepository, + MonitorLogRepository monitorLogRepository, + ActiveDeviceViewer activeDeviceViewer) { + super(deviceRepository, monitorLogRepository, activeDeviceViewer); + } + + @Override + protected List find() { + return List.of(); + } + + @Override + protected boolean judge(Device device) { + return false; + } + + @Override + protected void raiseEvent(List devices) { + + } +} From 0bba87a54900cb297b91d7c6990a39eef29e2a3d Mon Sep 17 00:00:00 2001 From: bellmin Date: Wed, 8 Jan 2025 17:00:26 +0900 Subject: [PATCH 040/138] =?UTF-8?q?refactor(main-api):=20DeviceFilter=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../device/active/SpringDeviceStatusManager.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java index f7ef962a..60fd8769 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java @@ -1,7 +1,6 @@ package com.whoz_in.main_api.shared.domain.device.active; import com.whoz_in.domain.device.DeviceRepository; -import com.whoz_in.domain.device.active.DeviceStatusManager; import com.whoz_in.domain.device.model.Device; import com.whoz_in.domain.network_log.MonitorLog; import com.whoz_in.domain.network_log.MonitorLogRepository; @@ -37,16 +36,23 @@ public class SpringDeviceStatusManager implements DeviceStatusManager { private final Map deviceByMac; private final Map deviceById; + private final InActiveDeviceFilter inActiveDeviceFilter; + private final ActiveDeviceFilter activeDeviceFilter; + private static final Duration MEASURE = Duration.ofMinutes(10); // 측정 시간 10분 public SpringDeviceStatusManager( DeviceRepository deviceRepository, MonitorLogRepository monitorLogRepository, - ActiveDeviceViewer activeDeviceViewer + ActiveDeviceViewer activeDeviceViewer, + InActiveDeviceFilter inActiveDeviceFilter, + ActiveDeviceFilter activeDeviceFilter ){ this.deviceRepository = deviceRepository; this.monitorLogRepository = monitorLogRepository; this.activeDeviceViewer = activeDeviceViewer; + this.inActiveDeviceFilter = inActiveDeviceFilter; + this.activeDeviceFilter = activeDeviceFilter; this.deviceByMac = createDeviceMapByMac(); this.deviceById = createDeviceMapById(); } From b9bdf9b12562bb3897f1083bef528d3fa3836e1e Mon Sep 17 00:00:00 2001 From: bellmin Date: Wed, 8 Jan 2025 18:12:18 +0900 Subject: [PATCH 041/138] =?UTF-8?q?refactor(api-query-jpa):=20=EC=9D=B4?= =?UTF-8?q?=EB=B2=A4=ED=8A=B8=20=ED=83=80=EC=9E=85=20=EB=AF=B8=EC=8A=A4?= =?UTF-8?q?=EB=A7=A4=EC=B9=98=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - InActiveDeviceFinded --- .../api_query_jpa/device/event/DeviceStatusEventHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java index 55eadd1e..4b6876e0 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java @@ -34,7 +34,7 @@ public void saveActiveDevices(ActiveDeviceFinded event) { // 바로 위의 이벤트 핸들러에서 데이터를 수정할 수 있으므로, 격리 수준을 가장 강하게 설정 @Transactional(isolation = Isolation.SERIALIZABLE) - @EventListener(ActiveDeviceFinded.class) + @EventListener(InActiveDeviceFinded.class) public void processInActiveDevices(InActiveDeviceFinded event) { // InActiveDevice 찾는 로직 List devices = event.getDevices(); From 37d03b64615430ce3e60401751d8d214f495ff91 Mon Sep 17 00:00:00 2001 From: bellmin Date: Wed, 8 Jan 2025 20:01:43 +0900 Subject: [PATCH 042/138] =?UTF-8?q?feat(api-query-jpa):=20Member=EC=97=90?= =?UTF-8?q?=20name=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/whoz_in/api_query_jpa/member/Member.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/member/Member.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/member/Member.java index 56b01968..de79e28b 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/member/Member.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/member/Member.java @@ -16,12 +16,14 @@ + "m.id AS id, " + "m.login_id AS loginId, " + "m.password AS encodedPassword " + + "m.name as name" + "FROM member_entity m") @Synchronize({"member_entity"}) public class Member { @Id @UuidGenerator private UUID id; + private String name; private String loginId; private String encodedPassword; } From 3bde4a5ac62af64f3b71d39d3559ce79bbd94031 Mon Sep 17 00:00:00 2001 From: bellmin Date: Wed, 8 Jan 2025 20:04:18 +0900 Subject: [PATCH 043/138] =?UTF-8?q?feat(main-api,api-query-jpa):=20MemberN?= =?UTF-8?q?ame=20=EC=9D=84=20=EC=A1=B0=ED=9A=8C=ED=95=98=EA=B8=B0=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20View=20=EC=9E=91=EC=84=B1=20=EB=B0=8F=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../whoz_in/api_query_jpa/member/MemberJpaViewer.java | 9 +++++++++ .../main_api/query/member/application/MemberName.java | 8 ++++++++ .../main_api/query/member/application/MemberViewer.java | 1 + 3 files changed, 18 insertions(+) create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/member/application/MemberName.java diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/member/MemberJpaViewer.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/member/MemberJpaViewer.java index 7f3d928e..832fe805 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/member/MemberJpaViewer.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/member/MemberJpaViewer.java @@ -1,8 +1,10 @@ package com.whoz_in.api_query_jpa.member; import com.whoz_in.main_api.query.member.application.MemberAuthInfo; +import com.whoz_in.main_api.query.member.application.MemberName; import com.whoz_in.main_api.query.member.application.MemberViewer; import java.util.Optional; +import java.util.UUID; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; @@ -16,4 +18,11 @@ public Optional findAuthInfoByLoginId(String loginId) { return repository.findByLoginId(loginId) .map(member -> new MemberAuthInfo(member.getId(), member.getLoginId(), member.getEncodedPassword())); } + + @Override + public Optional findNameByMemberId(String memberId) { + return repository.findById(UUID.fromString(memberId)) + .map(member -> new MemberName(member.getName())); + + } } diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/member/application/MemberName.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/member/application/MemberName.java new file mode 100644 index 00000000..693c1dbd --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/member/application/MemberName.java @@ -0,0 +1,8 @@ +package com.whoz_in.main_api.query.member.application; + +import com.whoz_in.main_api.query.shared.application.View; + +public record MemberName( + String memberName +) implements View { +} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/member/application/MemberViewer.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/member/application/MemberViewer.java index 6024bc53..81e26864 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/member/application/MemberViewer.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/member/application/MemberViewer.java @@ -5,4 +5,5 @@ public interface MemberViewer extends Viewer { Optional findAuthInfoByLoginId(String loginId); + Optional findNameByMemberId(String memberId); } From e27fcd698e747385449328d0c6020e42cec953b0 Mon Sep 17 00:00:00 2001 From: bellmin Date: Wed, 8 Jan 2025 20:05:41 +0900 Subject: [PATCH 044/138] =?UTF-8?q?feat(main-api,api-query-jpa):=20ActiveD?= =?UTF-8?q?evice=20View=EC=97=90=20totalConnectedTime=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api_query_jpa/device/ActiveDeviceJpaViewer.java | 5 ++++- .../query/device/application/active/ActiveDevice.java | 7 +++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java index d92181ce..8fd7e7c0 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java @@ -3,7 +3,9 @@ import com.whoz_in.api_query_jpa.member.Member; import com.whoz_in.api_query_jpa.member.MemberRepository; import com.whoz_in.main_api.query.device.application.active.ActiveDevice; +import com.whoz_in.main_api.query.device.application.active.ActiveDeviceResponse; import com.whoz_in.main_api.query.device.application.active.ActiveDeviceViewer; +import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -54,6 +56,7 @@ private Optional createOptionalActiveDevice(ActiveDeviceEntity ent entity.getDeviceId(), member.getId(), entity.getActiveTime(), - entity.getInactiveTime())); + entity.getInactiveTime(), + entity.getTotalActiveTime())); } } diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java index 45e28789..645d8bff 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java @@ -1,6 +1,7 @@ package com.whoz_in.main_api.query.device.application.active; import com.whoz_in.main_api.query.shared.application.View; +import java.time.Duration; import java.time.LocalDateTime; import java.util.UUID; @@ -10,5 +11,7 @@ public record ActiveDevice( UUID deviceId, UUID memberId, LocalDateTime connectedTime, - LocalDateTime disconnectedTime -) implements View { } + LocalDateTime disconnectedTime, + Duration totalConnectedTime +) implements View { +} From 3ceb327b35c55fc110539a250cbee99be63c9786 Mon Sep 17 00:00:00 2001 From: bellmin Date: Wed, 8 Jan 2025 20:08:23 +0900 Subject: [PATCH 045/138] =?UTF-8?q?feat(main-api):=20DeviceController=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1=20=EB=B0=8F=20ActiveDeviceListHandler=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../active/ActiveDeviceListHandler.java | 51 +++++++++++++++++++ .../device/presentation/DeviceController.java | 33 ++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/presentation/DeviceController.java diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java new file mode 100644 index 00000000..412e664b --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java @@ -0,0 +1,51 @@ +package com.whoz_in.main_api.query.device.application.active; + +import com.whoz_in.main_api.query.member.application.MemberViewer; +import com.whoz_in.main_api.query.shared.application.QueryHandler; +import com.whoz_in.main_api.shared.application.Handler; +import java.time.Duration; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import lombok.RequiredArgsConstructor; + +@Handler +@RequiredArgsConstructor +public class ActiveDeviceListHandler implements QueryHandler { + + private final ActiveDeviceViewer activeDeviceViewer; + private final MemberViewer memberViewer; + + @Override + public ActiveDeviceListResponse handle(ActiveDeviceList query) { + int page = query.page(); + int size = query.size(); + String sortType = query.sortType(); + + List activeDevices = activeDeviceViewer.findAll(); + List responses = new ArrayList<>(); + + int start = page * size; + int end = start + size; + + for(int i = start; i getActiveDevices( + @RequestParam("size") int size, + @RequestParam("page") int page, + @RequestParam("sortType") String sortType + ) { + ActiveDeviceList query = new ActiveDeviceList(page, size, sortType); + ActiveDeviceListResponse response = ask(query); + return ResponseEntity.ok(response); + } + + +} From 2c161b57f73c3055727dbae9ed998eb2bc942a8a Mon Sep 17 00:00:00 2001 From: bellmin Date: Wed, 8 Jan 2025 20:17:53 +0900 Subject: [PATCH 046/138] =?UTF-8?q?feat(main-api):=20memberName=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/active/ActiveDeviceListHandler.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java index 412e664b..c53df69e 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java @@ -1,5 +1,6 @@ package com.whoz_in.main_api.query.device.application.active; +import com.whoz_in.main_api.query.member.application.MemberName; import com.whoz_in.main_api.query.member.application.MemberViewer; import com.whoz_in.main_api.query.shared.application.QueryHandler; import com.whoz_in.main_api.shared.application.Handler; @@ -30,10 +31,11 @@ public ActiveDeviceListResponse handle(ActiveDeviceList query) { for(int i = start; i new IllegalArgumentException("사용자 기기와 사용자 이름 매핑 중 예상치 못한 에러 발생")); + } } From 77ca3a220b7e120d23bf7c7d188bdc625aabcd6b Mon Sep 17 00:00:00 2001 From: bellmin Date: Wed, 8 Jan 2025 20:19:47 +0900 Subject: [PATCH 047/138] =?UTF-8?q?refactor(main-api):=20ActiveDeviceListH?= =?UTF-8?q?andler=20=EB=B9=88=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=EC=9D=BC=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=20=EB=B6=84=EA=B8=B0=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../active/ActiveDeviceListHandler.java | 46 +++++++++++-------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java index c53df69e..7a4aac45 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java @@ -6,6 +6,7 @@ import com.whoz_in.main_api.shared.application.Handler; import java.time.Duration; import java.util.ArrayList; +import java.util.Collections; import java.util.Comparator; import java.util.List; import lombok.RequiredArgsConstructor; @@ -26,27 +27,32 @@ public ActiveDeviceListResponse handle(ActiveDeviceList query) { List activeDevices = activeDeviceViewer.findAll(); List responses = new ArrayList<>(); - int start = page * size; - int end = start + size; - - for(int i = start; i Date: Wed, 8 Jan 2025 20:37:44 +0900 Subject: [PATCH 048/138] =?UTF-8?q?refactor(main-api):=20ResponseEntityGen?= =?UTF-8?q?erator=20=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../query/device/presentation/DeviceController.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/presentation/DeviceController.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/presentation/DeviceController.java index e22a0935..3422bea9 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/presentation/DeviceController.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/presentation/DeviceController.java @@ -4,6 +4,10 @@ import com.whoz_in.main_api.query.device.application.active.ActiveDeviceListResponse; import com.whoz_in.main_api.query.shared.application.QueryBus; import com.whoz_in.main_api.query.shared.presentation.QueryController; +import com.whoz_in.main_api.shared.presentation.ApiResponseCode; +import com.whoz_in.main_api.shared.presentation.CrudResponseCode; +import com.whoz_in.main_api.shared.presentation.ResponseEntityGenerator; +import com.whoz_in.main_api.shared.presentation.SuccessBody; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -19,14 +23,14 @@ protected DeviceController(QueryBus queryBus) { } @GetMapping("/active") - public ResponseEntity getActiveDevices( + public ResponseEntity> getActiveDevices( @RequestParam("size") int size, @RequestParam("page") int page, @RequestParam("sortType") String sortType ) { ActiveDeviceList query = new ActiveDeviceList(page, size, sortType); ActiveDeviceListResponse response = ask(query); - return ResponseEntity.ok(response); + return ResponseEntityGenerator.success(response, CrudResponseCode.READ); } From 908fed46774a9781fbf8be80375d64f835171446 Mon Sep 17 00:00:00 2001 From: bellmin Date: Wed, 8 Jan 2025 20:41:36 +0900 Subject: [PATCH 049/138] =?UTF-8?q?refactor(api-query-jpa):=20@Column=20?= =?UTF-8?q?=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=EC=9C=BC=EB=A1=9C?= =?UTF-8?q?=20=ED=85=8C=EC=9D=B4=EB=B8=94=20=EC=97=B4=20=EB=A7=A4=ED=95=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/whoz_in/api_query_jpa/member/Member.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/member/Member.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/member/Member.java index de79e28b..c79e11e3 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/member/Member.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/member/Member.java @@ -1,5 +1,6 @@ package com.whoz_in.api_query_jpa.member; +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Id; import java.util.UUID; @@ -13,17 +14,24 @@ @Entity @Immutable @Subselect("SELECT " - + "m.id AS id, " - + "m.login_id AS loginId, " - + "m.password AS encodedPassword " - + "m.name as name" + + "m.id," + + "m.login_id," + + "m.password," + + "m.name " + "FROM member_entity m") @Synchronize({"member_entity"}) public class Member { @Id @UuidGenerator + @Column(name = "id") private UUID id; + + @Column(name = "name") private String name; + + @Column(name = "login_id") private String loginId; + + @Column(name = "password") private String encodedPassword; } From 1b4c5536c4f16584e28c229547b5777c180f349f Mon Sep 17 00:00:00 2001 From: bellmin Date: Wed, 8 Jan 2025 20:58:51 +0900 Subject: [PATCH 050/138] =?UTF-8?q?refactor(main-api):=20page=20=EC=88=AB?= =?UTF-8?q?=EC=9E=90=20-=201?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../device/application/active/ActiveDeviceListHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java index 7a4aac45..be3f5bde 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java @@ -20,7 +20,7 @@ public class ActiveDeviceListHandler implements QueryHandler Date: Wed, 8 Jan 2025 21:11:48 +0900 Subject: [PATCH 051/138] =?UTF-8?q?refactor(main-api):=20GlobalExceptionHa?= =?UTF-8?q?ndler=EC=97=90=EC=84=9C=20=EC=97=90=EB=9F=AC=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - e.getMessage() - e.printStackTrace() --- .../presentation/MainApiGlobalExceptionHandler.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/presentation/MainApiGlobalExceptionHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/presentation/MainApiGlobalExceptionHandler.java index 7cf73455..002372d7 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/presentation/MainApiGlobalExceptionHandler.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/presentation/MainApiGlobalExceptionHandler.java @@ -1,27 +1,35 @@ package com.whoz_in.main_api.shared.presentation; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; @ControllerAdvice +@Slf4j public class MainApiGlobalExceptionHandler { // 사용자 예외 @ExceptionHandler(IllegalArgumentException.class) public ResponseEntity handleIllegalArgumentException(IllegalArgumentException e) { + log.error("[USER_ERROR] {}", e.getMessage()); + e.printStackTrace(); return ResponseEntityGenerator.fail("USER_ERROR", e.getMessage(), HttpStatus.BAD_REQUEST); } // 개발자 예외 @ExceptionHandler(IllegalStateException.class) public ResponseEntity handleIllegalStateException(IllegalStateException e) { + log.error("[SYSTEM_ERROR] {}", e.getMessage()); + e.printStackTrace(); return ResponseEntityGenerator.fail("SYSTEM_ERROR", e.getMessage(), HttpStatus.BAD_REQUEST); } // 나머지 예외 @ExceptionHandler(Exception.class) public ResponseEntity handleException(Exception e) { + log.error("[UNEXPECTED_ERROR] {}", e.getMessage()); + e.printStackTrace(); return ResponseEntityGenerator.fail("UNEXPECTED_ERROR", e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); } From b8410b2577307903a39e18792467c2265e1ce58b Mon Sep 17 00:00:00 2001 From: bellmin Date: Wed, 8 Jan 2025 21:23:17 +0900 Subject: [PATCH 052/138] =?UTF-8?q?refactor(main-api):=20null=20=EA=B0=92?= =?UTF-8?q?=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - connectedTime 이 null 일 경우 - disConnectedTime 이 null 일 경우 - totalConnectedTime 이 null 일 경우 --- .../active/ActiveDeviceListHandler.java | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java index be3f5bde..bd6d2acd 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java @@ -5,6 +5,7 @@ import com.whoz_in.main_api.query.shared.application.QueryHandler; import com.whoz_in.main_api.shared.application.Handler; import java.time.Duration; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -30,17 +31,24 @@ public ActiveDeviceListResponse handle(ActiveDeviceList query) { if(!activeDevices.isEmpty()) { int start = page * size; - int end = start + size; + int end = Math.min((start + size), activeDevices.size()); for (int i = start; i < end; i++) { ActiveDevice activeDevice = activeDevices.get(i); + + String deviceId = activeDevice.deviceId().toString(); + String memberId = activeDevice.memberId().toString(); String memberName = getMemberName(activeDevice.memberId().toString()); + LocalDateTime connectedTime = activeDevice.connectedTime(); + LocalDateTime disConnectedTime = activeDevice.disconnectedTime() == null ? LocalDateTime.now() : activeDevice.disconnectedTime(); + Duration totalConnectedTime = activeDevice.totalConnectedTime() == null ? Duration.between(LocalDateTime.now(), connectedTime) : activeDevice.totalConnectedTime(); + ActiveDeviceResponse oneResponse = new ActiveDeviceResponse( - activeDevice.deviceId().toString(), - activeDevice.memberId().toString(), + deviceId, + memberId, memberName, - Duration.between(activeDevice.disconnectedTime(), activeDevice.connectedTime()).toString(), - activeDevice.totalConnectedTime().toString() + Duration.between(disConnectedTime, connectedTime).toString(), + totalConnectedTime.toString() ); responses.add(oneResponse); } @@ -57,6 +65,10 @@ public ActiveDeviceListResponse handle(ActiveDeviceList query) { return new ActiveDeviceListResponse(responses); } + private String calculateContinuousTime(ActiveDevice activeDevice){ + return ""; + } + private String getMemberName(String memberId){ return memberViewer.findNameByMemberId(memberId) .map(MemberName::memberName) From e0612b090dc848520d87f50a9561ba80e37ec665 Mon Sep 17 00:00:00 2001 From: bellmin Date: Thu, 9 Jan 2025 00:42:30 +0900 Subject: [PATCH 053/138] =?UTF-8?q?feat(main-api):=20totalConnectedTime,?= =?UTF-8?q?=20continuousTime=20=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../device/application/active/ActiveDevice.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java index 645d8bff..7cd19b92 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java @@ -11,7 +11,20 @@ public record ActiveDevice( UUID deviceId, UUID memberId, LocalDateTime connectedTime, - LocalDateTime disconnectedTime, + LocalDateTime disConnectedTime, Duration totalConnectedTime ) implements View { + + public Duration totalConnectedTime(){ + if(totalConnectedTime!=null){ + return totalConnectedTime.plus(continuousTime()); + } + return continuousTime(); + } + + public Duration continuousTime(){ + if(disConnectedTime!=null) return Duration.between(connectedTime,disConnectedTime); + return Duration.between(connectedTime, LocalDateTime.now()); + } + } From 18760f414db92c8f1e2a65425d73533731127282 Mon Sep 17 00:00:00 2001 From: bellmin Date: Thu, 9 Jan 2025 00:44:32 +0900 Subject: [PATCH 054/138] =?UTF-8?q?refactor(api-query-jpa):=20save=20?= =?UTF-8?q?=EB=A9=94=EC=86=8C=EB=93=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - putIfAbsent 메소드 사용 --- .../api_query_jpa/device/InMemoryActiveDeviceRepository.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/InMemoryActiveDeviceRepository.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/InMemoryActiveDeviceRepository.java index 1c7c34ff..873da924 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/InMemoryActiveDeviceRepository.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/InMemoryActiveDeviceRepository.java @@ -5,9 +5,11 @@ import java.util.Map; import java.util.Optional; import java.util.UUID; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Repository; @Repository +@Slf4j public class InMemoryActiveDeviceRepository { private final Map repository; @@ -18,7 +20,7 @@ public InMemoryActiveDeviceRepository(){ public UUID save(ActiveDeviceEntity device){ UUID id = device.getDeviceId(); - repository.put(id, device); + repository.putIfAbsent(id, device); return device.getDeviceId(); } From 28e4fc6325c08225c7eb19588bd73d82b6ce990b Mon Sep 17 00:00:00 2001 From: bellmin Date: Thu, 9 Jan 2025 00:52:04 +0900 Subject: [PATCH 055/138] =?UTF-8?q?feat(main-api):=20=EB=8F=99=EB=B3=91=20?= =?UTF-8?q?=ED=98=84=ED=99=A9=20=EC=A1=B0=ED=9A=8C=20api=20=ED=97=88?= =?UTF-8?q?=EC=9A=A9=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main_api/config/security/SecurityFilterChainConfig.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java b/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java index 1a30f5cb..9bea23e3 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java @@ -54,7 +54,8 @@ public SecurityFilterChain oauth2FilterChain(HttpSecurity httpSecurity) throws E @Order(2) public SecurityFilterChain noAuthenticationFilterChain(HttpSecurity httpSecurity) throws Exception { httpSecurity.securityMatcher( - "/api/v1/signup/oauth" + "/api/v1/signup/oauth", + "/api/v1/devices/active" ); httpSecurity.authorizeHttpRequests(auth-> auth.anyRequest().permitAll()); From 570395b9e53f919327513621f0a7e421d160c638 Mon Sep 17 00:00:00 2001 From: bellmin Date: Thu, 9 Jan 2025 00:53:08 +0900 Subject: [PATCH 056/138] =?UTF-8?q?refactor(main-api):=20ActiveDeviceListH?= =?UTF-8?q?andler=20=EC=8B=9C=EA=B0=84=20=EA=B3=84=EC=82=B0=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/active/ActiveDeviceListHandler.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java index bd6d2acd..94da2f8d 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java @@ -7,7 +7,6 @@ import java.time.Duration; import java.time.LocalDateTime; import java.util.ArrayList; -import java.util.Collections; import java.util.Comparator; import java.util.List; import lombok.RequiredArgsConstructor; @@ -39,16 +38,15 @@ public ActiveDeviceListResponse handle(ActiveDeviceList query) { String deviceId = activeDevice.deviceId().toString(); String memberId = activeDevice.memberId().toString(); String memberName = getMemberName(activeDevice.memberId().toString()); - LocalDateTime connectedTime = activeDevice.connectedTime(); - LocalDateTime disConnectedTime = activeDevice.disconnectedTime() == null ? LocalDateTime.now() : activeDevice.disconnectedTime(); - Duration totalConnectedTime = activeDevice.totalConnectedTime() == null ? Duration.between(LocalDateTime.now(), connectedTime) : activeDevice.totalConnectedTime(); + Duration continuousTime = activeDevice.continuousTime(); + Duration totalConnectedTime = activeDevice.totalConnectedTime(); ActiveDeviceResponse oneResponse = new ActiveDeviceResponse( deviceId, memberId, memberName, - Duration.between(disConnectedTime, connectedTime).toString(), - totalConnectedTime.toString() + String.format("%s시간 %s분", continuousTime.toHours(), continuousTime.toMinutes()), + String.format("%s시간 %s분", totalConnectedTime.toHours(), totalConnectedTime.toMinutes()) ); responses.add(oneResponse); } From a4070e126af5e2b31e184305613f2188acbe5f09 Mon Sep 17 00:00:00 2001 From: bellmin Date: Thu, 9 Jan 2025 00:54:13 +0900 Subject: [PATCH 057/138] =?UTF-8?q?refactor(network-api):=20room-setting?= =?UTF-8?q?=20=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/whoz_in/network_api/config/NetworkConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/config/NetworkConfig.java b/modules/network-api/src/main/java/com/whoz_in/network_api/config/NetworkConfig.java index 39174282..9d1f917c 100644 --- a/modules/network-api/src/main/java/com/whoz_in/network_api/config/NetworkConfig.java +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/config/NetworkConfig.java @@ -48,7 +48,7 @@ private String generateCommand(String commandTemplate, String interfaceName) { @Getter - @ConfigurationProperties(prefix = "log-writer-setting") + @ConfigurationProperties(prefix = "room-setting") public static class NetworkConfigProperties { private final String room; From 3605bf6d2195baa5aa572bf8781d88312e24ccb4 Mon Sep 17 00:00:00 2001 From: bellmin Date: Thu, 9 Jan 2025 00:57:38 +0900 Subject: [PATCH 058/138] =?UTF-8?q?refactor(network-api):=20room-setting?= =?UTF-8?q?=20=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../network-api/src/main/resources/application-network-api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/network-api/src/main/resources/application-network-api.yml b/modules/network-api/src/main/resources/application-network-api.yml index 4f1a51c1..1d5872a8 100644 --- a/modules/network-api/src/main/resources/application-network-api.yml +++ b/modules/network-api/src/main/resources/application-network-api.yml @@ -2,7 +2,7 @@ spring: config: import: #해당 room의 network interface 설정 파일 - - "classpath:env-network-interface-setting.yml" + - "classpath:env-network-room-setting.yml" #logging 모듈의 설정 파일 - "classpath:application-logging.yml" #domain-jpa 모듈의 설정 파일 From 08e3c9e0dbbb4571863778297a5974282e2c9841 Mon Sep 17 00:00:00 2001 From: bellmin Date: Thu, 9 Jan 2025 01:11:19 +0900 Subject: [PATCH 059/138] =?UTF-8?q?refactor(domain):=20=ED=95=84=EC=9A=94?= =?UTF-8?q?=20=EC=97=86=EB=8A=94=20=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/whoz_in/domain/network_log/MonitorLogRepository.java | 1 - .../whoz_in/domain_jpa/monitor/MonitorLogEntityRepository.java | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/domain/src/main/java/com/whoz_in/domain/network_log/MonitorLogRepository.java b/modules/domain/src/main/java/com/whoz_in/domain/network_log/MonitorLogRepository.java index c064964a..c5527c56 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/network_log/MonitorLogRepository.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/network_log/MonitorLogRepository.java @@ -7,7 +7,6 @@ public interface MonitorLogRepository { void save(MonitorLog log); void saveAll(Collection logs); - boolean existsLatestByMacAfter(String mac, LocalDateTime time); List findAll(); List findByUpdatedAtAfterOrderByUpdatedAtDesc(LocalDateTime updatedAt); // 해당 시간 이후의 로그를 가져오기 // TODO: 이전 로그까지 가져와야 할까? diff --git a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/monitor/MonitorLogEntityRepository.java b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/monitor/MonitorLogEntityRepository.java index 95dedfe6..46dd020c 100644 --- a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/monitor/MonitorLogEntityRepository.java +++ b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/monitor/MonitorLogEntityRepository.java @@ -4,6 +4,7 @@ import java.util.List; import java.time.LocalDateTime; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; public interface MonitorLogEntityRepository extends JpaRepository { From 6f2067517ed42d73f4db5874d18479a159fb6ec2 Mon Sep 17 00:00:00 2001 From: bellmin Date: Thu, 9 Jan 2025 01:16:14 +0900 Subject: [PATCH 060/138] =?UTF-8?q?refactor(main-api):=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - DeviceController -> DeviceQueryController --- .../{DeviceController.java => DeviceQueryController.java} | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) rename modules/main-api/src/main/java/com/whoz_in/main_api/query/device/presentation/{DeviceController.java => DeviceQueryController.java} (89%) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/presentation/DeviceController.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/presentation/DeviceQueryController.java similarity index 89% rename from modules/main-api/src/main/java/com/whoz_in/main_api/query/device/presentation/DeviceController.java rename to modules/main-api/src/main/java/com/whoz_in/main_api/query/device/presentation/DeviceQueryController.java index 3422bea9..5a35b91b 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/presentation/DeviceController.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/presentation/DeviceQueryController.java @@ -4,7 +4,6 @@ import com.whoz_in.main_api.query.device.application.active.ActiveDeviceListResponse; import com.whoz_in.main_api.query.shared.application.QueryBus; import com.whoz_in.main_api.query.shared.presentation.QueryController; -import com.whoz_in.main_api.shared.presentation.ApiResponseCode; import com.whoz_in.main_api.shared.presentation.CrudResponseCode; import com.whoz_in.main_api.shared.presentation.ResponseEntityGenerator; import com.whoz_in.main_api.shared.presentation.SuccessBody; @@ -16,9 +15,9 @@ @RestController @RequestMapping("/api/v1/devices") -public class DeviceController extends QueryController { +public class DeviceQueryController extends QueryController { - protected DeviceController(QueryBus queryBus) { + protected DeviceQueryController(QueryBus queryBus) { super(queryBus); } From 9600edf1ababca4806c2af83c96745f3490ca420 Mon Sep 17 00:00:00 2001 From: bellmin Date: Thu, 9 Jan 2025 01:35:35 +0900 Subject: [PATCH 061/138] =?UTF-8?q?refactor(main-api,api-query-jpa):=20isA?= =?UTF-8?q?ctive=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java | 4 ++++ .../query/device/application/active/ActiveDevice.java | 3 ++- .../query/device/application/active/ActiveDeviceResponse.java | 3 ++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java index 52863913..831f0074 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java @@ -24,16 +24,20 @@ public class ActiveDeviceEntity { private Duration totalActiveTime; + private boolean isActive; + private ActiveDeviceEntity(UUID deviceId, LocalDateTime activeTime) { this.deviceId = deviceId; this.activeTime = activeTime; } public void activeOn(LocalDateTime activeTime){ + this.isActive = true; this.activeTime = activeTime; } public void inActiveOn(LocalDateTime inactiveTime){ + this.isActive = false; this.inactiveTime = inactiveTime; this.totalActiveTime = this.totalActiveTime.plus(Duration.between(this.activeTime, this.inactiveTime)); } diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java index 7cd19b92..5cc5e10c 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java @@ -12,7 +12,8 @@ public record ActiveDevice( UUID memberId, LocalDateTime connectedTime, LocalDateTime disConnectedTime, - Duration totalConnectedTime + Duration totalConnectedTime, + boolean isActive ) implements View { public Duration totalConnectedTime(){ diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceResponse.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceResponse.java index 3f3bc057..87a4860a 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceResponse.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceResponse.java @@ -7,6 +7,7 @@ public record ActiveDeviceResponse( String memberId, String memberName, String continuousActiveTime, - String totalActiveTime + String totalActiveTime, + boolean isActive ) implements Response { } From 0f29b37abe5a0c79c20e4fc9554e2f62db59461e Mon Sep 17 00:00:00 2001 From: bellmin Date: Thu, 9 Jan 2025 01:38:53 +0900 Subject: [PATCH 062/138] =?UTF-8?q?refactor(main-api,api-query-jpa):=20isA?= =?UTF-8?q?ctive=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java | 1 + .../whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java | 3 ++- .../device/application/active/ActiveDeviceListHandler.java | 4 +++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java index 831f0074..dd9ba39e 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java @@ -29,6 +29,7 @@ public class ActiveDeviceEntity { private ActiveDeviceEntity(UUID deviceId, LocalDateTime activeTime) { this.deviceId = deviceId; this.activeTime = activeTime; + this.isActive = true; } public void activeOn(LocalDateTime activeTime){ diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java index 8fd7e7c0..1c446b50 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java @@ -57,6 +57,7 @@ private Optional createOptionalActiveDevice(ActiveDeviceEntity ent member.getId(), entity.getActiveTime(), entity.getInactiveTime(), - entity.getTotalActiveTime())); + entity.getTotalActiveTime(), + entity.isActive())); } } diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java index 94da2f8d..fafdf1ec 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java @@ -40,13 +40,15 @@ public ActiveDeviceListResponse handle(ActiveDeviceList query) { String memberName = getMemberName(activeDevice.memberId().toString()); Duration continuousTime = activeDevice.continuousTime(); Duration totalConnectedTime = activeDevice.totalConnectedTime(); + boolean isActive = activeDevice.isActive(); ActiveDeviceResponse oneResponse = new ActiveDeviceResponse( deviceId, memberId, memberName, String.format("%s시간 %s분", continuousTime.toHours(), continuousTime.toMinutes()), - String.format("%s시간 %s분", totalConnectedTime.toHours(), totalConnectedTime.toMinutes()) + String.format("%s시간 %s분", totalConnectedTime.toHours(), totalConnectedTime.toMinutes()), + isActive ); responses.add(oneResponse); } From 81d099c92ed1081217430ec518a35b960cb59718 Mon Sep 17 00:00:00 2001 From: bellmin Date: Thu, 9 Jan 2025 02:12:30 +0900 Subject: [PATCH 063/138] =?UTF-8?q?refactor(main-api):=20monitorLog=2010?= =?UTF-8?q?=EB=B6=84=20=EC=A0=84=20=EB=A1=9C=EA=B7=B8=EB=93=A4=EB=A1=9C?= =?UTF-8?q?=EB=A7=8C=20=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/device/active/SpringDeviceStatusManager.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java index 0bc9d6ac..29e985dd 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java @@ -67,9 +67,9 @@ public void activeDeviceFind() { log.info("[DeviceStatusManager] 처리할 정보 없음"); return; } - LocalDateTime todayMidnight = LocalDate.now().atTime(LocalTime.of(0, 0, 0)); + LocalDateTime before10Minute = LocalDateTime.now().minusMinutes(10); - List logs = monitorLogRepository.findByUpdatedAtAfterOrderByUpdatedAtDesc(todayMidnight); // 오늘 자정 이후의 로그들 , 현재 시간으로 바꿔야 할까? + List logs = monitorLogRepository.findByUpdatedAtAfterOrderByUpdatedAtDesc(before10Minute); // 10분 전 로그 조회 Set uniqueLogs = new HashSet<>(logs); // 중복 제거 if (!uniqueLogs.isEmpty()) { @@ -92,9 +92,10 @@ public void inActiveDeviceFind() { log.info("[DeviceStatusManager] 처리할 정보 없음"); return; } - List activeDevices = activeDeviceViewer.findAll(); + LocalDateTime before10Minute = LocalDateTime.now().minusMinutes(10); - List logs = monitorLogRepository.findAll(); + List activeDevices = activeDeviceViewer.findAll(); + List logs = monitorLogRepository.findByUpdatedAtAfterOrderByUpdatedAtDesc(before10Minute); List monitorLogDeviceIds = logs.stream() .map(log -> deviceByMac.get(log.getMac())) .filter(Objects::nonNull) From 9060b6e3f15c9f89dc0fb7bc8e27d50733347101 Mon Sep 17 00:00:00 2001 From: bellmin Date: Thu, 9 Jan 2025 02:22:53 +0900 Subject: [PATCH 064/138] =?UTF-8?q?refactor(api-query-jpa):=20ConcurrentHa?= =?UTF-8?q?shMap=20=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api_query_jpa/device/InMemoryActiveDeviceRepository.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/InMemoryActiveDeviceRepository.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/InMemoryActiveDeviceRepository.java index 873da924..d722cd1e 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/InMemoryActiveDeviceRepository.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/InMemoryActiveDeviceRepository.java @@ -5,6 +5,7 @@ import java.util.Map; import java.util.Optional; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Repository; @@ -15,7 +16,7 @@ public class InMemoryActiveDeviceRepository { private final Map repository; public InMemoryActiveDeviceRepository(){ - this.repository = new HashMap<>(); + this.repository = new ConcurrentHashMap<>(); } public UUID save(ActiveDeviceEntity device){ From 0ac2341e84a07b570314427abb0f63a41c76725d Mon Sep 17 00:00:00 2001 From: bellmin Date: Thu, 9 Jan 2025 02:24:18 +0900 Subject: [PATCH 065/138] =?UTF-8?q?refactor(api-query-jpa):=20=EA=B2=A9?= =?UTF-8?q?=EB=A6=AC=20=EC=88=98=EC=A4=80=20default=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../device/event/DeviceStatusEventHandler.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java index 4b6876e0..ad4a2301 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java @@ -21,7 +21,7 @@ public class DeviceStatusEventHandler { // TODO: JPA 적용 private final InMemoryActiveDeviceRepository activeDeviceRepository; - @Transactional(isolation = Isolation.SERIALIZABLE) + @Transactional(isolation = Isolation.DEFAULT) @EventListener(ActiveDeviceFinded.class) public void saveActiveDevices(ActiveDeviceFinded event) { List devices = event.getDevices(); @@ -32,8 +32,8 @@ public void saveActiveDevices(ActiveDeviceFinded event) { activeDeviceRepository.saveAll(entities); } - // 바로 위의 이벤트 핸들러에서 데이터를 수정할 수 있으므로, 격리 수준을 가장 강하게 설정 - @Transactional(isolation = Isolation.SERIALIZABLE) + // 바로 위의 이벤트 핸들러에서 데이터를 수정할 수 있지만, ConcurrentHashMap 사용하므로 격리 수준을 default로 설정 + @Transactional(isolation = Isolation.DEFAULT) @EventListener(InActiveDeviceFinded.class) public void processInActiveDevices(InActiveDeviceFinded event) { // InActiveDevice 찾는 로직 From cc71c6bc72363e8a62d19191a78612eddb3c835e Mon Sep 17 00:00:00 2001 From: bellmin Date: Thu, 9 Jan 2025 02:33:56 +0900 Subject: [PATCH 066/138] =?UTF-8?q?refactor(main-api):=20=EC=A0=84?= =?UTF-8?q?=EC=B2=B4=EC=A0=81=EC=9D=B8=20=EC=BD=94=EB=93=9C=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../active/SpringDeviceStatusManager.java | 105 +++++++++--------- 1 file changed, 53 insertions(+), 52 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java index 29e985dd..3ecb901f 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java @@ -41,7 +41,7 @@ public class SpringDeviceStatusManager implements DeviceStatusManager { private final InActiveDeviceFilter inActiveDeviceFilter; private final ActiveDeviceFilter activeDeviceFilter; - private static final Duration MEASURE = Duration.ofMinutes(10); // 측정 시간 10분 + private static final Duration MEASURE = Duration.ofMinutes(1); // 측정 시간 10분 public SpringDeviceStatusManager( DeviceRepository deviceRepository, @@ -63,75 +63,76 @@ public SpringDeviceStatusManager( @Override @Scheduled(fixedRate = 5000) public void activeDeviceFind() { - if(deviceByMac.keySet().isEmpty() || deviceById.keySet().isEmpty()){ - log.info("[DeviceStatusManager] 처리할 정보 없음"); - return; - } - LocalDateTime before10Minute = LocalDateTime.now().minusMinutes(10); + LocalDateTime before10Minute = LocalDateTime.now().minusMinutes(10); List logs = monitorLogRepository.findByUpdatedAtAfterOrderByUpdatedAtDesc(before10Minute); // 10분 전 로그 조회 Set uniqueLogs = new HashSet<>(logs); // 중복 제거 - if (!uniqueLogs.isEmpty()) { - // 실제 판별 로직 - // 판별 로직이 허술하다. 판별하는 decider 를 구현해야 하나 - List activeDevices = uniqueLogs.stream() - .map(log -> deviceByMac.get(log.getMac())) - .filter(Objects::nonNull) - .map(device -> device.getId().id()) - .toList(); - - Events.raise(new ActiveDeviceFinded(activeDevices, uniqueLogs.stream().toList())); - } - } - - @Override - @Scheduled(fixedRate = 5000) - public void inActiveDeviceFind() { - if(deviceByMac.keySet().isEmpty() || deviceById.keySet().isEmpty()){ + if(deviceByMac.keySet().isEmpty() || deviceById.keySet().isEmpty() || uniqueLogs.isEmpty()){ log.info("[DeviceStatusManager] 처리할 정보 없음"); return; } - LocalDateTime before10Minute = LocalDateTime.now().minusMinutes(10); - - List activeDevices = activeDeviceViewer.findAll(); - List logs = monitorLogRepository.findByUpdatedAtAfterOrderByUpdatedAtDesc(before10Minute); - List monitorLogDeviceIds = logs.stream() + // 실제 판별 로직 + // 판별 로직이 허술하다. 판별하는 decider 를 구현해야 하나 + List activeDevices = uniqueLogs.stream() .map(log -> deviceByMac.get(log.getMac())) .filter(Objects::nonNull) .map(device -> device.getId().id()) .toList(); - Map logTimeByDeviceId = logs.stream() - .filter(log -> deviceByMac.containsKey(log.getMac())) - .collect(Collectors.toMap( - log-> deviceByMac.get(log.getMac()).getId().id(), - MonitorLog::getUpdatedAt - )); + Events.raise(new ActiveDeviceFinded(activeDevices, uniqueLogs.stream().toList())); - activeDevices = activeDevices.stream() - .filter(activeDevice -> !monitorLogDeviceIds.contains(activeDevice.deviceId())) - .filter(activeDevice -> { - LocalDateTime logCreatedTime = logTimeByDeviceId.get(activeDevice.deviceId()); - LocalDateTime activeDeviceActiveTime = activeDevice.connectedTime(); + } - Duration term = Duration.between(logCreatedTime, activeDeviceActiveTime); + @Override + @Scheduled(fixedRate = 5000) + public void inActiveDeviceFind() { + List activeDevices = activeDeviceViewer.findAll(); - boolean isInActive = term.compareTo(MEASURE) > 0; // 로그 발생 시간과의 차이가 기준치보다 클 경우 InActive + if(!activeDevices.isEmpty()) { - return isInActive; - })// 모니터 로그에 없는 Device 만 추출 (InActive 후보) - .toList(); + LocalDateTime before10Minute = LocalDateTime.now().minusMinutes(10); - List inActiveDevices = activeDevices.stream() - .map(activeDevice -> { - UUID id = activeDevice.deviceId(); - return deviceById.get(id); - }) - .map(device -> device.getId().id()) - .toList(); + List logs = monitorLogRepository.findByUpdatedAtAfterOrderByUpdatedAtDesc(before10Minute); + List monitorLogDeviceIds = logs.stream() + .map(log -> deviceByMac.get(log.getMac())) + .filter(Objects::nonNull) + .map(device -> device.getId().id()) + .toList(); + Map logTimeByDeviceId = logs.stream() + .filter(log -> deviceByMac.containsKey(log.getMac())) + .collect(Collectors.toMap( + log -> deviceByMac.get(log.getMac()).getId().id(), + MonitorLog::getUpdatedAt + )); + + activeDevices = activeDevices.stream() + .filter(activeDevice -> !monitorLogDeviceIds.contains( + activeDevice.deviceId())) // 모니터 로그에 없는 Device 만 추출 (InActive 후보) + .filter(activeDevice -> { + LocalDateTime logCreatedTime = logTimeByDeviceId.get(activeDevice.deviceId()); + LocalDateTime activeDeviceActiveTime = activeDevice.connectedTime(); + + Duration term = Duration.between(logCreatedTime, activeDeviceActiveTime); + + boolean isInActive = term.compareTo(MEASURE) > 0; // 로그 발생 시간과의 차이가 기준치보다 클 경우 InActive + + return isInActive; + }) + .toList(); - Events.raise(new InActiveDeviceFinded(inActiveDevices)); + List inActiveDevices = activeDevices.stream() + .map(activeDevice -> { + UUID id = activeDevice.deviceId(); + return deviceById.get(id); + }) + .map(device -> device.getId().id()) + .toList(); + + Events.raise(new InActiveDeviceFinded(inActiveDevices)); + } else { + log.info("[DeviceStatusManager] 처리할 정보 없음"); + } } private Map createDeviceMapById() { From 817b548c60f6b38029f7b13b63cbb6830ab590bc Mon Sep 17 00:00:00 2001 From: bellmin Date: Thu, 9 Jan 2025 02:35:02 +0900 Subject: [PATCH 067/138] =?UTF-8?q?refactor(main-api):=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=20=EB=AC=B8=EA=B5=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/device/active/SpringDeviceStatusManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java index 3ecb901f..baa7edf2 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java @@ -69,7 +69,7 @@ public void activeDeviceFind() { Set uniqueLogs = new HashSet<>(logs); // 중복 제거 if(deviceByMac.keySet().isEmpty() || deviceById.keySet().isEmpty() || uniqueLogs.isEmpty()){ - log.info("[DeviceStatusManager] 처리할 정보 없음"); + log.info("[ActiveDeviceFind] 처리할 정보 없음"); return; } // 실제 판별 로직 @@ -131,7 +131,7 @@ public void inActiveDeviceFind() { Events.raise(new InActiveDeviceFinded(inActiveDevices)); } else { - log.info("[DeviceStatusManager] 처리할 정보 없음"); + log.info("[InActiveDeviceFind] 처리할 정보 없음"); } } From e6c1c4510cba64323b418aee08787ebf980a5c8e Mon Sep 17 00:00:00 2001 From: bellmin Date: Thu, 9 Jan 2025 02:59:26 +0900 Subject: [PATCH 068/138] =?UTF-8?q?refactor(api-query-jpa):=20totalActiveT?= =?UTF-8?q?ime=EC=9D=B4=20null=20=EC=9D=BC=20=EA=B2=BD=EC=9A=B0=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../whoz_in/api_query_jpa/device/ActiveDeviceEntity.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java index dd9ba39e..2c8fafb9 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java @@ -4,6 +4,7 @@ import jakarta.persistence.Id; import java.time.Duration; import java.time.LocalDateTime; +import java.util.Objects; import java.util.UUID; import lombok.AccessLevel; import lombok.Getter; @@ -40,7 +41,12 @@ public void activeOn(LocalDateTime activeTime){ public void inActiveOn(LocalDateTime inactiveTime){ this.isActive = false; this.inactiveTime = inactiveTime; - this.totalActiveTime = this.totalActiveTime.plus(Duration.between(this.activeTime, this.inactiveTime)); + addTotalActiveTime(); + } + + private void addTotalActiveTime(){ + Duration add = Duration.between(activeTime, inactiveTime); + this.totalActiveTime = Objects.nonNull(totalActiveTime) ? totalActiveTime.plus(add) : add; } public static ActiveDeviceEntity create(UUID deviceId, LocalDateTime activeTime){ From 656a09199394b3ef58c3f1a8d0c1ead3feddbbbe Mon Sep 17 00:00:00 2001 From: bellmin Date: Thu, 9 Jan 2025 03:05:15 +0900 Subject: [PATCH 069/138] =?UTF-8?q?refactor(api-query-jpa):=20=EA=B2=A9?= =?UTF-8?q?=EB=A6=AC=20=EC=88=98=EC=A4=91=20=EC=B5=9C=EA=B0=95=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api_query_jpa/device/event/DeviceStatusEventHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java index ad4a2301..b2e9b512 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java @@ -21,7 +21,7 @@ public class DeviceStatusEventHandler { // TODO: JPA 적용 private final InMemoryActiveDeviceRepository activeDeviceRepository; - @Transactional(isolation = Isolation.DEFAULT) + @Transactional(isolation = Isolation.SERIALIZABLE) @EventListener(ActiveDeviceFinded.class) public void saveActiveDevices(ActiveDeviceFinded event) { List devices = event.getDevices(); @@ -33,7 +33,7 @@ public void saveActiveDevices(ActiveDeviceFinded event) { } // 바로 위의 이벤트 핸들러에서 데이터를 수정할 수 있지만, ConcurrentHashMap 사용하므로 격리 수준을 default로 설정 - @Transactional(isolation = Isolation.DEFAULT) + @Transactional(isolation = Isolation.SERIALIZABLE) @EventListener(InActiveDeviceFinded.class) public void processInActiveDevices(InActiveDeviceFinded event) { // InActiveDevice 찾는 로직 From 60bb5a27712d272ae11ef89cc69d5e93f1d077a7 Mon Sep 17 00:00:00 2001 From: coco3x Date: Thu, 9 Jan 2025 23:01:54 +0900 Subject: [PATCH 070/138] =?UTF-8?q?refactor(network-api):=20IpHolder=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../network_api/common/util/IpHolder.java | 22 +++------------- .../common/util/RequesterInfo.java | 11 -------- .../interceptor/ClientIpInterceptor.java | 7 +++--- .../interceptor/ThreadLocalIpHolder.java | 25 +++++++++++++++++++ 4 files changed, 31 insertions(+), 34 deletions(-) delete mode 100644 modules/network-api/src/main/java/com/whoz_in/network_api/common/util/RequesterInfo.java create mode 100644 modules/network-api/src/main/java/com/whoz_in/network_api/config/interceptor/ThreadLocalIpHolder.java diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/common/util/IpHolder.java b/modules/network-api/src/main/java/com/whoz_in/network_api/common/util/IpHolder.java index c22cd375..ef23cbc5 100644 --- a/modules/network-api/src/main/java/com/whoz_in/network_api/common/util/IpHolder.java +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/common/util/IpHolder.java @@ -1,22 +1,6 @@ package com.whoz_in.network_api.common.util; -import org.springframework.stereotype.Component; - -@Component -public class IpHolder implements RequesterInfo{ - - private final ThreadLocal ip = new ThreadLocal<>(); - - public void setIp(String ip) { - this.ip.set(ip); - } - - public String getIp(){ - return ip.get(); - } - - public void clear(){ - ip.remove(); - } - +//요청의 아이피를 꺼낼 수 있는 인터페이스 +public interface IpHolder { + String getIp(); } diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/common/util/RequesterInfo.java b/modules/network-api/src/main/java/com/whoz_in/network_api/common/util/RequesterInfo.java deleted file mode 100644 index a1bf46ce..00000000 --- a/modules/network-api/src/main/java/com/whoz_in/network_api/common/util/RequesterInfo.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.whoz_in.network_api.common.util; - -public interface RequesterInfo { - - String getIp(); - - void setIp(String ip); - - void clear(); - -} diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/config/interceptor/ClientIpInterceptor.java b/modules/network-api/src/main/java/com/whoz_in/network_api/config/interceptor/ClientIpInterceptor.java index 9b10a41e..5373e7ce 100644 --- a/modules/network-api/src/main/java/com/whoz_in/network_api/config/interceptor/ClientIpInterceptor.java +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/config/interceptor/ClientIpInterceptor.java @@ -1,6 +1,5 @@ package com.whoz_in.network_api.config.interceptor; -import com.whoz_in.network_api.common.util.RequesterInfo; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; @@ -12,19 +11,19 @@ @RequiredArgsConstructor public class ClientIpInterceptor implements HandlerInterceptor { - private final RequesterInfo requesterInfo; + private final ThreadLocalIpHolder ipHolder; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - requesterInfo.setIp(request.getRemoteAddr()); + ipHolder.setIp(request.getRemoteAddr()); return HandlerInterceptor.super.preHandle(request, response, handler); } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { - requesterInfo.clear(); + ipHolder.clear(); HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); } } diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/config/interceptor/ThreadLocalIpHolder.java b/modules/network-api/src/main/java/com/whoz_in/network_api/config/interceptor/ThreadLocalIpHolder.java new file mode 100644 index 00000000..d61139ca --- /dev/null +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/config/interceptor/ThreadLocalIpHolder.java @@ -0,0 +1,25 @@ +package com.whoz_in.network_api.config.interceptor; + +import com.whoz_in.network_api.common.util.IpHolder; +import org.springframework.stereotype.Component; + +//ThreadLocal로 구현 +@Component +public class ThreadLocalIpHolder implements IpHolder { + + private static final ThreadLocal ip = new ThreadLocal<>(); + + public void setIp(String ip) { + ThreadLocalIpHolder.ip.set(ip); + } + + @Override + public String getIp(){ + return ip.get(); + } + + public void clear(){ + ip.remove(); + } + +} From 0460d2d75de58e33d0103c0f39ec880b7af3faf1 Mon Sep 17 00:00:00 2001 From: coco3x Date: Thu, 9 Jan 2025 23:03:23 +0900 Subject: [PATCH 071/138] =?UTF-8?q?update(network-api):=20=EC=BB=A8?= =?UTF-8?q?=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/IpAddressController.java | 25 -------------- .../controller/NetworkApiController.java | 34 +++++++++++++++++++ 2 files changed, 34 insertions(+), 25 deletions(-) delete mode 100644 modules/network-api/src/main/java/com/whoz_in/network_api/controller/IpAddressController.java create mode 100644 modules/network-api/src/main/java/com/whoz_in/network_api/controller/NetworkApiController.java diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/controller/IpAddressController.java b/modules/network-api/src/main/java/com/whoz_in/network_api/controller/IpAddressController.java deleted file mode 100644 index a0bd0a58..00000000 --- a/modules/network-api/src/main/java/com/whoz_in/network_api/controller/IpAddressController.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.whoz_in.network_api.controller; - -import com.whoz_in.network_api.common.util.RequesterInfo; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@Slf4j -@RestController -@RequestMapping("/api/v1") -@RequiredArgsConstructor -public class IpAddressController { - private final RequesterInfo requesterInfo; - - @GetMapping("/ip") - public ResponseEntity getMac() { - String ip = requesterInfo.getIp(); - log.info("Requester Info : " + ip); - return ResponseEntity.ok(ip); - } - -} diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/controller/NetworkApiController.java b/modules/network-api/src/main/java/com/whoz_in/network_api/controller/NetworkApiController.java new file mode 100644 index 00000000..5762bd2f --- /dev/null +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/controller/NetworkApiController.java @@ -0,0 +1,34 @@ +package com.whoz_in.network_api.controller; + +import com.whoz_in.network_api.common.util.IpHolder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RestController +@RequestMapping("/api/v1") +public class NetworkApiController { + private final IpHolder ipHolder; + private final String room; + + public NetworkApiController(IpHolder ipHolder, @Value("${room-setting.room-name}") String room) { + this.ipHolder = ipHolder; + this.room = room; + } + + @GetMapping("/ip") + public ResponseEntity getIp() { + String ip = ipHolder.getIp(); + log.info("Requester Info : " + ip); + return ResponseEntity.ok(ip); + } + + @GetMapping("/room") + public ResponseEntity getRoom(){ + return ResponseEntity.ok(room); + } +} From e06e5768cad2488f8447f3fb4f0998b3c213371d Mon Sep 17 00:00:00 2001 From: bellmin Date: Thu, 9 Jan 2025 23:35:57 +0900 Subject: [PATCH 072/138] =?UTF-8?q?test(main-api):=20viewerTest=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Viewer는 Collection를 반환해야 한다 --- .../main_api/architecture/ViewerTest.java | 47 ++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/modules/main-api/src/test/java/com/whoz_in/main_api/architecture/ViewerTest.java b/modules/main-api/src/test/java/com/whoz_in/main_api/architecture/ViewerTest.java index f2b1e9cd..9599c1aa 100644 --- a/modules/main-api/src/test/java/com/whoz_in/main_api/architecture/ViewerTest.java +++ b/modules/main-api/src/test/java/com/whoz_in/main_api/architecture/ViewerTest.java @@ -15,6 +15,7 @@ import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; +import java.util.Collection; import java.util.Optional; @AnalyzeClasses(packages = "com.whoz_in.main_api", importOptions = ImportOption.DoNotIncludeTests.class) @@ -35,6 +36,50 @@ public void check(JavaMethod method, ConditionEvents events) { } }; + ArchCondition returnTypeIsCollectionView = new ArchCondition("return a type collection of view") { + @Override + public void check(JavaMethod method, ConditionEvents events) { + JavaClass returnType = method.getReturnType().toErasure(); + + if (!returnType.isAssignableTo(Collection.class)) { + try { + + // 순수 자바 표준으로만 구현된 클래스와 메소드 찾기 + Class onwerClass = Class.forName(method.getOwner().getName()); + Method reflectedMethod = onwerClass.getDeclaredMethod(method.getName(), + method.getRawParameterTypes().stream() + .map(param -> { + try { + return Class.forName(param.getName()); + } catch (ClassNotFoundException e) { + throw new RuntimeException( + "Failed to load parameter type: " + param.getName(), e); + } + }) + .toArray(Class[]::new)); + + Type genericReturnType = reflectedMethod.getGenericReturnType(); + if (genericReturnType instanceof ParameterizedType parameterizedType) { + Type[] typeArguments = parameterizedType.getActualTypeArguments(); + for (Type typeArgument : typeArguments) { + if (typeArgument instanceof Class) { + Class typeClass = (Class) typeArgument; + if (View.class.isAssignableFrom(typeClass)) { + return; + } + } + } + } + } catch (ClassNotFoundException | NoSuchMethodException e) { + String error = String.format("리플렉션 실패: '%s'의 '%s': %s", + method.getOwner().getName(), method.getName(), e.getMessage()); + events.add(SimpleConditionEvent.violated(method, error)); + return; + } + } + } + }; + ArchCondition returnTypeIsOptionalView = new ArchCondition<>("return Optional where T implements View") { @Override public void check(JavaMethod method, ConditionEvents events) { @@ -82,7 +127,7 @@ public void check(JavaMethod method, ConditionEvents events) { ArchRuleDefinition.methods() .that().areDeclaredInClassesThat().areAssignableTo(Viewer.class) - .should(returnTypeIsView.or(returnTypeIsOptionalView)) + .should(returnTypeIsView.or(returnTypeIsOptionalView).or(returnTypeIsCollectionView)) .check(importedClasses); } From 5e9f2ab7303530525dda1f9c326016498b0ca0b7 Mon Sep 17 00:00:00 2001 From: bellmin Date: Thu, 9 Jan 2025 23:39:49 +0900 Subject: [PATCH 073/138] =?UTF-8?q?comment(main-api):=20=EC=A3=BC=EC=84=9D?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../active/SpringDeviceStatusManager.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java index baa7edf2..f4b89ec5 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java @@ -41,7 +41,7 @@ public class SpringDeviceStatusManager implements DeviceStatusManager { private final InActiveDeviceFilter inActiveDeviceFilter; private final ActiveDeviceFilter activeDeviceFilter; - private static final Duration MEASURE = Duration.ofMinutes(1); // 측정 시간 10분 + private static final Duration MEASURE = Duration.ofMinutes(5); // 측정 시간 10분 public SpringDeviceStatusManager( DeviceRepository deviceRepository, @@ -84,6 +84,11 @@ public void activeDeviceFind() { } + // inactive 판별 다시 설계하기 + // 고려해야할 것 + // 1. monitorLog 조회 크기 (10분 등) + // 2. 모니터 로그에 없는 맥을 제외할 것이냐 아니냐 + @Override @Scheduled(fixedRate = 5000) public void inActiveDeviceFind() { @@ -107,17 +112,15 @@ public void inActiveDeviceFind() { )); activeDevices = activeDevices.stream() - .filter(activeDevice -> !monitorLogDeviceIds.contains( - activeDevice.deviceId())) // 모니터 로그에 없는 Device 만 추출 (InActive 후보) + .filter(activeDevice -> !monitorLogDeviceIds.contains(activeDevice.deviceId())) // 모니터 로그에 없는 Device 만 추출 (InActive 후보) .filter(activeDevice -> { LocalDateTime logCreatedTime = logTimeByDeviceId.get(activeDevice.deviceId()); LocalDateTime activeDeviceActiveTime = activeDevice.connectedTime(); - Duration term = Duration.between(logCreatedTime, activeDeviceActiveTime); - - boolean isInActive = term.compareTo(MEASURE) > 0; // 로그 발생 시간과의 차이가 기준치보다 클 경우 InActive + Duration term = Duration.between(activeDeviceActiveTime, logCreatedTime).abs(); - return isInActive; + // 로그 발생 시간과의 차이가 기준치보다 클 경우 InActive + return term.compareTo(MEASURE) > 0; }) .toList(); From 00905bf44febef2de91837d7ef0ca59d07dd9ffb Mon Sep 17 00:00:00 2001 From: bellmin Date: Thu, 9 Jan 2025 23:50:13 +0900 Subject: [PATCH 074/138] =?UTF-8?q?refactor(main-api):=20DeviceFilter=20ex?= =?UTF-8?q?ecute=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main_api/shared/domain/device/active/DeviceFilter.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java index bc22e45e..fe91e0cc 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java @@ -34,11 +34,12 @@ public DeviceFilter( this.deviceById = createDeviceMapById(); } - public List execute(){ + public void execute(){ List devices = find(); - return devices.stream() + devices = devices.stream() .filter(this::judge) .toList(); + raiseEvent(devices); } private Map createDeviceMapById() { From 3264884fb09bbf1dae2a60c5a202c3645dc19d9b Mon Sep 17 00:00:00 2001 From: coco3x Date: Thu, 9 Jan 2025 23:38:33 +0900 Subject: [PATCH 075/138] =?UTF-8?q?remove(main-api):=20DeviceInfo=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5=20=EC=A0=9C=ED=95=9C=EC=9D=84=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=ED=95=A9=EB=8B=88=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../command/device/application/DeviceInfoStore.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceInfoStore.java b/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceInfoStore.java index a2ed9228..4651e0e6 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceInfoStore.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceInfoStore.java @@ -21,13 +21,13 @@ @Component @RequiredArgsConstructor public final class DeviceInfoStore { - private final RoomSsidConfig ssidConfig; - private static final Cache> store = CacheBuilder.newBuilder() .expireAfterAccess(5, TimeUnit.MINUTES) // 5분 동안 접근이 없으면 만료 - .maximumSize(10) // 최대 10개 항목 저장 .build(); + private final RoomSsidConfig ssidConfig; + + //이전에 등록되지 않은 DeviceInfo인지 검증 public void mustNotExist(MemberId ownerId, DeviceInfo deviceInfo){ List deviceInfos = store.getIfPresent(ownerId); From aabb2b13e4373410be3f2d557ce976b874d78881 Mon Sep 17 00:00:00 2001 From: bellmin Date: Fri, 10 Jan 2025 00:39:46 +0900 Subject: [PATCH 076/138] =?UTF-8?q?refactor(main-api):=20ActiveDeviceFinde?= =?UTF-8?q?d=20=ED=95=84=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - MonitorLog 필드 제거 --- .../device/application/active/event/ActiveDeviceFinded.java | 6 +++--- .../domain/device/active/SpringDeviceStatusManager.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/event/ActiveDeviceFinded.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/event/ActiveDeviceFinded.java index 63ac5234..654bf9b2 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/event/ActiveDeviceFinded.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/event/ActiveDeviceFinded.java @@ -10,11 +10,11 @@ public class ActiveDeviceFinded implements Event { private final List devices; - private final List logs; + // 모니터 로그는 ActiveDevice 가 언제 Active 되었는지 시간을 삽입하기 위해 필요하다. +// private final List logs; - public ActiveDeviceFinded(List devices, List logs) { + public ActiveDeviceFinded(List devices) { this.devices = devices; - this.logs = logs; } } diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java index f4b89ec5..655018ba 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java @@ -80,7 +80,7 @@ public void activeDeviceFind() { .map(device -> device.getId().id()) .toList(); - Events.raise(new ActiveDeviceFinded(activeDevices, uniqueLogs.stream().toList())); + Events.raise(new ActiveDeviceFinded(activeDevices)); } From ac334ecafb5cd9d595e2fe5fcffc72818c4da83a Mon Sep 17 00:00:00 2001 From: bellmin Date: Fri, 10 Jan 2025 00:42:15 +0900 Subject: [PATCH 077/138] =?UTF-8?q?feat(main-api):=20ActiveDeviceFilter=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - DeviceFilter 추상 클래스 상속 - Active 상태인 Device 만 거르는 필터 --- .../device/active/ActiveDeviceFilter.java | 54 ++++++++++++++----- 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java index 36ca18ca..5e475207 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java @@ -2,9 +2,13 @@ import com.whoz_in.domain.device.DeviceRepository; import com.whoz_in.domain.device.model.Device; +import com.whoz_in.domain.device.model.DeviceId; import com.whoz_in.domain.network_log.MonitorLog; import com.whoz_in.domain.network_log.MonitorLogRepository; +import com.whoz_in.main_api.query.device.application.active.ActiveDevice; import com.whoz_in.main_api.query.device.application.active.ActiveDeviceViewer; +import com.whoz_in.main_api.query.device.application.active.event.ActiveDeviceFinded; +import com.whoz_in.main_api.shared.event.Events; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -12,9 +16,12 @@ import java.util.List; import java.util.Objects; import java.util.Set; +import java.util.UUID; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @Component +@Slf4j public class ActiveDeviceFilter extends DeviceFilter { public ActiveDeviceFilter( @@ -26,31 +33,50 @@ public ActiveDeviceFilter( @Override protected List find() { - LocalDateTime todayMidnight = LocalDate.now().atTime(LocalTime.of(0, 0, 0)); - - List logs = monitorLogRepository.findByUpdatedAtAfterOrderByUpdatedAtDesc(todayMidnight); // 오늘 자정 이후의 로그들 , 현재 시간으로 바꿔야 할까? - Set uniqueLogs = new HashSet<>(logs); // 중복 제거 - - if (!uniqueLogs.isEmpty()) { - // 실제 판별 로직 - // 판별 로직이 허술하다. 판별하는 decider 를 구현해야 하나 - return uniqueLogs.stream() - .map(log -> deviceByMac.get(log.getMac())) - .filter(Objects::nonNull) - .toList(); + Set uniqueLogs = getUniqueMonitorLogs(); + if(deviceByMac.keySet().isEmpty() || deviceById.keySet().isEmpty() || uniqueLogs.isEmpty()){ + log.info("[ActiveDeviceFind] 처리할 정보 없음"); + return List.of(); } - return List.of(); + return uniqueLogs.stream() + .map(log -> deviceByMac.get(log.getMac())) + .filter(Objects::nonNull) + .toList(); } + + // 1. isActive = false 인 경우 -> true + // 2. isActive = true 인 경우 -> true + // 3. 어떤 상황에 false 일까? @Override protected boolean judge(Device device) { - return false; + // 이미 MonitorLog 에 존재하는 기기이다. + + UUID deviceId = device.getId().id(); + ActiveDevice activeDevice; + try { + activeDevice = activeDeviceViewer.getByDeviceId(deviceId.toString()); + } catch (IllegalArgumentException e){ + log.error("[Active - judge] 예상치 못한 에러 발생"); + throw new IllegalStateException(e.getMessage()); + } + + if(!activeDevice.isActive()) return true; // 현재 inActive 상태인데, MonitorLog 에 존재할 경우 + + return true; } @Override protected void raiseEvent(List devices) { + List deviceIds = devices.stream().map(Device::getId).map(DeviceId::id).toList(); + Events.raise(new ActiveDeviceFinded(deviceIds)); + } + private Set getUniqueMonitorLogs(){ + LocalDateTime before10Minute = LocalDateTime.now().minusMinutes(10); + List logs = monitorLogRepository.findByUpdatedAtAfterOrderByUpdatedAtDesc(before10Minute); // 10분 전 로그 조회 + return new HashSet<>(logs); // 중복 제거 } } From a7624b0b9ffb95ca73a501c78aced7e3c5375c14 Mon Sep 17 00:00:00 2001 From: bellmin Date: Fri, 10 Jan 2025 00:50:08 +0900 Subject: [PATCH 078/138] =?UTF-8?q?refactor(main-api):=20getUniqueMonitorL?= =?UTF-8?q?ogs=20=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=9D=B4=EC=A0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - DeviceFilter 로 이전 --- .../domain/device/active/ActiveDeviceFilter.java | 6 ------ .../shared/domain/device/active/DeviceFilter.java | 10 ++++++++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java index 5e475207..9f1a8181 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java @@ -73,10 +73,4 @@ protected void raiseEvent(List devices) { List deviceIds = devices.stream().map(Device::getId).map(DeviceId::id).toList(); Events.raise(new ActiveDeviceFinded(deviceIds)); } - - private Set getUniqueMonitorLogs(){ - LocalDateTime before10Minute = LocalDateTime.now().minusMinutes(10); - List logs = monitorLogRepository.findByUpdatedAtAfterOrderByUpdatedAtDesc(before10Minute); // 10분 전 로그 조회 - return new HashSet<>(logs); // 중복 제거 - } } diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java index fe91e0cc..afac5193 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java @@ -2,11 +2,15 @@ import com.whoz_in.domain.device.DeviceRepository; import com.whoz_in.domain.device.model.Device; +import com.whoz_in.domain.network_log.MonitorLog; import com.whoz_in.domain.network_log.MonitorLogRepository; import com.whoz_in.main_api.query.device.application.active.ActiveDeviceViewer; +import java.time.LocalDateTime; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; import org.springframework.stereotype.Component; @@ -42,6 +46,12 @@ public void execute(){ raiseEvent(devices); } + protected Set getUniqueMonitorLogs(){ + LocalDateTime before10Minute = LocalDateTime.now().minusMinutes(10); + List logs = monitorLogRepository.findByUpdatedAtAfterOrderByUpdatedAtDesc(before10Minute); // 10분 전 로그 조회 + return new HashSet<>(logs); // 중복 제거 + } + private Map createDeviceMapById() { return deviceRepository.findAll().stream() .collect(Collectors.toMap(device -> device.getId().id(), device -> device)); From 7ac306c34c5553cbb3e821fc542dcc74915bac6e Mon Sep 17 00:00:00 2001 From: bellmin Date: Fri, 10 Jan 2025 01:08:06 +0900 Subject: [PATCH 079/138] =?UTF-8?q?refactor(main-api):=20Filter=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../active/SpringDeviceStatusManager.java | 71 +------------------ 1 file changed, 2 insertions(+), 69 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java index 655018ba..062c0392 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/SpringDeviceStatusManager.java @@ -41,8 +41,6 @@ public class SpringDeviceStatusManager implements DeviceStatusManager { private final InActiveDeviceFilter inActiveDeviceFilter; private final ActiveDeviceFilter activeDeviceFilter; - private static final Duration MEASURE = Duration.ofMinutes(5); // 측정 시간 10분 - public SpringDeviceStatusManager( DeviceRepository deviceRepository, MonitorLogRepository monitorLogRepository, @@ -63,79 +61,14 @@ public SpringDeviceStatusManager( @Override @Scheduled(fixedRate = 5000) public void activeDeviceFind() { - - LocalDateTime before10Minute = LocalDateTime.now().minusMinutes(10); - List logs = monitorLogRepository.findByUpdatedAtAfterOrderByUpdatedAtDesc(before10Minute); // 10분 전 로그 조회 - Set uniqueLogs = new HashSet<>(logs); // 중복 제거 - - if(deviceByMac.keySet().isEmpty() || deviceById.keySet().isEmpty() || uniqueLogs.isEmpty()){ - log.info("[ActiveDeviceFind] 처리할 정보 없음"); - return; - } - // 실제 판별 로직 - // 판별 로직이 허술하다. 판별하는 decider 를 구현해야 하나 - List activeDevices = uniqueLogs.stream() - .map(log -> deviceByMac.get(log.getMac())) - .filter(Objects::nonNull) - .map(device -> device.getId().id()) - .toList(); - - Events.raise(new ActiveDeviceFinded(activeDevices)); - + activeDeviceFilter.execute(); } - // inactive 판별 다시 설계하기 - // 고려해야할 것 - // 1. monitorLog 조회 크기 (10분 등) - // 2. 모니터 로그에 없는 맥을 제외할 것이냐 아니냐 @Override @Scheduled(fixedRate = 5000) public void inActiveDeviceFind() { - List activeDevices = activeDeviceViewer.findAll(); - - if(!activeDevices.isEmpty()) { - - LocalDateTime before10Minute = LocalDateTime.now().minusMinutes(10); - - List logs = monitorLogRepository.findByUpdatedAtAfterOrderByUpdatedAtDesc(before10Minute); - List monitorLogDeviceIds = logs.stream() - .map(log -> deviceByMac.get(log.getMac())) - .filter(Objects::nonNull) - .map(device -> device.getId().id()) - .toList(); - Map logTimeByDeviceId = logs.stream() - .filter(log -> deviceByMac.containsKey(log.getMac())) - .collect(Collectors.toMap( - log -> deviceByMac.get(log.getMac()).getId().id(), - MonitorLog::getUpdatedAt - )); - - activeDevices = activeDevices.stream() - .filter(activeDevice -> !monitorLogDeviceIds.contains(activeDevice.deviceId())) // 모니터 로그에 없는 Device 만 추출 (InActive 후보) - .filter(activeDevice -> { - LocalDateTime logCreatedTime = logTimeByDeviceId.get(activeDevice.deviceId()); - LocalDateTime activeDeviceActiveTime = activeDevice.connectedTime(); - - Duration term = Duration.between(activeDeviceActiveTime, logCreatedTime).abs(); - - // 로그 발생 시간과의 차이가 기준치보다 클 경우 InActive - return term.compareTo(MEASURE) > 0; - }) - .toList(); - - List inActiveDevices = activeDevices.stream() - .map(activeDevice -> { - UUID id = activeDevice.deviceId(); - return deviceById.get(id); - }) - .map(device -> device.getId().id()) - .toList(); - - Events.raise(new InActiveDeviceFinded(inActiveDevices)); - } else { - log.info("[InActiveDeviceFind] 처리할 정보 없음"); - } + inActiveDeviceFilter.execute(); } private Map createDeviceMapById() { From d6fb45390fe8103757f759bac9b18723a38b2f6f Mon Sep 17 00:00:00 2001 From: bellmin Date: Fri, 10 Jan 2025 01:08:31 +0900 Subject: [PATCH 080/138] =?UTF-8?q?feat(main-api):=20InActiveDeviceFilter?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - InActive 상태인 Device 를 거른다 --- .../device/active/InActiveDeviceFilter.java | 75 ++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java index caa4e413..cc78f04f 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java @@ -2,14 +2,31 @@ import com.whoz_in.domain.device.DeviceRepository; import com.whoz_in.domain.device.model.Device; +import com.whoz_in.domain.device.model.DeviceId; +import com.whoz_in.domain.network_log.MonitorLog; import com.whoz_in.domain.network_log.MonitorLogRepository; +import com.whoz_in.main_api.query.device.application.active.ActiveDevice; import com.whoz_in.main_api.query.device.application.active.ActiveDeviceViewer; +import com.whoz_in.main_api.query.device.application.active.event.InActiveDeviceFinded; +import com.whoz_in.main_api.shared.event.Events; +import java.time.Duration; +import java.time.LocalDateTime; import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @Component +@Slf4j public class InActiveDeviceFilter extends DeviceFilter{ + // MonitorLog 가 마지막으로 뜬지 10분이 되도록 발생하지 않을경우 InActive 처리하는 기준 + private static final Duration MEASURE = Duration.ofMinutes(10); + public InActiveDeviceFilter( DeviceRepository deviceRepository, MonitorLogRepository monitorLogRepository, @@ -19,16 +36,72 @@ public InActiveDeviceFilter( @Override protected List find() { + + List activeDevices = activeDeviceViewer.findAll(); + + if(!activeDevices.isEmpty()) { + Set logs = getUniqueMonitorLogs(); + + List monitorLogDeviceIds = logs.stream() + .map(log -> deviceByMac.get(log.getMac())) + .filter(Objects::nonNull) + .map(Device::getId) + .map(DeviceId::id) + .toList(); + + List deviceIds = activeDevices.stream().map(ActiveDevice::deviceId).toList(); + + return deviceIds.stream() + .filter(deviceId -> !monitorLogDeviceIds.contains(deviceId)) + .map(deviceById::get) + .filter(Objects::nonNull) + .toList(); + + } + log.info("[InActiveDeviceFind] 처리할 정보 없음"); return List.of(); } + // inactive 판별 다시 설계하기 + // 고려해야할 것 + // 1. monitorLog 조회 크기 (10분 등) + // 2. 모니터 로그에 없는 맥을 제외할 것이냐 아니냐 @Override protected boolean judge(Device device) { - return false; + UUID deviceId = device.getId().id(); + + ActiveDevice activeDevice = activeDeviceViewer.getByDeviceId(deviceId.toString()); + + Map logTimeByDeviceId = createLogTimeByDeviceIdMap(); + + LocalDateTime logCreatedTime = logTimeByDeviceId.get(deviceId); + LocalDateTime activeDeviceActiveTime = activeDevice.connectedTime(); + + Duration term = Duration.between(activeDeviceActiveTime, logCreatedTime).abs(); + + // 로그 발생 시간과의 차이가 기준치보다 클 경우 InActive + return term.compareTo(MEASURE) > 0; } @Override protected void raiseEvent(List devices) { + // 이벤트 발생 + List deviceIds = devices.stream() + .map(Device::getId) + .map(DeviceId::id) + .toList(); + + Events.raise(new InActiveDeviceFinded(deviceIds)); + } + + private Map createLogTimeByDeviceIdMap(){ + Set logs = getUniqueMonitorLogs(); + return logs.stream() // 이 기기가 언제 MonitorLog를 발생시켰는지 알기위한 맵 + .filter(log -> deviceByMac.containsKey(log.getMac())) + .collect(Collectors.toMap( + log -> deviceByMac.get(log.getMac()).getId().id(), + MonitorLog::getUpdatedAt + )); } } From e5bcc61afec5fa82f73e8304e486270c09b1ebce Mon Sep 17 00:00:00 2001 From: bellmin Date: Fri, 10 Jan 2025 01:43:50 +0900 Subject: [PATCH 081/138] =?UTF-8?q?refactor(main-api):=20ActiveDeviceFilte?= =?UTF-8?q?r=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 로그 추가 --- .../domain/device/active/ActiveDeviceFilter.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java index 9f1a8181..e2e44487 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java @@ -40,10 +40,17 @@ protected List find() { return List.of(); } - return uniqueLogs.stream() + List devices = uniqueLogs.stream() .map(log -> deviceByMac.get(log.getMac())) - .filter(Objects::nonNull) + .filter(Objects::nonNull) // MonitorLog 에 있는 mac 주소 중, WhozIn에 등록되지 않은 mac 제거 .toList(); + + if(devices.isEmpty()){ + log.info("[ActiveDeviceFind] 처리할 정보 없음"); + return List.of(); + } + + return devices; } @@ -59,8 +66,8 @@ protected boolean judge(Device device) { try { activeDevice = activeDeviceViewer.getByDeviceId(deviceId.toString()); } catch (IllegalArgumentException e){ - log.error("[Active - judge] 예상치 못한 에러 발생"); - throw new IllegalStateException(e.getMessage()); + log.error("[ActiveDeviceFind] 처음 Active 상태가 된 기기 {}", deviceId); + return true; } if(!activeDevice.isActive()) return true; // 현재 inActive 상태인데, MonitorLog 에 존재할 경우 From d48722103f7a8be12a7ae40fb41e9cb7837850f7 Mon Sep 17 00:00:00 2001 From: bellmin Date: Fri, 10 Jan 2025 01:53:33 +0900 Subject: [PATCH 082/138] =?UTF-8?q?comment(main-api):=20DeviceFilter=20?= =?UTF-8?q?=EC=BD=94=EB=A9=98=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - deviceByMac - deviceById --- .../main_api/shared/domain/device/active/DeviceFilter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java index afac5193..bd6b44ac 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java @@ -34,6 +34,7 @@ public DeviceFilter( this.deviceRepository = deviceRepository; this.monitorLogRepository = monitorLogRepository; this.activeDeviceViewer = activeDeviceViewer; + // TODO: 이 Map 들은, Active, InActive 판별에 아주 중요한 요소인데 메모리로만 유지하면, 최신화된 데이터를 받아올 수 없다. this.deviceByMac = createDeviceMapByMac(); this.deviceById = createDeviceMapById(); } @@ -47,7 +48,7 @@ public void execute(){ } protected Set getUniqueMonitorLogs(){ - LocalDateTime before10Minute = LocalDateTime.now().minusMinutes(10); + LocalDateTime before10Minute = LocalDateTime.now().minusMinutes(1); List logs = monitorLogRepository.findByUpdatedAtAfterOrderByUpdatedAtDesc(before10Minute); // 10분 전 로그 조회 return new HashSet<>(logs); // 중복 제거 } From 59af952b3ccaac3e4d61766fee2a4033a1fd4008 Mon Sep 17 00:00:00 2001 From: bellmin Date: Fri, 10 Jan 2025 02:09:52 +0900 Subject: [PATCH 083/138] =?UTF-8?q?refactor(api-query-jpa):=20=EA=B0=B1?= =?UTF-8?q?=EC=8B=A0=EB=90=9C=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=82=BD?= =?UTF-8?q?=EC=9E=85=20=EA=B0=80=EB=8A=A5=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api_query_jpa/device/InMemoryActiveDeviceRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/InMemoryActiveDeviceRepository.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/InMemoryActiveDeviceRepository.java index d722cd1e..247562a8 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/InMemoryActiveDeviceRepository.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/InMemoryActiveDeviceRepository.java @@ -21,7 +21,7 @@ public InMemoryActiveDeviceRepository(){ public UUID save(ActiveDeviceEntity device){ UUID id = device.getDeviceId(); - repository.putIfAbsent(id, device); + repository.put(id, device); // 갱신된 데이터가 삽입될 수 있도록 return device.getDeviceId(); } From df0a5ef7671295a6947fbfc23821a0efedc8058b Mon Sep 17 00:00:00 2001 From: bellmin Date: Fri, 10 Jan 2025 02:12:19 +0900 Subject: [PATCH 084/138] =?UTF-8?q?refactor(main-api):=20ActiveDeviceFilte?= =?UTF-8?q?r,=20InActiveDeviceFilter=20=EB=A1=9C=EC=A7=81=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ActiveDeviceFilter : 이미 Active 인 경우 이벤트에서 제외 - InActiveDeviceFilter : 이미 InActive 인 경우 이벤트에서 제외 --- .../domain/device/active/ActiveDeviceFilter.java | 9 +++++++-- .../device/active/InActiveDeviceFilter.java | 16 ++++++++++++---- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java index e2e44487..586bb0f5 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java @@ -70,9 +70,14 @@ protected boolean judge(Device device) { return true; } - if(!activeDevice.isActive()) return true; // 현재 inActive 상태인데, MonitorLog 에 존재할 경우 - return true; + if(!activeDevice.isActive()) { + log.info("[ActiveDeviceFind] Active 전환 : {}", deviceId); + return true; // 현재 inActive 상태인데, MonitorLog 에 존재할 경우 + } + + // 이미 active 인 경우 이벤트에서 제외 + return false; } @Override diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java index cc78f04f..819c1d48 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java @@ -25,7 +25,7 @@ public class InActiveDeviceFilter extends DeviceFilter{ // MonitorLog 가 마지막으로 뜬지 10분이 되도록 발생하지 않을경우 InActive 처리하는 기준 - private static final Duration MEASURE = Duration.ofMinutes(10); + private static final Duration MEASURE = Duration.ofMinutes(1); public InActiveDeviceFilter( DeviceRepository deviceRepository, @@ -72,15 +72,23 @@ protected boolean judge(Device device) { ActiveDevice activeDevice = activeDeviceViewer.getByDeviceId(deviceId.toString()); + // 이미 inActive 상태인 기기의 경우 이벤트에서 제외 + if(!activeDevice.isActive()) return false; + Map logTimeByDeviceId = createLogTimeByDeviceIdMap(); - LocalDateTime logCreatedTime = logTimeByDeviceId.get(deviceId); + LocalDateTime now = LocalDateTime.now(); LocalDateTime activeDeviceActiveTime = activeDevice.connectedTime(); - Duration term = Duration.between(activeDeviceActiveTime, logCreatedTime).abs(); + Duration term = Duration.between(activeDeviceActiveTime, now).abs(); // 로그 발생 시간과의 차이가 기준치보다 클 경우 InActive - return term.compareTo(MEASURE) > 0; + + if(term.compareTo(MEASURE) > 0){ + log.info("[InActiveDeviceFind] InActive 전환 {}", deviceId); + return true; + } + return false; } @Override From 30496249ef556bb4e1c6961893011031fa03d111 Mon Sep 17 00:00:00 2001 From: bellmin Date: Fri, 10 Jan 2025 02:13:34 +0900 Subject: [PATCH 085/138] =?UTF-8?q?comment(main-api):=20DeviceFilter=20TOD?= =?UTF-8?q?O=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main_api/shared/domain/device/active/DeviceFilter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java index bd6b44ac..fe86265b 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java @@ -16,6 +16,7 @@ import org.springframework.stereotype.Component; // Device 들을 받으면, 정해진 기준에 맞춰 거르는 역할이라는 뜻 +// TODO: 아래의 Map 들을 주기적으로 최신화 하거나, DB에서 직접 가져오기 @Component public abstract class DeviceFilter { From c31977f8a421b91d9c9f434a226c6aa78922bf82 Mon Sep 17 00:00:00 2001 From: bellmin Date: Fri, 10 Jan 2025 02:16:51 +0900 Subject: [PATCH 086/138] =?UTF-8?q?refactor(main-api):=20MonitorLog=20?= =?UTF-8?q?=EA=B0=80=20=EC=97=86=EC=9D=84=20=EA=B2=BD=EC=9A=B0=20=EB=B0=94?= =?UTF-8?q?=EB=A1=9C=20=EB=A6=AC=ED=84=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shared/domain/device/active/InActiveDeviceFilter.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java index 819c1d48..6bafc4df 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java @@ -38,10 +38,9 @@ public InActiveDeviceFilter( protected List find() { List activeDevices = activeDeviceViewer.findAll(); + Set logs = getUniqueMonitorLogs(); - if(!activeDevices.isEmpty()) { - Set logs = getUniqueMonitorLogs(); - + if(!activeDevices.isEmpty() && !logs.isEmpty()) { List monitorLogDeviceIds = logs.stream() .map(log -> deviceByMac.get(log.getMac())) .filter(Objects::nonNull) From 8bf47fa82e58121fce0ef101e0423b46886d2938 Mon Sep 17 00:00:00 2001 From: bellmin Date: Fri, 10 Jan 2025 02:41:44 +0900 Subject: [PATCH 087/138] =?UTF-8?q?feat(api-query-jpa):=20DeviceEventHandl?= =?UTF-8?q?er=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - DeviceStatusEventHandler 삭제 - ActiveDeviceEventHandler 와 InActiveDeviceEventHandler 로 분리 - ActiveDeviceEventHandler 저장 로직 수정 --- .../event/ActiveDeviceEventHandler.java | 66 +++++++++++++++++++ ...r.java => InActiveDeviceEventHandler.java} | 18 +---- 2 files changed, 68 insertions(+), 16 deletions(-) create mode 100644 modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java rename modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/{DeviceStatusEventHandler.java => InActiveDeviceEventHandler.java} (59%) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java new file mode 100644 index 00000000..01ff8c66 --- /dev/null +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java @@ -0,0 +1,66 @@ +package com.whoz_in.api_query_jpa.device.event; + +import com.whoz_in.api_query_jpa.device.ActiveDeviceEntity; +import com.whoz_in.api_query_jpa.device.InMemoryActiveDeviceRepository; +import com.whoz_in.main_api.query.device.application.active.event.ActiveDeviceFinded; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Transactional; + +@Component +@RequiredArgsConstructor +public class ActiveDeviceEventHandler { + +// private final ActiveDeviceRepository activeDeviceRepository; + // TODO: JPA 적용 + private final InMemoryActiveDeviceRepository activeDeviceRepository; + + @Transactional(isolation = Isolation.SERIALIZABLE) + @EventListener(ActiveDeviceFinded.class) + public void saveActiveDevices(ActiveDeviceFinded event) { + List deviceIds = event.getDevices(); + List activeDeviceEntities = activeDeviceRepository.findAll(); + + List deviceIdFromDB = activeDeviceEntities.stream().map(ActiveDeviceEntity::getDeviceId).toList(); + + List firstActiveDevices = deviceIds.stream() + .filter(deviceId -> deviceIdFromDB.stream().noneMatch(idFromDB -> idFromDB.equals(deviceId))) + .map(deviceId -> ActiveDeviceEntity.create(deviceId, LocalDateTime.now())) // TODO: active Time 을 이 시점으로 설정해도 될까? + .toList(); + + + List nonFirstActiveDevice = deviceIds.stream() + .filter(deviceIdFromDB::contains) + .map(deviceId -> { + return activeDeviceEntities.stream() + .filter(active -> active.getDeviceId().equals(deviceId)) + .findAny() + .orElse(null); + }) + .filter(Objects::nonNull) + .toList(); + + + saveFirstActive(firstActiveDevices); + saveNonFirstActive(nonFirstActiveDevice); + } + + private void saveFirstActive(List entities){ + // 처음으로 Active 된 Device 는 그냥 저장 가능 + activeDeviceRepository.saveAll(entities); + } + + private void saveNonFirstActive(List entities){ + // 참조를 이용한 JPA 변경 감지 짝퉁 + entities.forEach(activeDevice -> { + if(!activeDevice.isActive()) activeDevice.activeOn(LocalDateTime.now()); + }); + } + +} diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/InActiveDeviceEventHandler.java similarity index 59% rename from modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java rename to modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/InActiveDeviceEventHandler.java index b2e9b512..7e5b7f04 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/DeviceStatusEventHandler.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/InActiveDeviceEventHandler.java @@ -2,7 +2,6 @@ import com.whoz_in.api_query_jpa.device.ActiveDeviceEntity; import com.whoz_in.api_query_jpa.device.InMemoryActiveDeviceRepository; -import com.whoz_in.main_api.query.device.application.active.event.ActiveDeviceFinded; import com.whoz_in.main_api.query.device.application.active.event.InActiveDeviceFinded; import java.time.LocalDateTime; import java.util.List; @@ -15,24 +14,11 @@ @Component @RequiredArgsConstructor -public class DeviceStatusEventHandler { +public class InActiveDeviceEventHandler { -// private final ActiveDeviceRepository activeDeviceRepository; - // TODO: JPA 적용 private final InMemoryActiveDeviceRepository activeDeviceRepository; - @Transactional(isolation = Isolation.SERIALIZABLE) - @EventListener(ActiveDeviceFinded.class) - public void saveActiveDevices(ActiveDeviceFinded event) { - List devices = event.getDevices(); - List entities = devices.stream() - .map(device -> ActiveDeviceEntity.create(device, LocalDateTime.now())) // TODO: active Time 을 이 시점으로 설정해도 될까? - .toList(); - - activeDeviceRepository.saveAll(entities); - } - - // 바로 위의 이벤트 핸들러에서 데이터를 수정할 수 있지만, ConcurrentHashMap 사용하므로 격리 수준을 default로 설정 + // ActiveDeviceEvent 핸들러에서 데이터를 수정할 수 있으므로 격리 수준을 serializable 로 설정 @Transactional(isolation = Isolation.SERIALIZABLE) @EventListener(InActiveDeviceFinded.class) public void processInActiveDevices(InActiveDeviceFinded event) { From 6c2b7f7e68d61ea97d1503a4d2155357ce0fe02a Mon Sep 17 00:00:00 2001 From: bellmin Date: Fri, 10 Jan 2025 02:47:14 +0900 Subject: [PATCH 088/138] =?UTF-8?q?refactor(main-api):=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=20=EB=AC=B8=EA=B5=AC=20=EC=88=98=EC=A0=95=20=EB=B0=8F?= =?UTF-8?q?=20inActive=20=ED=8C=90=EB=B3=84=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shared/domain/device/active/ActiveDeviceFilter.java | 8 ++++---- .../shared/domain/device/active/InActiveDeviceFilter.java | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java index 586bb0f5..a3348238 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java @@ -36,7 +36,7 @@ protected List find() { Set uniqueLogs = getUniqueMonitorLogs(); if(deviceByMac.keySet().isEmpty() || deviceById.keySet().isEmpty() || uniqueLogs.isEmpty()){ - log.info("[ActiveDeviceFind] 처리할 정보 없음"); + log.info("[ActiveDeviceFilter] 처리할 정보 없음"); return List.of(); } @@ -46,7 +46,7 @@ protected List find() { .toList(); if(devices.isEmpty()){ - log.info("[ActiveDeviceFind] 처리할 정보 없음"); + log.info("[ActiveDeviceFilter] 처리할 정보 없음"); return List.of(); } @@ -66,13 +66,13 @@ protected boolean judge(Device device) { try { activeDevice = activeDeviceViewer.getByDeviceId(deviceId.toString()); } catch (IllegalArgumentException e){ - log.error("[ActiveDeviceFind] 처음 Active 상태가 된 기기 {}", deviceId); + log.error("[ActiveDeviceFilter] 처음 Active 상태가 된 기기 {}", deviceId); return true; } if(!activeDevice.isActive()) { - log.info("[ActiveDeviceFind] Active 전환 : {}", deviceId); + log.info("[ActiveDeviceFilter] Active 전환 : {}", deviceId); return true; // 현재 inActive 상태인데, MonitorLog 에 존재할 경우 } diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java index 6bafc4df..410a4c4c 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java @@ -40,7 +40,7 @@ protected List find() { List activeDevices = activeDeviceViewer.findAll(); Set logs = getUniqueMonitorLogs(); - if(!activeDevices.isEmpty() && !logs.isEmpty()) { + if(!activeDevices.isEmpty()) { List monitorLogDeviceIds = logs.stream() .map(log -> deviceByMac.get(log.getMac())) .filter(Objects::nonNull) @@ -57,7 +57,7 @@ protected List find() { .toList(); } - log.info("[InActiveDeviceFind] 처리할 정보 없음"); + log.info("[InActiveDeviceFilter] 처리할 정보 없음"); return List.of(); } @@ -84,7 +84,7 @@ protected boolean judge(Device device) { // 로그 발생 시간과의 차이가 기준치보다 클 경우 InActive if(term.compareTo(MEASURE) > 0){ - log.info("[InActiveDeviceFind] InActive 전환 {}", deviceId); + log.info("[InActiveDeviceFilter] InActive 전환 {}", deviceId); return true; } return false; From edbbf9314a1ff0ad8f387b925599dc40b580a9db Mon Sep 17 00:00:00 2001 From: bellmin Date: Fri, 10 Jan 2025 02:55:35 +0900 Subject: [PATCH 089/138] =?UTF-8?q?refactor(api-query-jpa):=20ActiveDevice?= =?UTF-8?q?Entity=20activeOn=20=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - inactiveTime null로 초기화 --- .../com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java index 2c8fafb9..37df999f 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java @@ -36,6 +36,7 @@ private ActiveDeviceEntity(UUID deviceId, LocalDateTime activeTime) { public void activeOn(LocalDateTime activeTime){ this.isActive = true; this.activeTime = activeTime; + this.inactiveTime = null; } public void inActiveOn(LocalDateTime inactiveTime){ From c76b88aa5dabac66172ce39d680121b73abb5201 Mon Sep 17 00:00:00 2001 From: bellmin Date: Fri, 10 Jan 2025 02:59:39 +0900 Subject: [PATCH 090/138] =?UTF-8?q?refactor(api-query-jpa):=20ActiveDevice?= =?UTF-8?q?Entity=20addTotalActiveTime=20=EB=A9=94=EC=86=8C=EB=93=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Duration.abs 메소드 사용 --- .../com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java index 37df999f..c6240995 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java @@ -46,7 +46,7 @@ public void inActiveOn(LocalDateTime inactiveTime){ } private void addTotalActiveTime(){ - Duration add = Duration.between(activeTime, inactiveTime); + Duration add = Duration.between(activeTime, inactiveTime).abs(); this.totalActiveTime = Objects.nonNull(totalActiveTime) ? totalActiveTime.plus(add) : add; } From 717b33b92fff2e2911de9ff16c856e310785eb4c Mon Sep 17 00:00:00 2001 From: bellmin Date: Fri, 10 Jan 2025 03:01:56 +0900 Subject: [PATCH 091/138] =?UTF-8?q?refactor(main-api):=20ActiveDevice=20Vi?= =?UTF-8?q?ew=20=EC=8B=9C=EA=B0=84=20=EA=B3=84=EC=82=B0=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 연속 접속 시간 계산 로직 수정 - TODO 추가 --- .../query/device/application/active/ActiveDevice.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java index 5cc5e10c..6318e866 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java @@ -16,6 +16,7 @@ public record ActiveDevice( boolean isActive ) implements View { + // TODO: ActiveTime Calculator 로 이동 public Duration totalConnectedTime(){ if(totalConnectedTime!=null){ return totalConnectedTime.plus(continuousTime()); @@ -24,8 +25,8 @@ public Duration totalConnectedTime(){ } public Duration continuousTime(){ - if(disConnectedTime!=null) return Duration.between(connectedTime,disConnectedTime); - return Duration.between(connectedTime, LocalDateTime.now()); + if(isActive) Duration.between(connectedTime, LocalDateTime.now()).abs(); + return Duration.between(connectedTime,disConnectedTime).abs(); } } From 76e41c4d0f0bfa6bc961705b461943f57a9a2f73 Mon Sep 17 00:00:00 2001 From: bellmin Date: Fri, 10 Jan 2025 03:08:36 +0900 Subject: [PATCH 092/138] =?UTF-8?q?refactor(main-api):=20return=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main_api/query/device/application/active/ActiveDevice.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java index 6318e866..5e28744b 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java @@ -25,7 +25,7 @@ public Duration totalConnectedTime(){ } public Duration continuousTime(){ - if(isActive) Duration.between(connectedTime, LocalDateTime.now()).abs(); + if(isActive) return Duration.between(connectedTime, LocalDateTime.now()).abs(); return Duration.between(connectedTime,disConnectedTime).abs(); } From 5fd7c83af133c47424b22ef321aa14ddc0ad575a Mon Sep 17 00:00:00 2001 From: bellmin Date: Fri, 10 Jan 2025 03:28:36 +0900 Subject: [PATCH 093/138] =?UTF-8?q?refactor(main-api):=20total=20=EC=8B=9C?= =?UTF-8?q?=EA=B0=84=20=EA=B3=84=EC=82=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../query/device/application/active/ActiveDevice.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java index 5e28744b..67143507 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDevice.java @@ -3,6 +3,7 @@ import com.whoz_in.main_api.query.shared.application.View; import java.time.Duration; import java.time.LocalDateTime; +import java.util.Objects; import java.util.UUID; // Active 상태인 기기를 나타내는 View @@ -18,10 +19,12 @@ public record ActiveDevice( // TODO: ActiveTime Calculator 로 이동 public Duration totalConnectedTime(){ - if(totalConnectedTime!=null){ + if(isActive && Objects.nonNull(totalConnectedTime)){ // 한 번 이상 접속을 끊었다 연결한 경우 return totalConnectedTime.plus(continuousTime()); + } else if (isActive){ // 처음 접속했는데, 안 끊은 경우 + return continuousTime(); } - return continuousTime(); + return totalConnectedTime; // 접속을 종료한 경우 } public Duration continuousTime(){ From 3680b05966eeb153defdd83aed5ce7729fb41568 Mon Sep 17 00:00:00 2001 From: bellmin Date: Fri, 10 Jan 2025 03:35:11 +0900 Subject: [PATCH 094/138] =?UTF-8?q?comment(main-api):=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=EC=A3=BC=EC=84=9D=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shared/domain/device/active/ActiveDeviceFilter.java | 3 --- .../shared/domain/device/active/InActiveDeviceFilter.java | 4 ---- 2 files changed, 7 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java index a3348238..e40b5c58 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java @@ -54,9 +54,6 @@ protected List find() { } - // 1. isActive = false 인 경우 -> true - // 2. isActive = true 인 경우 -> true - // 3. 어떤 상황에 false 일까? @Override protected boolean judge(Device device) { // 이미 MonitorLog 에 존재하는 기기이다. diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java index 410a4c4c..8e43e456 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java @@ -61,10 +61,6 @@ protected List find() { return List.of(); } - // inactive 판별 다시 설계하기 - // 고려해야할 것 - // 1. monitorLog 조회 크기 (10분 등) - // 2. 모니터 로그에 없는 맥을 제외할 것이냐 아니냐 @Override protected boolean judge(Device device) { UUID deviceId = device.getId().id(); From 312c63580361549175461a97f701f726cf5d0453 Mon Sep 17 00:00:00 2001 From: bellmin Date: Fri, 10 Jan 2025 15:23:51 +0900 Subject: [PATCH 095/138] =?UTF-8?q?refactor(main-api):=20=EC=97=B0?= =?UTF-8?q?=EC=86=8D=20=EC=A0=91=EC=86=8D=20=EC=8B=9C=EA=B0=84,=20?= =?UTF-8?q?=EB=88=84=EC=A0=81=20=EC=A0=91=EC=86=8D=20=EC=8B=9C=EA=B0=84=20?= =?UTF-8?q?=EC=8B=9C=EA=B0=84=20=EA=B3=84=EC=82=B0=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/active/ActiveDeviceListHandler.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java index fafdf1ec..f79eb239 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/active/ActiveDeviceListHandler.java @@ -38,16 +38,16 @@ public ActiveDeviceListResponse handle(ActiveDeviceList query) { String deviceId = activeDevice.deviceId().toString(); String memberId = activeDevice.memberId().toString(); String memberName = getMemberName(activeDevice.memberId().toString()); - Duration continuousTime = activeDevice.continuousTime(); - Duration totalConnectedTime = activeDevice.totalConnectedTime(); + Long continuousMinute = activeDevice.continuousTime().toMinutes(); + Long totalConnectedMinute = activeDevice.totalConnectedTime().toMinutes(); boolean isActive = activeDevice.isActive(); ActiveDeviceResponse oneResponse = new ActiveDeviceResponse( deviceId, memberId, memberName, - String.format("%s시간 %s분", continuousTime.toHours(), continuousTime.toMinutes()), - String.format("%s시간 %s분", totalConnectedTime.toHours(), totalConnectedTime.toMinutes()), + String.format("%s시간 %s분", continuousMinute / 60, continuousMinute % 60), + String.format("%s시간 %s분", totalConnectedMinute / 60, totalConnectedMinute % 60), isActive ); responses.add(oneResponse); From b84e88aa2c02f8ace66436c63dbef11ca71f6f3a Mon Sep 17 00:00:00 2001 From: coco3x Date: Sat, 11 Jan 2025 03:51:11 +0900 Subject: [PATCH 096/138] =?UTF-8?q?fix(main-api):=20=EA=B8=B0=EA=B8=B0=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EB=93=B1=EB=A1=9D=20-=20monitor=20log=20?= =?UTF-8?q?=ED=99=95=EC=9D=B8=20=EB=B2=94=EC=9C=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../command/device/application/DeviceInfoAddHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceInfoAddHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceInfoAddHandler.java index 6002ba2f..bc34afe5 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceInfoAddHandler.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceInfoAddHandler.java @@ -45,8 +45,8 @@ public Void handle(DeviceInfoAdd req) { //이미 등록된 DeviceInfo가 아닌지 미리 확인 deviceInfoStore.mustNotExist(requesterId, deviceInfo); - //모니터 로그에서 시간 내에 존재하는 맥이 있는지 확인 - monitorLogRepository.mustExistAfter(mac, LocalDateTime.now().minusDays(1)); + //모니터 로그에서 현재 접속 중인 맥이 있는지 확인 (넉넉하게 15분) + monitorLogRepository.mustExistAfter(mac, LocalDateTime.now().minusMinutes(15)); //해당 맥으로 이미 등록된 기기가 있을경우 deviceRepository.findByMac(mac).ifPresent(device -> { From daaa304737aa171cbc9cec4983a23627bbd9f5e1 Mon Sep 17 00:00:00 2001 From: coco3x Date: Sat, 11 Jan 2025 04:14:48 +0900 Subject: [PATCH 097/138] =?UTF-8?q?refactor(network-api):=20=EC=A0=84?= =?UTF-8?q?=EC=B2=B4=EC=A0=81=EC=9C=BC=EB=A1=9C=20=EC=B1=85=EC=9E=84=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../network_api/common/NetworkInterface.java | 17 ++-- .../network_api/config/NetworkConfig.java | 94 ++++++------------- .../config/NetworkInterfaceProperties.java | 28 ++++++ .../managed/arp/ArpLogProcess.java | 7 +- .../network_api/managed/arp/ArpLogWriter.java | 21 +++-- .../managed/mdns/MdnsLogProcess.java | 7 +- .../managed/mdns/MdnsLogWriter.java | 59 ++++++------ .../network_api/monitor/ChannelHopper.java | 6 +- .../monitor/MonitorLogProcess.java | 4 +- .../network_api/monitor/MonitorLogWriter.java | 9 +- 10 files changed, 124 insertions(+), 128 deletions(-) create mode 100644 modules/network-api/src/main/java/com/whoz_in/network_api/config/NetworkInterfaceProperties.java diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/common/NetworkInterface.java b/modules/network-api/src/main/java/com/whoz_in/network_api/common/NetworkInterface.java index 60693cac..5d0aa5a2 100644 --- a/modules/network-api/src/main/java/com/whoz_in/network_api/common/NetworkInterface.java +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/common/NetworkInterface.java @@ -1,25 +1,30 @@ package com.whoz_in.network_api.common; +import jakarta.annotation.Nullable; import lombok.EqualsAndHashCode; import lombok.Getter; @Getter +@EqualsAndHashCode public final class NetworkInterface{ - // - @EqualsAndHashCode.Exclude - private final String altSsid; //network log의 ssid는 이걸로 저장된다. (ex: econo) private final String interfaceName; private final String realSsid; //실제 연결될 와이파이 이름 (ex: ECONO_5G) private final String mode; - public NetworkInterface(String altSsid, String interfaceName, String realSsid, String mode) { - this.altSsid = altSsid; + @EqualsAndHashCode.Exclude + @Nullable private final String altSsid; //network log의 ssid는 이걸로 저장된다. (ex: econo) + @EqualsAndHashCode.Exclude + @Nullable private final String command; //실행할 명령어 + + public NetworkInterface(String interfaceName, String realSsid, String mode, String altSsid, String command) { this.interfaceName = interfaceName; this.realSsid = realSsid; this.mode = mode; + this.altSsid = altSsid; + this.command = command; } public NetworkInterface(String interfaceName, String realSsid, String mode) { - this(realSsid, interfaceName, realSsid, mode); + this(interfaceName, realSsid, mode, realSsid, null); } } \ No newline at end of file diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/config/NetworkConfig.java b/modules/network-api/src/main/java/com/whoz_in/network_api/config/NetworkConfig.java index e9c57e11..6fdfbc05 100644 --- a/modules/network-api/src/main/java/com/whoz_in/network_api/config/NetworkConfig.java +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/config/NetworkConfig.java @@ -1,95 +1,57 @@ package com.whoz_in.network_api.config; import com.whoz_in.network_api.common.NetworkInterface; -import com.whoz_in.network_api.managed.ManagedInfo; -import com.whoz_in.network_api.monitor.MonitorInfo; -import java.util.ArrayList; +import java.util.Collection; import java.util.List; +import java.util.stream.Stream; import lombok.Getter; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.bind.ConstructorBinding; import org.springframework.stereotype.Component; -//실행시킬 프로세스들이 필요로 하는 정보를 제공하는 역할을 한다. -//다른 모듈이 구현한 LogWriterConfig를 통해 정보를 초기화한다. +//이 서버의 전체적인 설정 값을 관리한다. @Getter @Component public class NetworkConfig { private final String room; private final String sudoPassword; private final List networkInterfaces; - private final MonitorInfo monitorInfo; - private final List mdnsList; - private final List arpList; + private final NetworkInterface monitorNI; + private final List mdnsNIs; + private final List arpNIs; public NetworkConfig( - NetworkConfigProperties properties, + NetworkInterfaceProperties properties, + @Value("${room-setting.room-name}") String roomName, @Value("${sudo_password}") String sudoPassword, @Value("${command.monitor}") String monitorCommandTemplate, @Value("${command.managed.mdns}") String mdnsCommandTemplate, @Value("${command.managed.arp}") String arpCommandTemplate ) { - this.room = properties.getRoom(); + this.room = roomName; this.sudoPassword = sudoPassword; - this.networkInterfaces = properties.getNIs(); - this.monitorInfo = new MonitorInfo(properties.getMonitorNI(), generateCommand(monitorCommandTemplate, properties.getMonitorNI().getInterfaceName())); - this.mdnsList=properties.getMdnsNIs().stream() - .map(ni-> new ManagedInfo(ni, generateCommand(mdnsCommandTemplate, ni.getInterfaceName()))) + this.monitorNI = new NetworkInterface(properties.getMonitor().interfaceName(), null, "monitor", + null, generateCommand(monitorCommandTemplate, properties.getMonitor().interfaceName())); + this.mdnsNIs = properties.getMdns().stream() + .map(mdns -> { + String altSsid = (mdns.altSsid() != null) ? mdns.altSsid() : mdns.realSsid(); + return new NetworkInterface(mdns.interfaceName() , mdns.realSsid(), "managed", altSsid, + generateCommand(mdnsCommandTemplate, mdns.interfaceName())); + }) .toList(); - this.arpList=properties.getArpNIs().stream() - .map(ni-> new ManagedInfo(ni, generateCommand(arpCommandTemplate, ni.getInterfaceName()))) + this.arpNIs = properties.getArp().stream() + .map(arp -> { + String altSsid = (arp.altSsid() != null) ? arp.altSsid() : arp.realSsid(); + return new NetworkInterface(arp.interfaceName(), arp.realSsid(), "managed", altSsid, + generateCommand(arpCommandTemplate, arp.interfaceName())); + }) + .toList(); + this.networkInterfaces = Stream.of(monitorNI, mdnsNIs, arpNIs) + .flatMap(list -> list instanceof Collection ? + ((Collection) list).stream() : Stream.of((NetworkInterface) list)) .toList(); } - private String generateCommand(String commandTemplate, String interfaceName) { + private static String generateCommand(String commandTemplate, String interfaceName) { return commandTemplate.replace("{{interface}}", interfaceName); } - - - @Getter - @ConfigurationProperties(prefix = "room-setting") - public static class NetworkConfigProperties { - - private final String room; - private final NetworkInterface monitorNI; - private final List mdnsNIs; - private final List arpNIs; - - public record Monitor(String interfaceName) {} - public record Managed(List mdns, List arp) { - public record Mdns(String altSsid, String realSsid, String interfaceName) {} - public record Arp(String altSsid, String realSsid, String interfaceName) {} - } - - public List getNIs() { - List nis = new ArrayList<>(); - nis.add(getMonitorNI()); - nis.addAll(getMdnsNIs()); - nis.addAll(getArpNIs()); - return nis; - } - - @ConstructorBinding - public NetworkConfigProperties( - String roomName, - Monitor monitor, - Managed managed - ) { - this.room = roomName; - this.monitorNI = new NetworkInterface(null, monitor.interfaceName, null, "monitor"); - this.mdnsNIs = managed.mdns.stream() - .map(ni -> { - String altSsid = (ni.altSsid != null) ? ni.altSsid : ni.realSsid; - return new NetworkInterface(altSsid, ni.interfaceName, ni.realSsid, "managed"); - }) - .toList(); - this.arpNIs = managed.arp.stream() - .map(ni -> { - String altSsid = (ni.altSsid != null) ? ni.altSsid : ni.realSsid; - return new NetworkInterface(altSsid, ni.interfaceName, ni.realSsid, "managed"); - }) - .toList(); - } - } } \ No newline at end of file diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/config/NetworkInterfaceProperties.java b/modules/network-api/src/main/java/com/whoz_in/network_api/config/NetworkInterfaceProperties.java new file mode 100644 index 00000000..64af8360 --- /dev/null +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/config/NetworkInterfaceProperties.java @@ -0,0 +1,28 @@ +package com.whoz_in.network_api.config; + +import java.util.List; +import lombok.Getter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.bind.ConstructorBinding; + +//네트워크 인터페이스와 관련된 환경 변수로부터 설정값을 읽어서 사용하기 쉽도록 가공하는 역할을 한다. +@Getter +@ConfigurationProperties(prefix = "room-setting.network-interfaces") +public class NetworkInterfaceProperties { + private final Monitor monitor; + private final List arp; + private final List mdns; + + public record Monitor(String interfaceName) {} + public record Managed(List mdns, List arp) {} + public record Mdns(String altSsid, String realSsid, String interfaceName) {} + public record Arp(String altSsid, String realSsid, String interfaceName) {} + + + @ConstructorBinding + public NetworkInterfaceProperties(Monitor monitor, Managed managed) { + this.monitor = monitor; + this.arp = managed.arp; + this.mdns = managed.mdns; + } +} diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/managed/arp/ArpLogProcess.java b/modules/network-api/src/main/java/com/whoz_in/network_api/managed/arp/ArpLogProcess.java index 2fe7eea6..e6196ac5 100644 --- a/modules/network-api/src/main/java/com/whoz_in/network_api/managed/arp/ArpLogProcess.java +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/managed/arp/ArpLogProcess.java @@ -1,15 +1,12 @@ package com.whoz_in.network_api.managed.arp; import com.whoz_in.network_api.common.process.TransientProcess; -import com.whoz_in.network_api.managed.ManagedInfo; import lombok.Getter; @Getter public class ArpLogProcess extends TransientProcess { - private final ManagedInfo info; - public ArpLogProcess(ManagedInfo info, String password) { - super(info.command(), password); - this.info = info; + public ArpLogProcess(String command, String password) { + super(command, password); } } diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/managed/arp/ArpLogWriter.java b/modules/network-api/src/main/java/com/whoz_in/network_api/managed/arp/ArpLogWriter.java index 9dada5f5..0b859234 100644 --- a/modules/network-api/src/main/java/com/whoz_in/network_api/managed/arp/ArpLogWriter.java +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/managed/arp/ArpLogWriter.java @@ -3,8 +3,8 @@ import com.whoz_in.domain.network_log.ManagedLog; import com.whoz_in.domain.network_log.ManagedLogRepository; +import com.whoz_in.network_api.common.NetworkInterface; import com.whoz_in.network_api.config.NetworkConfig; -import com.whoz_in.network_api.managed.ManagedInfo; import com.whoz_in.network_api.managed.ParsedLog; import java.util.Collection; import java.util.List; @@ -21,7 +21,7 @@ public class ArpLogWriter { private final String room; private final ManagedLogRepository repository; private final ArpLogParser parser; - private final List arpList; + private final List arpNIs; private final String sudoPassword; public ArpLogWriter(ManagedLogRepository repository, @@ -31,29 +31,32 @@ public ArpLogWriter(ManagedLogRepository repository, this.room = config.getRoom(); this.repository = repository; this.parser = parser; - this.arpList = config.getArpList(); + this.arpNIs = config.getArpNIs(); this.sudoPassword = config.getSudoPassword(); } //주기적으로 arp 명령어를 실행하여 로그를 저장함 @Scheduled(initialDelay = 10000, fixedDelay = 5000) private void scan() { - List logs = arpList.stream() //실행할 arp들을 스트림화 - .map(info -> new ArpLogProcess(info, sudoPassword)) //arp 실행 - .map(this::getLogsFromProcess) //arp 출력을 로그 Set으로 변환 - .flatMap(Collection::stream) //Set끼리 합침 + List logs = arpNIs.stream() + .collect(Collectors.toMap( + ni -> ni, + ni -> new ArpLogProcess(ni.getCommand(), sudoPassword) + )).entrySet().stream() + .map(entry -> getLogsFromProcess(entry.getKey(), entry.getValue())) + .flatMap(Collection::stream) .toList(); repository.saveAll(logs); } //프로세스의 출력들을 로그로 변환한다. - private List getLogsFromProcess(ArpLogProcess process){ + private List getLogsFromProcess(NetworkInterface ni, ArpLogProcess process){ Set logs = process.resultList().stream() .filter(parser::validate) .map(parser::parse) .collect(Collectors.toSet());//Set으로 중복 제거 - String altSsid = process.getInfo().ni().getAltSsid(); + String altSsid = ni.getAltSsid(); log.info("[managed - arp({})] log to save : {}", altSsid, logs.size()); //parsedLog를 저장할 수 있는 ManagedLog로 변환 return logs.stream() diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/managed/mdns/MdnsLogProcess.java b/modules/network-api/src/main/java/com/whoz_in/network_api/managed/mdns/MdnsLogProcess.java index 567f2f1a..bb2560c4 100644 --- a/modules/network-api/src/main/java/com/whoz_in/network_api/managed/mdns/MdnsLogProcess.java +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/managed/mdns/MdnsLogProcess.java @@ -1,14 +1,11 @@ package com.whoz_in.network_api.managed.mdns; import com.whoz_in.network_api.common.process.ContinuousProcess; -import com.whoz_in.network_api.managed.ManagedInfo; import lombok.Getter; @Getter public class MdnsLogProcess extends ContinuousProcess { - private final ManagedInfo info; - public MdnsLogProcess(ManagedInfo info, String sudoPassword) { - super(info.command(), sudoPassword); - this.info = info; + public MdnsLogProcess(String command, String sudoPassword) { + super(command, sudoPassword); } } diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/managed/mdns/MdnsLogWriter.java b/modules/network-api/src/main/java/com/whoz_in/network_api/managed/mdns/MdnsLogWriter.java index 82393d70..2a5ea468 100644 --- a/modules/network-api/src/main/java/com/whoz_in/network_api/managed/mdns/MdnsLogWriter.java +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/managed/mdns/MdnsLogWriter.java @@ -2,9 +2,9 @@ import com.whoz_in.domain.network_log.ManagedLog; import com.whoz_in.domain.network_log.ManagedLogRepository; +import com.whoz_in.network_api.common.NetworkInterface; import com.whoz_in.network_api.common.SystemNetworkInterfaces; import com.whoz_in.network_api.config.NetworkConfig; -import com.whoz_in.network_api.managed.ManagedInfo; import com.whoz_in.network_api.managed.ParsedLog; import java.util.Collection; import java.util.HashMap; @@ -22,8 +22,8 @@ @Component public class MdnsLogWriter { private final String room; - private final Map processes; - private final Map dead; + private final Map processes; + private final Map dead; private final MdnsLogParser parser; private final ManagedLogRepository repository; private final String sudoPassword; @@ -39,33 +39,38 @@ public MdnsLogWriter(ManagedLogRepository repository, MdnsLogParser parser, Netw this.processes = new HashMap<>(); this.dead = new HashMap<>(); this.systemNIs = systemNIs; - config.getMdnsList().forEach(this::startProcess); + config.getMdnsNIs().forEach(this::startProcess); } //주기적으로 로그를 저장함 + @Scheduled(initialDelay = 10000, fixedDelay = 10000) private void saveLogs() { - List totalLogs = this.processes.values().parallelStream() - .filter(MdnsLogProcess::isAlive) - .map(this::getLogsFromProcess) + List totalLogs = this.processes.entrySet().parallelStream() + .filter(entry -> entry.getValue().isAlive()) + .map(entry -> getLogsFromProcess(entry.getKey(), entry.getValue())) .flatMap(Collection::stream) .toList(); repository.saveAll(totalLogs); } - //프로세스에 쌓인 출력들을 로그로 변환 - private List getLogsFromProcess(MdnsLogProcess process){ + private List getLogsFromProcess(NetworkInterface ni, MdnsLogProcess process) { Set logs = process.readLines().stream() .map(parser::parse) .filter(Optional::isPresent) .map(Optional::get) .collect(Collectors.toSet()); - String altSsid = process.getInfo().ni().getAltSsid(); - log.info("[managed - mdns({})] log to save : {}", altSsid, logs.size()); //이거 여기 있는건 좀 그러긴 함 - //parsedLog를 저장할 수 있는 ManagedLog로 변환 + + String altSsid = ni.getAltSsid(); + log.info("[managed - mdns({})] log to save : {}", altSsid, logs.size()); + + //Parsed를 Managed로 변환 return logs.stream() - .map(log -> new ManagedLog(log.getMac(), log.getIp(), log.getDeviceName(), altSsid, room, - log.getCreatedAt(), log.getCreatedAt())) + .map(log -> new ManagedLog( + log.getMac(), log.getIp(), + log.getDeviceName(), altSsid, room, + log.getCreatedAt(), log.getCreatedAt() + )) .toList(); } @@ -75,32 +80,30 @@ private void checkProcesses(){ this.processes.entrySet().parallelStream() .filter(entry-> !entry.getValue().isAlive()) .forEach(entry ->{ - ManagedInfo managedInfo = entry.getKey(); + NetworkInterface ni = entry.getKey(); MdnsLogProcess process = entry.getValue(); //프로세스가 죽었다는 것을 인지했을때만 아래 로직을 실행 - if (dead.get(managedInfo).equals(Boolean.FALSE)) { - dead.put(managedInfo, true); - log.error("[managed - mdns({})] 프로세스가 종료됨 :\n{}\n{}", managedInfo.ni().getRealSsid(), "프로세스의 에러 스트림 내용:", process.readErrorLines()); + if (dead.get(ni).equals(Boolean.FALSE)) { + dead.put(ni, true); + log.error("[managed - mdns({})] 프로세스가 종료됨 :\n{}\n{}", ni.getRealSsid(), "프로세스의 에러 스트림 내용:", process.readErrorLines()); } - startProcess(managedInfo); + startProcess(ni); }); } - private void startProcess(ManagedInfo info){ - String altSsid = info.ni().getAltSsid(); + private void startProcess(NetworkInterface ni){ + String altSsid = ni.getAltSsid(); log.info("[managed - mdns({})] 프로세스를 실행합니다.", altSsid); - if (!systemNIs.exists(info.ni())){ + if (!systemNIs.exists(ni)){ log.error("[managed - mdns({})] 설정된 mdns 네트워크 인터페이스가 시스템에 존재하지 않습니다.", altSsid); return; } - Optional.ofNullable(this.processes.get(info)).ifPresent(MdnsLogProcess::terminate); - MdnsLogProcess process = new MdnsLogProcess(info, sudoPassword); - this.processes.put(info, process); - this.dead.put(info, false); + Optional.ofNullable(this.processes.get(ni)).ifPresent(MdnsLogProcess::terminate); + MdnsLogProcess process = new MdnsLogProcess(ni.getCommand(), sudoPassword); + this.processes.put(ni, process); + this.dead.put(ni, false); log.info("[managed - mdns({})] 프로세스 실행 완료", altSsid); } - - } diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/monitor/ChannelHopper.java b/modules/network-api/src/main/java/com/whoz_in/network_api/monitor/ChannelHopper.java index bd48da2d..d6e20227 100644 --- a/modules/network-api/src/main/java/com/whoz_in/network_api/monitor/ChannelHopper.java +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/monitor/ChannelHopper.java @@ -18,13 +18,13 @@ @Profile("prod") @Component public final class ChannelHopper { - private final NetworkInterface monitor; + private final NetworkInterface monitorNI; private final String sudoPassword; private final Set channelsToHop = new HashSet<>(); public ChannelHopper(NetworkConfig config, @Value("${sudo_password}") String sudoPassword) { this.sudoPassword = sudoPassword; - this.monitor = config.getMonitorInfo().ni(); + this.monitorNI = config.getMonitorNI(); } @Scheduled(initialDelay = 5000, fixedDelay = 1000) @@ -37,7 +37,7 @@ public void hop(){ //hop channel Integer channel = channelsToHop.iterator().next(); - String hopCommand = "sudo -S iwconfig %s channel %d".formatted(monitor.getInterfaceName(), channel); + String hopCommand = "sudo -S iwconfig %s channel %d".formatted(monitorNI.getInterfaceName(), channel); new TransientProcess(hopCommand, sudoPassword); //hopping된 채널 삭제 channelsToHop.remove(channel); diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/monitor/MonitorLogProcess.java b/modules/network-api/src/main/java/com/whoz_in/network_api/monitor/MonitorLogProcess.java index 36ab5798..47459076 100644 --- a/modules/network-api/src/main/java/com/whoz_in/network_api/monitor/MonitorLogProcess.java +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/monitor/MonitorLogProcess.java @@ -6,7 +6,7 @@ @Slf4j public final class MonitorLogProcess extends ContinuousProcess { - public MonitorLogProcess(MonitorInfo info, String sudoPassword) { - super(info.command(), sudoPassword); + public MonitorLogProcess(String command, String sudoPassword) { + super(command, sudoPassword); } } diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/monitor/MonitorLogWriter.java b/modules/network-api/src/main/java/com/whoz_in/network_api/monitor/MonitorLogWriter.java index 2140a546..5148038a 100644 --- a/modules/network-api/src/main/java/com/whoz_in/network_api/monitor/MonitorLogWriter.java +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/monitor/MonitorLogWriter.java @@ -2,6 +2,7 @@ import com.whoz_in.domain.network_log.MonitorLog; import com.whoz_in.domain.network_log.MonitorLogRepository; +import com.whoz_in.network_api.common.NetworkInterface; import com.whoz_in.network_api.common.SystemNetworkInterfaces; import com.whoz_in.network_api.config.NetworkConfig; import java.util.HashSet; @@ -20,7 +21,7 @@ public class MonitorLogWriter { private final MonitorLogParser parser; private final MonitorLogRepository repository; private final String sudoPassword; - private final MonitorInfo monitorInfo; + private final NetworkInterface monitorNI; private final SystemNetworkInterfaces systemNIs; public MonitorLogWriter(MonitorLogParser parser, MonitorLogRepository repository, NetworkConfig config, @@ -28,7 +29,7 @@ public MonitorLogWriter(MonitorLogParser parser, MonitorLogRepository repository this.parser = parser; this.repository = repository; this.room = config.getRoom(); - this.monitorInfo = config.getMonitorInfo(); + this.monitorNI = config.getMonitorNI(); this.sudoPassword = config.getSudoPassword(); this.systemNIs = systemNIs; startProcess(); @@ -65,12 +66,12 @@ private void startProcess(){ log.info("[monitor] 프로세스를 실행합니다."); //TODO: validator - if (!systemNIs.exists(monitorInfo.ni())){ + if (!systemNIs.exists(monitorNI)){ log.error("[monitor] 실행 실패 : 설정된 모니터 네트워크 인터페이스가 시스템에 존재하지 않습니다."); return; } Optional.ofNullable(this.process).ifPresent(MonitorLogProcess::terminate); - this.process = new MonitorLogProcess(monitorInfo, sudoPassword); + this.process = new MonitorLogProcess(monitorNI.getCommand(), sudoPassword); this.isProcDead = false; log.info("[monitor] 프로세스 실행 완료"); From beafcda4dd8a7ed75d975e239ded1b424ada4fc3 Mon Sep 17 00:00:00 2001 From: coco3x Date: Sat, 11 Jan 2025 07:30:40 +0900 Subject: [PATCH 098/138] =?UTF-8?q?feat(api-redis):=20=EB=A0=88=EB=94=94?= =?UTF-8?q?=EC=8A=A4=20=EB=AA=A8=EB=93=88=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/infrastructure/api-redis/build.gradle | 6 ++++++ modules/main-api/build.gradle | 1 + settings.gradle | 2 ++ 3 files changed, 9 insertions(+) create mode 100644 modules/infrastructure/api-redis/build.gradle diff --git a/modules/infrastructure/api-redis/build.gradle b/modules/infrastructure/api-redis/build.gradle new file mode 100644 index 00000000..974b1bb2 --- /dev/null +++ b/modules/infrastructure/api-redis/build.gradle @@ -0,0 +1,6 @@ +dependencies { + compileOnly project(":modules:main-api") + + implementation platform("org.springframework.boot:spring-boot-dependencies:${springBootVersion}") + implementation 'org.springframework.boot:spring-boot-starter-data-redis' +} \ No newline at end of file diff --git a/modules/main-api/build.gradle b/modules/main-api/build.gradle index f910facb..adf8f515 100644 --- a/modules/main-api/build.gradle +++ b/modules/main-api/build.gradle @@ -33,4 +33,5 @@ dependencies { //main-api 구현 모듈 (runtimeOnly - 순환 의존 방지) runtimeOnly project(":modules:infrastructure:api-query-jpa") +// runtimeOnly project(":modules:infrastructure:api-redis") } \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 9840dd1b..1ba6b03b 100644 --- a/settings.gradle +++ b/settings.gradle @@ -13,4 +13,6 @@ include 'modules:infrastructure:logging' findProject(':modules:infrastructure:logging')?.name = 'logging' include 'modules:master-api' findProject(':modules:master-api')?.name = 'master-api' +include 'modules:infrastructure:api-redis' +findProject(':modules:infrastructure:api-redis')?.name = 'api-redis' From b19cac0115c7b0a3493c2d0e25603440897e6f15 Mon Sep 17 00:00:00 2001 From: coco3x Date: Sun, 12 Jan 2025 19:44:10 +0900 Subject: [PATCH 099/138] =?UTF-8?q?style:=20=EC=93=B8=EB=AA=A8=20=EC=97=86?= =?UTF-8?q?=EB=8A=94=20=EC=9E=84=ED=8F=AC=ED=8A=B8=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/whoz_in/domain/member/MemberRepository.java | 1 - .../main/java/com/whoz_in/domain_jpa/device/DeviceEntity.java | 4 ---- .../com/whoz_in/domain_jpa/device/DeviceJpaRepository.java | 1 - .../main/java/com/whoz_in/domain_jpa/member/MemberEntity.java | 1 - .../whoz_in/domain_jpa/monitor/MonitorLogJpaRepository.java | 1 - .../command/device/presentation/DeviceController.java | 2 +- .../command/member/application/MemberOAuth2SignUpHandler.java | 4 ---- .../command/member/presentation/MemberController.java | 1 - .../main_api/shared/domain/SpringSecurityPasswordEncoder.java | 1 - .../main_api/shared/jwt/tokens/RefreshTokenSerializer.java | 2 +- 10 files changed, 2 insertions(+), 16 deletions(-) diff --git a/modules/domain/src/main/java/com/whoz_in/domain/member/MemberRepository.java b/modules/domain/src/main/java/com/whoz_in/domain/member/MemberRepository.java index d3fe9f87..a026d232 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/member/MemberRepository.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/member/MemberRepository.java @@ -3,7 +3,6 @@ import com.whoz_in.domain.member.exception.NoMemberException; import com.whoz_in.domain.member.model.Member; import com.whoz_in.domain.member.model.MemberId; -import com.whoz_in.domain.member.model.SocialProvider; import java.util.List; import java.util.Optional; diff --git a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceEntity.java b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceEntity.java index 99dd3374..55e34089 100644 --- a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceEntity.java +++ b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceEntity.java @@ -1,13 +1,10 @@ package com.whoz_in.domain_jpa.device; -import com.whoz_in.domain.member.model.Member; import com.whoz_in.domain_jpa.shared.BaseEntity; import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.OneToMany; @@ -17,7 +14,6 @@ import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; -import org.hibernate.annotations.UuidGenerator; @Entity @Getter diff --git a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceJpaRepository.java b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceJpaRepository.java index d80d0452..e94e2d04 100644 --- a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceJpaRepository.java +++ b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceJpaRepository.java @@ -2,7 +2,6 @@ import com.whoz_in.domain.device.DeviceRepository; import com.whoz_in.domain.device.model.Device; -import com.whoz_in.domain.device.model.MacAddress; import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; diff --git a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/member/MemberEntity.java b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/member/MemberEntity.java index 49c2a9ce..d7cec4b9 100644 --- a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/member/MemberEntity.java +++ b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/member/MemberEntity.java @@ -12,7 +12,6 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; -import org.hibernate.annotations.UuidGenerator; @Getter diff --git a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/monitor/MonitorLogJpaRepository.java b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/monitor/MonitorLogJpaRepository.java index d74de152..80ad29e4 100644 --- a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/monitor/MonitorLogJpaRepository.java +++ b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/monitor/MonitorLogJpaRepository.java @@ -2,7 +2,6 @@ import com.whoz_in.domain.network_log.MonitorLog; import com.whoz_in.domain.network_log.MonitorLogRepository; -import java.sql.Timestamp; import java.time.LocalDateTime; import java.util.Collection; import lombok.RequiredArgsConstructor; diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/presentation/DeviceController.java b/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/presentation/DeviceController.java index 5ef4878a..004484a7 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/presentation/DeviceController.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/presentation/DeviceController.java @@ -1,7 +1,7 @@ package com.whoz_in.main_api.command.device.presentation; -import com.whoz_in.main_api.command.device.application.DeviceRegister; import com.whoz_in.main_api.command.device.application.DeviceInfoAdd; +import com.whoz_in.main_api.command.device.application.DeviceRegister; import com.whoz_in.main_api.command.shared.application.CommandBus; import com.whoz_in.main_api.command.shared.presentation.CommandController; import com.whoz_in.main_api.shared.presentation.SuccessBody; diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/command/member/application/MemberOAuth2SignUpHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/command/member/application/MemberOAuth2SignUpHandler.java index d3aaca6b..e1c8aca1 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/command/member/application/MemberOAuth2SignUpHandler.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/command/member/application/MemberOAuth2SignUpHandler.java @@ -5,11 +5,7 @@ import com.whoz_in.domain.member.model.OAuthCredentials; import com.whoz_in.domain.shared.event.EventBus; import com.whoz_in.main_api.command.shared.application.CommandHandler; -import com.whoz_in.main_api.config.security.oauth2.OAuth2UserInfo; import com.whoz_in.main_api.shared.application.Handler; -import com.whoz_in.main_api.config.security.oauth2.OAuth2UserInfoStore; -import com.whoz_in.main_api.shared.jwt.tokens.OAuth2TempToken; -import com.whoz_in.main_api.shared.jwt.tokens.OAuth2TempTokenSerializer; import lombok.RequiredArgsConstructor; import org.springframework.transaction.annotation.Transactional; diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/command/member/presentation/MemberController.java b/modules/main-api/src/main/java/com/whoz_in/main_api/command/member/presentation/MemberController.java index 563687f0..8fa7d9f5 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/command/member/presentation/MemberController.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/command/member/presentation/MemberController.java @@ -14,7 +14,6 @@ import com.whoz_in.main_api.config.security.oauth2.OAuth2UserInfoStore; import com.whoz_in.main_api.shared.jwt.JwtProperties; import com.whoz_in.main_api.shared.jwt.TokenType; -import com.whoz_in.main_api.shared.jwt.tokens.AccessToken; import com.whoz_in.main_api.shared.jwt.tokens.OAuth2TempToken; import com.whoz_in.main_api.shared.jwt.tokens.TokenSerializer; import com.whoz_in.main_api.shared.presentation.ResponseEntityGenerator; diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/SpringSecurityPasswordEncoder.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/SpringSecurityPasswordEncoder.java index f71934a9..4117efa1 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/SpringSecurityPasswordEncoder.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/SpringSecurityPasswordEncoder.java @@ -2,7 +2,6 @@ import com.whoz_in.domain.member.service.PasswordEncoder; import lombok.RequiredArgsConstructor; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Component; @Component diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/jwt/tokens/RefreshTokenSerializer.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/jwt/tokens/RefreshTokenSerializer.java index c19f956d..c3635e5c 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/jwt/tokens/RefreshTokenSerializer.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/jwt/tokens/RefreshTokenSerializer.java @@ -1,8 +1,8 @@ package com.whoz_in.main_api.shared.jwt.tokens; -import static com.whoz_in.main_api.shared.jwt.JwtConst.TOKEN_ID; import static com.whoz_in.main_api.shared.jwt.JwtConst.MEMBER_ID; +import static com.whoz_in.main_api.shared.jwt.JwtConst.TOKEN_ID; import com.whoz_in.domain.member.model.MemberId; import com.whoz_in.main_api.shared.jwt.JwtProperties; From 3dfe8ebb953e806b02bdba7990118561650404cb Mon Sep 17 00:00:00 2001 From: coco3x Date: Sun, 12 Jan 2025 21:59:11 +0900 Subject: [PATCH 100/138] =?UTF-8?q?fix(domain-jpa):=20managed=20log=201?= =?UTF-8?q?=EA=B0=9C=EB=A7=8C=20=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../whoz_in/domain_jpa/managed/ManagedLogEntityRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/managed/ManagedLogEntityRepository.java b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/managed/ManagedLogEntityRepository.java index d63afaa7..a54c74ad 100644 --- a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/managed/ManagedLogEntityRepository.java +++ b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/managed/ManagedLogEntityRepository.java @@ -10,7 +10,7 @@ @Repository public interface ManagedLogEntityRepository extends JpaRepository { - @Query("SELECT m FROM ManagedLogEntity m WHERE m.room = :room AND m.logId.ip = :ip AND m.updatedAt > :time ORDER BY m.updatedAt DESC") + @Query("SELECT m FROM ManagedLogEntity m WHERE m.room = :room AND m.logId.ip = :ip AND m.updatedAt > :time ORDER BY m.updatedAt DESC LIMIT 1") Optional findTopByRoomAndIpOrderByUpdatedAtDescAfter( @Param("room") String room, @Param("ip") String ip, @Param("time") LocalDateTime time); From 5ff16e89d060a1eecc15777b10310b47e99f12dd Mon Sep 17 00:00:00 2001 From: coco3x Date: Mon, 13 Jan 2025 20:27:13 +0900 Subject: [PATCH 101/138] =?UTF-8?q?fix(network-api):=20monitor=20=EC=9D=B8?= =?UTF-8?q?=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EB=93=B1=EB=A1=9D=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../network_api/common/IwconfigNetworkInterfaces.java | 9 ++++++--- .../com/whoz_in/network_api/common/NetworkInterface.java | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/common/IwconfigNetworkInterfaces.java b/modules/network-api/src/main/java/com/whoz_in/network_api/common/IwconfigNetworkInterfaces.java index 59a16110..15ec3a0b 100644 --- a/modules/network-api/src/main/java/com/whoz_in/network_api/common/IwconfigNetworkInterfaces.java +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/common/IwconfigNetworkInterfaces.java @@ -33,11 +33,14 @@ public List getLatest() { } // 새 인터페이스 정보 모으기 & 초기화 currentName = line.split("\\s+")[0]; - if (line.contains("ESSID:")) + if (line.contains("ESSID:")) { currentSsid = line.split("ESSID:")[1].split("\\s+")[0].replace("\"", "") .trim(); - else - currentSsid = ""; + currentSsid = currentSsid.isEmpty() ? null : currentSsid; + } + else { + currentSsid = null; + } currentMode = null; // 초기화 } // Mode 추출 diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/common/NetworkInterface.java b/modules/network-api/src/main/java/com/whoz_in/network_api/common/NetworkInterface.java index 5d0aa5a2..557347bc 100644 --- a/modules/network-api/src/main/java/com/whoz_in/network_api/common/NetworkInterface.java +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/common/NetworkInterface.java @@ -3,8 +3,10 @@ import jakarta.annotation.Nullable; import lombok.EqualsAndHashCode; import lombok.Getter; +import lombok.ToString; @Getter +@ToString @EqualsAndHashCode public final class NetworkInterface{ private final String interfaceName; From b6b329355bd3bfc584a7f8ae3ced08f23434cc61 Mon Sep 17 00:00:00 2001 From: bellmin Date: Mon, 13 Jan 2025 20:59:20 +0900 Subject: [PATCH 102/138] =?UTF-8?q?refactor(main-api):=20=EC=B2=98?= =?UTF-8?q?=EC=9D=8C=EC=9C=BC=EB=A1=9C=20active=20=EC=83=81=ED=83=9C?= =?UTF-8?q?=EA=B0=80=20=EB=90=9C=20=EA=B8=B0=EA=B8=B0=EC=9D=BC=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=20=EB=A1=9C=EA=B7=B8=20=EC=88=98=EC=A4=80=20info=20?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shared/domain/device/active/ActiveDeviceFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java index e40b5c58..5e37c097 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java @@ -63,7 +63,7 @@ protected boolean judge(Device device) { try { activeDevice = activeDeviceViewer.getByDeviceId(deviceId.toString()); } catch (IllegalArgumentException e){ - log.error("[ActiveDeviceFilter] 처음 Active 상태가 된 기기 {}", deviceId); + log.info("[ActiveDeviceFilter] 처음 Active 상태가 된 기기 {}", deviceId); return true; } From 0a77906f3acdacdfa98ffcbb9028addfdbb2dbe5 Mon Sep 17 00:00:00 2001 From: bellmin Date: Mon, 13 Jan 2025 21:05:17 +0900 Subject: [PATCH 103/138] =?UTF-8?q?comment(main-api):=20=EC=A3=BC=EC=84=9D?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shared/domain/device/active/ActiveDeviceFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java index 5e37c097..3809ee3c 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/ActiveDeviceFilter.java @@ -56,7 +56,7 @@ protected List find() { @Override protected boolean judge(Device device) { - // 이미 MonitorLog 에 존재하는 기기이다. + // 이미 MonitorLog 에 존재하고 WhozIn에 등록된 기기이다. UUID deviceId = device.getId().id(); ActiveDevice activeDevice; From 1253b3fef4d97f6f381cef58fe527c5df40564e0 Mon Sep 17 00:00:00 2001 From: bellmin Date: Mon, 13 Jan 2025 21:18:47 +0900 Subject: [PATCH 104/138] =?UTF-8?q?refactor(main-api):=20monitorLog=20?= =?UTF-8?q?=ED=98=84=EC=9E=AC=EB=A1=9C=EB=B6=80=ED=84=B0=2010=EB=B6=84=20?= =?UTF-8?q?=EC=9D=B4=EC=A0=84=20=EB=A1=9C=EA=B7=B8=20=EC=A1=B0=ED=9A=8C,?= =?UTF-8?q?=20InActive=20=ED=8C=90=EB=B3=84=20=EA=B8=B0=EC=A4=80=2010?= =?UTF-8?q?=EB=B6=84=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main_api/shared/domain/device/active/DeviceFilter.java | 2 +- .../shared/domain/device/active/InActiveDeviceFilter.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java index fe86265b..32e4d758 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/DeviceFilter.java @@ -49,7 +49,7 @@ public void execute(){ } protected Set getUniqueMonitorLogs(){ - LocalDateTime before10Minute = LocalDateTime.now().minusMinutes(1); + LocalDateTime before10Minute = LocalDateTime.now().minusMinutes(10); List logs = monitorLogRepository.findByUpdatedAtAfterOrderByUpdatedAtDesc(before10Minute); // 10분 전 로그 조회 return new HashSet<>(logs); // 중복 제거 } diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java index 8e43e456..13b38d4f 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/device/active/InActiveDeviceFilter.java @@ -25,7 +25,7 @@ public class InActiveDeviceFilter extends DeviceFilter{ // MonitorLog 가 마지막으로 뜬지 10분이 되도록 발생하지 않을경우 InActive 처리하는 기준 - private static final Duration MEASURE = Duration.ofMinutes(1); + private static final Duration MEASURE = Duration.ofMinutes(10); public InActiveDeviceFilter( DeviceRepository deviceRepository, From 78dfba64b3a2e2f7f321db3910d915551159e22a Mon Sep 17 00:00:00 2001 From: bellmin Date: Mon, 13 Jan 2025 21:46:11 +0900 Subject: [PATCH 105/138] =?UTF-8?q?refactor(main-api):=20=EC=B2=AB=20Activ?= =?UTF-8?q?e=20=EC=83=81=ED=83=9C=20=EC=A0=84=ED=99=98=EC=9D=B4=20?= =?UTF-8?q?=EC=95=84=EB=8B=98=EC=9D=84=20=ED=8C=90=EB=B3=84=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api_query_jpa/device/event/ActiveDeviceEventHandler.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java index 01ff8c66..1551b1a5 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java @@ -8,6 +8,7 @@ import java.util.Objects; import java.util.UUID; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Isolation; @@ -15,6 +16,7 @@ @Component @RequiredArgsConstructor +@Slf4j public class ActiveDeviceEventHandler { // private final ActiveDeviceRepository activeDeviceRepository; @@ -36,7 +38,7 @@ public void saveActiveDevices(ActiveDeviceFinded event) { List nonFirstActiveDevice = deviceIds.stream() - .filter(deviceIdFromDB::contains) + .filter(deviceId -> deviceIdFromDB.stream().anyMatch(idFromDB -> idFromDB.equals(deviceId))) .map(deviceId -> { return activeDeviceEntities.stream() .filter(active -> active.getDeviceId().equals(deviceId)) From 62a768d2dcdf6e38b33c9829f955e19b84db8185 Mon Sep 17 00:00:00 2001 From: coco3x Date: Tue, 14 Jan 2025 00:19:27 +0900 Subject: [PATCH 106/138] =?UTF-8?q?chore(main-api):=20domain=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=EC=B2=B4=20=ED=8C=A8=ED=82=A4=EC=A7=80=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{ => infrastructure}/domain/SpringApplicationEventBus.java | 2 +- .../domain/SpringSecurityPasswordEncoder.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename modules/main-api/src/main/java/com/whoz_in/main_api/shared/{ => infrastructure}/domain/SpringApplicationEventBus.java (92%) rename modules/main-api/src/main/java/com/whoz_in/main_api/shared/{ => infrastructure}/domain/SpringSecurityPasswordEncoder.java (91%) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/SpringApplicationEventBus.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/infrastructure/domain/SpringApplicationEventBus.java similarity index 92% rename from modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/SpringApplicationEventBus.java rename to modules/main-api/src/main/java/com/whoz_in/main_api/shared/infrastructure/domain/SpringApplicationEventBus.java index 4b4daabb..da0191a0 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/SpringApplicationEventBus.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/infrastructure/domain/SpringApplicationEventBus.java @@ -1,4 +1,4 @@ -package com.whoz_in.main_api.shared.domain; +package com.whoz_in.main_api.shared.infrastructure.domain; import com.whoz_in.domain.shared.event.DomainEvent; import com.whoz_in.domain.shared.event.EventBus; diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/SpringSecurityPasswordEncoder.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/infrastructure/domain/SpringSecurityPasswordEncoder.java similarity index 91% rename from modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/SpringSecurityPasswordEncoder.java rename to modules/main-api/src/main/java/com/whoz_in/main_api/shared/infrastructure/domain/SpringSecurityPasswordEncoder.java index 4117efa1..47e7c450 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/domain/SpringSecurityPasswordEncoder.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/infrastructure/domain/SpringSecurityPasswordEncoder.java @@ -1,4 +1,4 @@ -package com.whoz_in.main_api.shared.domain; +package com.whoz_in.main_api.shared.infrastructure.domain; import com.whoz_in.domain.member.service.PasswordEncoder; import lombok.RequiredArgsConstructor; From f4c418bade259ec27871445ea186424f50c32f11 Mon Sep 17 00:00:00 2001 From: coco3x Date: Tue, 14 Jan 2025 00:25:42 +0900 Subject: [PATCH 107/138] =?UTF-8?q?refactor(main-api):=20=EC=9E=84?= =?UTF-8?q?=EC=8B=9C=EB=A1=9C=20=EC=A0=80=EC=9E=A5=ED=95=A0=20DeviceInfo?= =?UTF-8?q?=EB=A5=BC=20query=EC=97=90=EC=84=9C=EB=8F=84=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/DeviceInfoAddHandler.java | 12 ++--- .../application/DeviceRegisterHandler.java | 11 +++-- .../shared/caching/device/TempDeviceInfo.java | 15 ++++++ .../caching/device/TempDeviceInfoStore.java} | 49 +++++++++---------- 4 files changed, 51 insertions(+), 36 deletions(-) create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/shared/caching/device/TempDeviceInfo.java rename modules/main-api/src/main/java/com/whoz_in/main_api/{command/device/application/DeviceInfoStore.java => shared/caching/device/TempDeviceInfoStore.java} (53%) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceInfoAddHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceInfoAddHandler.java index bc34afe5..e96bcd60 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceInfoAddHandler.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceInfoAddHandler.java @@ -1,8 +1,6 @@ package com.whoz_in.main_api.command.device.application; import com.whoz_in.domain.device.DeviceRepository; -import com.whoz_in.domain.device.model.DeviceInfo; -import com.whoz_in.domain.device.model.MacAddress; import com.whoz_in.domain.device.service.DeviceOwnershipService; import com.whoz_in.domain.member.model.MemberId; import com.whoz_in.domain.member.service.MemberFinderService; @@ -11,6 +9,8 @@ import com.whoz_in.domain.network_log.MonitorLogRepository; import com.whoz_in.main_api.command.shared.application.CommandHandler; import com.whoz_in.main_api.shared.application.Handler; +import com.whoz_in.main_api.shared.caching.device.TempDeviceInfo; +import com.whoz_in.main_api.shared.caching.device.TempDeviceInfoStore; import com.whoz_in.main_api.shared.utils.RequesterInfo; import java.time.LocalDateTime; import lombok.RequiredArgsConstructor; @@ -20,7 +20,7 @@ @RequiredArgsConstructor public class DeviceInfoAddHandler implements CommandHandler { private final RequesterInfo requesterInfo; - private final DeviceInfoStore deviceInfoStore; + private final TempDeviceInfoStore tempDeviceInfoStore; private final MemberFinderService memberFinderService; private final DeviceOwnershipService deviceOwnershipService; private final DeviceRepository deviceRepository; @@ -41,9 +41,9 @@ public Void handle(DeviceInfoAdd req) { String mac = managedLog.getMac(); //등록할 DeviceInfo 생성 - DeviceInfo deviceInfo = DeviceInfo.create(req.room(), managedLog.getSsid(), MacAddress.create(mac)); + TempDeviceInfo deviceInfo = new TempDeviceInfo(req.room(), managedLog.getSsid(), mac); //이미 등록된 DeviceInfo가 아닌지 미리 확인 - deviceInfoStore.mustNotExist(requesterId, deviceInfo); + tempDeviceInfoStore.mustNotExist(requesterId.id(), deviceInfo); //모니터 로그에서 현재 접속 중인 맥이 있는지 확인 (넉넉하게 15분) monitorLogRepository.mustExistAfter(mac, LocalDateTime.now().minusMinutes(15)); @@ -56,7 +56,7 @@ public Void handle(DeviceInfoAdd req) { }); //마침내! DeviceInfo를 추가한다. - deviceInfoStore.add(requesterId, deviceInfo); + tempDeviceInfoStore.add(requesterId.id(), deviceInfo); return null; } diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceRegisterHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceRegisterHandler.java index b6a6533f..61faa5d8 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceRegisterHandler.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceRegisterHandler.java @@ -3,11 +3,13 @@ import com.whoz_in.domain.device.DeviceRepository; import com.whoz_in.domain.device.model.Device; import com.whoz_in.domain.device.model.DeviceInfo; +import com.whoz_in.domain.device.model.MacAddress; import com.whoz_in.domain.member.model.MemberId; import com.whoz_in.domain.member.service.MemberFinderService; import com.whoz_in.domain.shared.event.EventBus; import com.whoz_in.main_api.command.shared.application.CommandHandler; import com.whoz_in.main_api.shared.application.Handler; +import com.whoz_in.main_api.shared.caching.device.TempDeviceInfoStore; import com.whoz_in.main_api.shared.utils.RequesterInfo; import java.util.List; import lombok.RequiredArgsConstructor; @@ -17,7 +19,7 @@ @RequiredArgsConstructor public class DeviceRegisterHandler implements CommandHandler { private final RequesterInfo requesterInfo; - private final DeviceInfoStore deviceInfoStore; + private final TempDeviceInfoStore tempDeviceInfoStore; private final MemberFinderService memberFinderService; private final DeviceRepository deviceRepository; private final EventBus eventBus; @@ -28,9 +30,12 @@ public Void handle(DeviceRegister cmd) { MemberId requesterId = requesterInfo.getMemberId(); memberFinderService.mustExist(requesterId); - deviceInfoStore.verifyAllAdded(requesterId, cmd.room()); + tempDeviceInfoStore.verifyAllAdded(requesterId.id(), cmd.room()); - List deviceInfos = deviceInfoStore.takeout(requesterId); + List deviceInfos = tempDeviceInfoStore.takeout(requesterId.id()) + .stream() + .map(cdi-> DeviceInfo.create(cdi.getRoom(), cdi.getSsid(), MacAddress.create(cdi.getMac()))) + .toList(); Device device = Device.create(requesterId, deviceInfos, cmd.deviceName()); deviceRepository.save(device); diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/caching/device/TempDeviceInfo.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/caching/device/TempDeviceInfo.java new file mode 100644 index 00000000..0f10cc05 --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/caching/device/TempDeviceInfo.java @@ -0,0 +1,15 @@ +package com.whoz_in.main_api.shared.caching.device; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@EqualsAndHashCode +@RequiredArgsConstructor +public final class TempDeviceInfo { + private final String room; + private final String ssid; + @EqualsAndHashCode.Exclude + private final String mac; +} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceInfoStore.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/caching/device/TempDeviceInfoStore.java similarity index 53% rename from modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceInfoStore.java rename to modules/main-api/src/main/java/com/whoz_in/main_api/shared/caching/device/TempDeviceInfoStore.java index 4651e0e6..8f054fe5 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceInfoStore.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/caching/device/TempDeviceInfoStore.java @@ -1,11 +1,10 @@ -package com.whoz_in.main_api.command.device.application; +package com.whoz_in.main_api.shared.caching.device; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; -import com.whoz_in.domain.device.model.DeviceInfo; -import com.whoz_in.domain.member.model.MemberId; import com.whoz_in.main_api.config.RoomSsidConfig; import java.util.List; +import java.util.UUID; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -15,30 +14,31 @@ /** * 사전 지식: 사용자는 기기 등록을 위해선 해당 방에 존재하는 와이파이에 대한 맥을(DeviceInfo) 가지고 있어야 하며, 모두 가지면 기기 등록을 시작할 수 있다. - * 따라서 이 클래스는 기기 등록 전까지 맥을 임시 저장 및 관리하는 책임을 가진다. - * (연결 시마다 맥이 바뀌도록 설정한 기기도 있기 때문에 시간 제한을 뒀다.) + * 책임: 따라서 이 클래스는 기기 등록 전까지 맥을 임시 저장 및 관리하는 책임을 가진다. + * 주의: command, query side에서 공용으로 사용하는 것이므로 어느 한 쪽에 의존하는 클래스를 사용하지 않도록 한다. + * 참고: 연결 시마다 맥이 바뀌도록 설정한 기기도 있기 때문에 시간 제한을 뒀다. */ @Component @RequiredArgsConstructor -public final class DeviceInfoStore { - private static final Cache> store = CacheBuilder.newBuilder() +public final class TempDeviceInfoStore { + private static final Cache> store = CacheBuilder.newBuilder() .expireAfterAccess(5, TimeUnit.MINUTES) // 5분 동안 접근이 없으면 만료 .build(); private final RoomSsidConfig ssidConfig; - //이전에 등록되지 않은 DeviceInfo인지 검증 - public void mustNotExist(MemberId ownerId, DeviceInfo deviceInfo){ - List deviceInfos = store.getIfPresent(ownerId); - if (deviceInfos != null && deviceInfos.stream().anyMatch(di->isInSameRoomAndWifi(di, deviceInfo))) + //이전에 등록되지 않은 TempDeviceInfo인지 검증 + public void mustNotExist(UUID ownerId, TempDeviceInfo deviceInfo){ + List deviceInfos = store.getIfPresent(ownerId); + if (deviceInfos != null && deviceInfos.stream().anyMatch(di->di.equals(deviceInfo))) throw new IllegalArgumentException("이미 등록됨"); } //TODO: deviceInfo들에 room이 있는데 room을 굳이 받아야 하나 - //room의 모든 와이파이에 대해 DeviceInfo가 추가되었는지 검증 - public void verifyAllAdded(MemberId ownerId, String room){ - List deviceInfos = get(ownerId); + //room의 모든 와이파이에 대해 CachedDevice가 추가되었는지 검증 + public void verifyAllAdded(UUID ownerId, String room){ + List deviceInfos = get(ownerId); List unregisteredSsids = ssidConfig.getSsids(room).stream() .filter(ssid -> deviceInfos.stream().noneMatch(di -> di.getSsid().equals(ssid))) .toList(); @@ -48,10 +48,10 @@ public void verifyAllAdded(MemberId ownerId, String room){ } //DeviceInfo 추가 - public void add(MemberId ownerId, DeviceInfo newDeviceInfo) { + public void add(UUID ownerId, TempDeviceInfo newDeviceInfo) { try { - List deviceInfos = store.get(ownerId, CopyOnWriteArrayList::new); - deviceInfos.removeIf(di-> isInSameRoomAndWifi(di, newDeviceInfo)); + List deviceInfos = store.get(ownerId, CopyOnWriteArrayList::new); + deviceInfos.removeIf(di-> di.equals(newDeviceInfo)); deviceInfos.add(newDeviceInfo); } catch (ExecutionException e) { throw new IllegalStateException("value 초기화 실패"); @@ -59,24 +59,19 @@ public void add(MemberId ownerId, DeviceInfo newDeviceInfo) { } //불변 반환 - public List get(MemberId ownerId){ - List deviceInfos = store.getIfPresent(ownerId); + public List get(UUID ownerId){ + List deviceInfos = store.getIfPresent(ownerId); return deviceInfos != null ? List.copyOf(deviceInfos) : List.of(); } - public void remove(MemberId ownerId){ + public void remove(UUID ownerId){ store.invalidate(ownerId); } //반환 전 제거 - public List takeout(MemberId ownerId){ - List deviceInfos = get(ownerId); + public List takeout(UUID ownerId){ + List deviceInfos = get(ownerId); remove(ownerId); return deviceInfos; } - - //같은 방, 같은 와이파이에 대해 저장된 정보인지 확인 - private boolean isInSameRoomAndWifi(DeviceInfo deviceInfo1, DeviceInfo deviceInfo2){ - return deviceInfo1.getRoom().equals(deviceInfo2.getRoom()) && deviceInfo1.getSsid().equals(deviceInfo2.getSsid()); - } } From ef285ad9a95a212c7d2274383900260854d4c361 Mon Sep 17 00:00:00 2001 From: coco3x Date: Tue, 14 Jan 2025 00:33:44 +0900 Subject: [PATCH 108/138] =?UTF-8?q?feat(main-api:query):=20=EA=B8=B0?= =?UTF-8?q?=EA=B8=B0=20=EC=A0=95=EB=B3=B4=20=EC=9E=84=EC=8B=9C=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=20=ED=98=84=ED=99=A9=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../whoz_in/api_query_jpa/device/Device.java | 36 +++++++++++++ .../api_query_jpa/device/DeviceInfo.java | 28 ++++++++++ .../device/DeviceInfoJpaViewer.java | 21 ++++++++ .../device/DeviceInfoRepository.java | 18 +++++++ .../security/SecurityFilterChainConfig.java | 3 ++ .../application/TempDeviceInfosStatus.java | 20 +++++++ .../application/TempDeviceInfosStatusGet.java | 8 +++ .../TempDeviceInfosStatusHandler.java | 53 +++++++++++++++++++ .../presentation/DeviceQueryController.java | 30 +++++++++++ .../query/device/view/DeviceInfoViewer.java | 8 +++ .../query/device/view/RegisteredSsids.java | 8 +++ 11 files changed, 233 insertions(+) create mode 100644 modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/Device.java create mode 100644 modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceInfo.java create mode 100644 modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceInfoJpaViewer.java create mode 100644 modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceInfoRepository.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/TempDeviceInfosStatus.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/TempDeviceInfosStatusGet.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/TempDeviceInfosStatusHandler.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/presentation/DeviceQueryController.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/view/DeviceInfoViewer.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/view/RegisteredSsids.java diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/Device.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/Device.java new file mode 100644 index 00000000..c0562d82 --- /dev/null +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/Device.java @@ -0,0 +1,36 @@ +package com.whoz_in.api_query_jpa.device; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToMany; +import java.util.List; +import java.util.UUID; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.Immutable; +import org.hibernate.annotations.Subselect; + +@Entity +@Getter +@Subselect("SELECT d.id , d.member_id " + + "FROM device_entity d") +@Immutable +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Device { + + @Id + @Column(name = "id", nullable = false) + private UUID id; + + @Column(name ="member_id", nullable = false) + private UUID memberId; + + @OneToMany(fetch = FetchType.LAZY) + @JoinColumn(name = "device_id", referencedColumnName = "id") + private List deviceInfos; + +} \ No newline at end of file diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceInfo.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceInfo.java new file mode 100644 index 00000000..67583b8a --- /dev/null +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceInfo.java @@ -0,0 +1,28 @@ +package com.whoz_in.api_query_jpa.device; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import java.util.UUID; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.Immutable; +import org.hibernate.annotations.Subselect; + +@Entity +@Getter +@Subselect("SELECT di.id, di.device_id, di.mac, di.ssid " + + "FROM device_info_entity di") +@Immutable +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class DeviceInfo { + + @Id + private Long id; + + private UUID deviceId; + + private String mac; + + private String ssid; +} \ No newline at end of file diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceInfoJpaViewer.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceInfoJpaViewer.java new file mode 100644 index 00000000..bc593da1 --- /dev/null +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceInfoJpaViewer.java @@ -0,0 +1,21 @@ +package com.whoz_in.api_query_jpa.device; + +import com.whoz_in.main_api.query.device.view.DeviceInfoViewer; +import com.whoz_in.main_api.query.device.view.RegisteredSsids; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + + +@Component +@RequiredArgsConstructor +public class DeviceInfoJpaViewer implements DeviceInfoViewer { + private final DeviceInfoRepository deviceInfoRepository; + @Override + public RegisteredSsids findRegisteredSsids(UUID ownerId, String room, String mac) { + return new RegisteredSsids( + deviceInfoRepository.findAllByMac(ownerId, room, mac).stream() + .map(DeviceInfo::getSsid) + .toList()); + } +} diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceInfoRepository.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceInfoRepository.java new file mode 100644 index 00000000..2f2c4306 --- /dev/null +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceInfoRepository.java @@ -0,0 +1,18 @@ +package com.whoz_in.api_query_jpa.device; + +import java.util.List; +import java.util.UUID; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +public interface DeviceInfoRepository extends JpaRepository { + @Query(value = "SELECT di.id, di.device_id AS deviceId, di.mac, di.ssid " + + "FROM device_entity d " + + "JOIN device_info_entity di ON d.id = di.device_id " + + "WHERE d.member_id = :ownerId " + + "AND di.room = :room " + + "AND di.mac = :mac", + nativeQuery = true) + List findAllByMac(@Param("ownerId") UUID ownerId, @Param("room") String room, @Param("mac") String mac); +} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java b/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java index 65a5a2b8..d72de958 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java @@ -77,6 +77,9 @@ public SecurityFilterChain authenticationFilterChain(HttpSecurity httpSecurity) ); httpSecurity.authorizeHttpRequests(auth-> { //인증 필요 + auth.requestMatchers(HttpMethod.GET, + "/api/v1/device/info-status" + ).authenticated(); auth.requestMatchers(HttpMethod.POST, "/api/v1/device", "/api/v1/device/info" diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/TempDeviceInfosStatus.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/TempDeviceInfosStatus.java new file mode 100644 index 00000000..e4533cc9 --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/TempDeviceInfosStatus.java @@ -0,0 +1,20 @@ +package com.whoz_in.main_api.query.device.application; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.whoz_in.main_api.query.shared.application.Response; +import com.whoz_in.main_api.shared.caching.device.TempDeviceInfoStore; +import java.util.Map; + + +/** + * 이 클래스는 사용자가 등록해야 할 DeviceInfo들의 상태를 가지고 있다.
+ * + * {@code isAddedPerSsid} 맵은 각 SSID의 임시 등록 여부를 나타낸다.
+ * - Key는 사용자가 아직 등록하지 않은 SSID를 의미한다. (db에 없다는 말이다.)
+ * - Value가 {@code true}인 경우, 해당 SSID는 + * {@link TempDeviceInfoStore}에 이미 등록된 것이다.
+ * 모두 true라면 기기 등록을 완료할 수 있다.
+ */ +public record TempDeviceInfosStatus( + @JsonProperty("status") Map isAddedPerSsid +) implements Response {} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/TempDeviceInfosStatusGet.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/TempDeviceInfosStatusGet.java new file mode 100644 index 00000000..bcbcf88e --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/TempDeviceInfosStatusGet.java @@ -0,0 +1,8 @@ +package com.whoz_in.main_api.query.device.application; + +import com.whoz_in.main_api.query.shared.application.Query; + +public record TempDeviceInfosStatusGet( + String room, + String ip +) implements Query {} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/TempDeviceInfosStatusHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/TempDeviceInfosStatusHandler.java new file mode 100644 index 00000000..9047b59a --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/TempDeviceInfosStatusHandler.java @@ -0,0 +1,53 @@ +package com.whoz_in.main_api.query.device.application; + +import com.whoz_in.domain.network_log.ManagedLog; +import com.whoz_in.domain.network_log.ManagedLogRepository; +import com.whoz_in.main_api.config.RoomSsidConfig; +import com.whoz_in.main_api.query.device.view.DeviceInfoViewer; +import com.whoz_in.main_api.query.shared.application.QueryHandler; +import com.whoz_in.main_api.shared.application.Handler; +import com.whoz_in.main_api.shared.caching.device.TempDeviceInfo; +import com.whoz_in.main_api.shared.caching.device.TempDeviceInfoStore; +import com.whoz_in.main_api.shared.utils.RequesterInfo; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; + +@Handler +@RequiredArgsConstructor +public class TempDeviceInfosStatusHandler implements QueryHandler { + private final RoomSsidConfig ssidConfig; + private final RequesterInfo requesterInfo; + private final DeviceInfoViewer deviceInfoViewer; + private final TempDeviceInfoStore tempDeviceInfoStore; + private final ManagedLogRepository managedLogRepository; + + @Override + public TempDeviceInfosStatus handle(TempDeviceInfosStatusGet query) { + UUID requesterId = requesterInfo.getMemberId().id(); + + // 사용자의 기기를 맥으로 찾기 위해 로그를 가져옴 + ManagedLog log = managedLogRepository.getLatestByRoomAndIpAfter( + query.room(), query.ip(), LocalDateTime.now().minusDays(1)); //이거 managed log가 판단해야 함 + // 방에 존재하는 와이파이들 + List roomSsids = ssidConfig.getSsids(query.room()); + // 사용자가 이전에 등록한 기기 정보를 가져옴 + List registeredSsids = deviceInfoViewer + .findRegisteredSsids(requesterId, query.room(), log.getMac()) + .ssids(); + // 임시로 등록한 기기 정보를 가져옴 + List addedTempDeviceInfos = tempDeviceInfoStore.get(requesterId); + // 방에 존재하는 와이파이 중 이전에 등록한 와이파이를 제외하고 임시로 등록되었는지를 체크함 + Map isAddedPerSsid = roomSsids.stream() + .filter(ssid -> !registeredSsids.contains(ssid)) //등록되지 않은 ssid만 남김 + .collect(Collectors.toMap( + ssid -> ssid, + ssid -> addedTempDeviceInfos.stream() + .anyMatch(tdi -> tdi.getSsid().equals(ssid)) + )); + return new TempDeviceInfosStatus(isAddedPerSsid); + } +} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/presentation/DeviceQueryController.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/presentation/DeviceQueryController.java new file mode 100644 index 00000000..927fa0f3 --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/presentation/DeviceQueryController.java @@ -0,0 +1,30 @@ +package com.whoz_in.main_api.query.device.presentation; + +import com.whoz_in.main_api.query.device.application.TempDeviceInfosStatus; +import com.whoz_in.main_api.query.device.application.TempDeviceInfosStatusGet; +import com.whoz_in.main_api.query.shared.application.QueryBus; +import com.whoz_in.main_api.query.shared.presentation.QueryController; +import com.whoz_in.main_api.shared.presentation.CrudResponseCode; +import com.whoz_in.main_api.shared.presentation.ResponseEntityGenerator; +import com.whoz_in.main_api.shared.presentation.SuccessBody; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/v1") +public class DeviceQueryController extends QueryController { + + public DeviceQueryController(QueryBus queryBus) { + super(queryBus); + } + + @GetMapping("/device/info-status") + public ResponseEntity> getTempDeviceInfosStatus(@RequestParam String room, @RequestParam String ip){ + return ResponseEntityGenerator.success( + ask(new TempDeviceInfosStatusGet(room, ip)), + CrudResponseCode.READ); + } +} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/view/DeviceInfoViewer.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/view/DeviceInfoViewer.java new file mode 100644 index 00000000..e3fc4eae --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/view/DeviceInfoViewer.java @@ -0,0 +1,8 @@ +package com.whoz_in.main_api.query.device.view; + +import com.whoz_in.main_api.query.shared.application.Viewer; +import java.util.UUID; + +public interface DeviceInfoViewer extends Viewer { + RegisteredSsids findRegisteredSsids(UUID ownerId, String room, String mac); +} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/view/RegisteredSsids.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/view/RegisteredSsids.java new file mode 100644 index 00000000..7e58aa7d --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/view/RegisteredSsids.java @@ -0,0 +1,8 @@ +package com.whoz_in.main_api.query.device.view; + +import com.whoz_in.main_api.query.shared.application.View; +import java.util.List; + +public record RegisteredSsids( + List ssids +) implements View {} From 6031107f31ba6065d1752de0bfb7bea52d7c3a41 Mon Sep 17 00:00:00 2001 From: coco3x Date: Tue, 14 Jan 2025 03:48:52 +0900 Subject: [PATCH 109/138] =?UTF-8?q?update(main-api):=20DeviceController=20?= =?UTF-8?q?=EC=9D=91=EB=8B=B5=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../command/device/presentation/DeviceController.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/presentation/DeviceController.java b/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/presentation/DeviceController.java index 004484a7..97cdd6ac 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/presentation/DeviceController.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/presentation/DeviceController.java @@ -4,7 +4,9 @@ import com.whoz_in.main_api.command.device.application.DeviceRegister; import com.whoz_in.main_api.command.shared.application.CommandBus; import com.whoz_in.main_api.command.shared.presentation.CommandController; +import com.whoz_in.main_api.shared.presentation.ResponseEntityGenerator; import com.whoz_in.main_api.shared.presentation.SuccessBody; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -22,12 +24,12 @@ public DeviceController(CommandBus commandBus) { @PostMapping("/device/info") public ResponseEntity> addDeviceInfo(@RequestBody DeviceInfoAdd request) { dispatch(request); - return null; + return ResponseEntityGenerator.success("기기 정보 등록 완료", HttpStatus.CREATED); } @PostMapping("/device") public ResponseEntity> registerDevice(@RequestBody DeviceRegister request) { dispatch(request); - return null; + return ResponseEntityGenerator.success("기기 등록 완료", HttpStatus.CREATED); } } From 38be1784f78155314edccdf914cb429fc105b878 Mon Sep 17 00:00:00 2001 From: coco3x Date: Tue, 14 Jan 2025 03:51:53 +0900 Subject: [PATCH 110/138] =?UTF-8?q?update(network-api):=20NetworkConfig=20?= =?UTF-8?q?-=20managed=20ni=EB=93=A4=20=EC=A1=B0=ED=9A=8C=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../whoz_in/network_api/common/StubNetworkInterfaces.java | 2 +- .../com/whoz_in/network_api/config/NetworkConfig.java | 8 ++++++-- .../network_api/system_validator/SystemValidator.java | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/common/StubNetworkInterfaces.java b/modules/network-api/src/main/java/com/whoz_in/network_api/common/StubNetworkInterfaces.java index b1fe6cbf..3c376f6b 100644 --- a/modules/network-api/src/main/java/com/whoz_in/network_api/common/StubNetworkInterfaces.java +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/common/StubNetworkInterfaces.java @@ -19,6 +19,6 @@ public final class StubNetworkInterfaces implements SystemNetworkInterfaces{ @Override public List getLatest() { - return networkConfig.getNetworkInterfaces(); + return networkConfig.getAllNIs(); } } diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/config/NetworkConfig.java b/modules/network-api/src/main/java/com/whoz_in/network_api/config/NetworkConfig.java index 6fdfbc05..b97e6f57 100644 --- a/modules/network-api/src/main/java/com/whoz_in/network_api/config/NetworkConfig.java +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/config/NetworkConfig.java @@ -14,7 +14,8 @@ public class NetworkConfig { private final String room; private final String sudoPassword; - private final List networkInterfaces; + private final List allNIs; + private final List managedNIs; private final NetworkInterface monitorNI; private final List mdnsNIs; private final List arpNIs; @@ -45,7 +46,10 @@ public NetworkConfig( generateCommand(arpCommandTemplate, arp.interfaceName())); }) .toList(); - this.networkInterfaces = Stream.of(monitorNI, mdnsNIs, arpNIs) + this.managedNIs = Stream.of(mdnsNIs, arpNIs) + .flatMap(Collection::stream) + .toList(); + this.allNIs = Stream.of(monitorNI, this.managedNIs) .flatMap(list -> list instanceof Collection ? ((Collection) list).stream() : Stream.of((NetworkInterface) list)) .toList(); diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/system_validator/SystemValidator.java b/modules/network-api/src/main/java/com/whoz_in/network_api/system_validator/SystemValidator.java index edf07bb4..9fb6d9e5 100644 --- a/modules/network-api/src/main/java/com/whoz_in/network_api/system_validator/SystemValidator.java +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/system_validator/SystemValidator.java @@ -40,7 +40,7 @@ public SystemValidator( //네트워크 인터페이스 정보 List system = systemNIs.getLatest(); - List setting = config.getNetworkInterfaces(); + List setting = config.getAllNIs(); //네트워크 인터페이스 출력 log.info("\n시스템 네트워크 인터페이스 - \n{}\n설정된 네트워크 인터페이스 - \n{}", @@ -64,7 +64,7 @@ private void checkRegularly() { log.info("시스템 검증 시작.."); //네트워크 인터페이스 상태 검증 ValidationResult result = networkInterfaceValidator.getValidationResult( - systemNIs.getLatest(), config.getNetworkInterfaces()); + systemNIs.getLatest(), config.getAllNIs()); //더 많은 검증하면 result에 추가하기.. if (result.hasErrors()) { From fc2da69fec80cf7751fc3cc91568fab9ac24bd30 Mon Sep 17 00:00:00 2001 From: coco3x Date: Tue, 14 Jan 2025 05:27:50 +0900 Subject: [PATCH 111/138] =?UTF-8?q?chore(main-api):=20=EC=8B=9C=ED=81=90?= =?UTF-8?q?=EB=A6=AC=ED=8B=B0=EB=A1=9C=20=EA=B5=AC=ED=98=84=ED=95=9C=20Req?= =?UTF-8?q?uesterInfo=20=ED=8C=A8=ED=82=A4=EC=A7=80=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../security}/SpringSecurityRequesterInfo.java | 4 ++-- .../java/com/whoz_in/main_api/shared/RequesterInfoTest.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename modules/main-api/src/main/java/com/whoz_in/main_api/{shared/utils => config/security}/SpringSecurityRequesterInfo.java (87%) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/utils/SpringSecurityRequesterInfo.java b/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SpringSecurityRequesterInfo.java similarity index 87% rename from modules/main-api/src/main/java/com/whoz_in/main_api/shared/utils/SpringSecurityRequesterInfo.java rename to modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SpringSecurityRequesterInfo.java index 55762f3d..df159c33 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/utils/SpringSecurityRequesterInfo.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SpringSecurityRequesterInfo.java @@ -1,7 +1,7 @@ -package com.whoz_in.main_api.shared.utils; +package com.whoz_in.main_api.config.security; import com.whoz_in.domain.member.model.MemberId; -import com.whoz_in.main_api.config.security.JwtAuthentication; +import com.whoz_in.main_api.shared.utils.RequesterInfo; import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.security.core.context.SecurityContextHolder; diff --git a/modules/main-api/src/test/java/com/whoz_in/main_api/shared/RequesterInfoTest.java b/modules/main-api/src/test/java/com/whoz_in/main_api/shared/RequesterInfoTest.java index 86487b9c..567d6fec 100644 --- a/modules/main-api/src/test/java/com/whoz_in/main_api/shared/RequesterInfoTest.java +++ b/modules/main-api/src/test/java/com/whoz_in/main_api/shared/RequesterInfoTest.java @@ -2,7 +2,7 @@ import com.whoz_in.domain.member.model.MemberId; import com.whoz_in.main_api.config.security.JwtAuthentication; -import com.whoz_in.main_api.shared.utils.SpringSecurityRequesterInfo; +import com.whoz_in.main_api.config.security.SpringSecurityRequesterInfo; import java.util.Collections; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; From 252c4c590d5e1d0a5f731b21af3421eeecf18023 Mon Sep 17 00:00:00 2001 From: coco3x Date: Tue, 14 Jan 2025 05:31:25 +0900 Subject: [PATCH 112/138] =?UTF-8?q?feat(main-api):=20=EC=84=9C=EB=B2=84=20?= =?UTF-8?q?=EA=B0=84=20=ED=86=B5=EC=8B=A0=EC=9D=84=20=EC=9C=84=ED=95=9C=20?= =?UTF-8?q?=EB=B3=B4=EC=95=88=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/security/SecurityConfig.java | 9 +++++ .../security/SecurityFilterChainConfig.java | 21 ++++++++++- .../security/ServerAuthenticationFilter.java | 37 +++++++++++++++++++ .../main/resources/application-main-api.yml | 4 +- 4 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/config/security/ServerAuthenticationFilter.java diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityConfig.java b/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityConfig.java index a8f2dc1c..d2d9c38b 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityConfig.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityConfig.java @@ -25,6 +25,15 @@ public FilterRegistrationBean jwtAuthenticationFilterRe return registrationBean; } + //위와 동일한 이유로 추가 + @Bean + public FilterRegistrationBean serverAuthenticationFilterRegistration( + ServerAuthenticationFilter serverAuthenticationFilter) { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(serverAuthenticationFilter); + registrationBean.setEnabled(false); + return registrationBean; + } + @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java b/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java index d72de958..9c4aa98b 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java @@ -23,9 +23,25 @@ public class SecurityFilterChainConfig { private final ClientRegistrationRepository clientRegistrationRepository; private final LoginSuccessHandler loginSuccessHandler; private final LoginFailureHandler loginFailureHandler; + private final ServerAuthenticationFilter serverAuthenticationFilter; private final JwtAuthenticationFilter jwtAuthenticationFilter; private final CorsConfigurationSource corsConfigurationSource; + @Bean + @Order(0) + public SecurityFilterChain serverToServerFilterChain(HttpSecurity httpSecurity) throws Exception { + httpSecurity.securityMatcher( + "/api/v1/private-ip" + ); + + commonConfigurations(httpSecurity); + httpSecurity.logout(AbstractHttpConfigurer::disable); + //TODO: ip 화이트 리스트 + httpSecurity.addFilterAt(serverAuthenticationFilter, LogoutFilter.class); + + return httpSecurity.build(); + } + @Bean @Order(1) public SecurityFilterChain oauth2FilterChain(HttpSecurity httpSecurity) throws Exception { @@ -50,7 +66,7 @@ public SecurityFilterChain oauth2FilterChain(HttpSecurity httpSecurity) throws E return httpSecurity.build(); } - //POST, PUT, PATCH, DELETE 중 인증인가 필요 없는 엔드포인트 + //인증인가 필요 없는 엔드포인트 @Bean @Order(2) public SecurityFilterChain noAuthenticationFilterChain(HttpSecurity httpSecurity) throws Exception { @@ -78,7 +94,8 @@ public SecurityFilterChain authenticationFilterChain(HttpSecurity httpSecurity) httpSecurity.authorizeHttpRequests(auth-> { //인증 필요 auth.requestMatchers(HttpMethod.GET, - "/api/v1/device/info-status" + "/api/v1/device/info-status", + "/api/v1/private-ip/*" ).authenticated(); auth.requestMatchers(HttpMethod.POST, "/api/v1/device", diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/ServerAuthenticationFilter.java b/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/ServerAuthenticationFilter.java new file mode 100644 index 00000000..131059f2 --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/ServerAuthenticationFilter.java @@ -0,0 +1,37 @@ +package com.whoz_in.main_api.config.security; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Optional; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +@Component +public class ServerAuthenticationFilter extends OncePerRequestFilter { + private final String apiKey; + + public ServerAuthenticationFilter(@Value("${api-key}") String apiKey) { + this.apiKey = apiKey; + } + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, + FilterChain filterChain) throws ServletException, IOException { + Optional extractedKey = extractApiKey(request); + + if (extractedKey.filter(apiKey::equals).isEmpty()) { + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid API Key"); + return; + } + + filterChain.doFilter(request, response); + } + + private Optional extractApiKey(HttpServletRequest request){ + return Optional.ofNullable(request.getHeader("Authorization")); + } +} diff --git a/modules/main-api/src/main/resources/application-main-api.yml b/modules/main-api/src/main/resources/application-main-api.yml index 6e8d4833..176c86d9 100644 --- a/modules/main-api/src/main/resources/application-main-api.yml +++ b/modules/main-api/src/main/resources/application-main-api.yml @@ -17,7 +17,9 @@ logging: frontend: base-url: ${FRONTEND_URL} -https-enabled: ${HTTPS-ENABLED} +api-key: ${API_KEY} + +https-enabled: ${HTTPS_ENABLED} oauth: redirectUri: ${OAUTH_REDIRECT_URL} From 168323f7b116ac9817230c793dce0c1f95f02894 Mon Sep 17 00:00:00 2001 From: coco3x Date: Tue, 14 Jan 2025 05:33:13 +0900 Subject: [PATCH 113/138] =?UTF-8?q?feat(main-api):=20network-api=EA=B0=80?= =?UTF-8?q?=20=EC=9E=90=EC=8B=A0=EC=9D=98=20private=20ip=EB=A5=BC=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8A=94=20?= =?UTF-8?q?api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../private_ip/PrivateIpController.java | 22 +++++++++++++ .../command/private_ip/PrivateIpUpdate.java | 15 +++++++++ .../private_ip/PrivateIpUpdateHandler.java | 18 +++++++++++ .../caching/private_ip/PrivateIpStore.java | 31 +++++++++++++++++++ 4 files changed, 86 insertions(+) create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/command/private_ip/PrivateIpController.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/command/private_ip/PrivateIpUpdate.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/command/private_ip/PrivateIpUpdateHandler.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/shared/caching/private_ip/PrivateIpStore.java diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/command/private_ip/PrivateIpController.java b/modules/main-api/src/main/java/com/whoz_in/main_api/command/private_ip/PrivateIpController.java new file mode 100644 index 00000000..d8153af7 --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/command/private_ip/PrivateIpController.java @@ -0,0 +1,22 @@ +package com.whoz_in.main_api.command.private_ip; + +import com.whoz_in.main_api.command.shared.application.CommandBus; +import com.whoz_in.main_api.command.shared.presentation.CommandController; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/v1") +public class PrivateIpController extends CommandController { + + public PrivateIpController(CommandBus commandBus) { + super(commandBus); + } + + @PutMapping("/private-ip") + public void updatePrivateIp(@RequestBody PrivateIpUpdate req){ + dispatch(req); + } +} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/command/private_ip/PrivateIpUpdate.java b/modules/main-api/src/main/java/com/whoz_in/main_api/command/private_ip/PrivateIpUpdate.java new file mode 100644 index 00000000..78e7ea64 --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/command/private_ip/PrivateIpUpdate.java @@ -0,0 +1,15 @@ +package com.whoz_in.main_api.command.private_ip; + +import com.whoz_in.domain.device.model.IpAddress; +import com.whoz_in.main_api.command.shared.application.Command; +import java.util.Map; + +public record PrivateIpUpdate( + String room, + Map privateIpList //Map<와이파이이름, 아이피> +) implements Command { + + public PrivateIpUpdate { + privateIpList.values().forEach(IpAddress::create); //아이피 형식 검증 + } +} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/command/private_ip/PrivateIpUpdateHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/command/private_ip/PrivateIpUpdateHandler.java new file mode 100644 index 00000000..4f30dd3f --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/command/private_ip/PrivateIpUpdateHandler.java @@ -0,0 +1,18 @@ +package com.whoz_in.main_api.command.private_ip; + +import com.whoz_in.main_api.command.shared.application.CommandHandler; +import com.whoz_in.main_api.shared.application.Handler; +import com.whoz_in.main_api.shared.caching.private_ip.PrivateIpStore; +import lombok.RequiredArgsConstructor; + +@Handler +@RequiredArgsConstructor +public class PrivateIpUpdateHandler implements CommandHandler { + private final PrivateIpStore privateIpStore; + + @Override + public Void handle(PrivateIpUpdate command) { + privateIpStore.put(command.room(), command.privateIpList()); + return null; + } +} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/caching/private_ip/PrivateIpStore.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/caching/private_ip/PrivateIpStore.java new file mode 100644 index 00000000..6c424e72 --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/caching/private_ip/PrivateIpStore.java @@ -0,0 +1,31 @@ +package com.whoz_in.main_api.shared.caching.private_ip; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.whoz_in.main_api.config.RoomSsidConfig; +import java.util.Map; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public final class PrivateIpStore { + //Cache<방, Map> + private static final Cache> store = CacheBuilder.newBuilder().build(); + private final RoomSsidConfig ssidConfig; + + public void put(String room, Map privateIps){ + store.put(room, privateIps); + } + + public Map get(String room){ + Map privateIps = store.getIfPresent(room); + if (privateIps == null){ + throw new IllegalStateException("방에 대한 내부 아이피 정보가 없음"); //main-api 서버 시작된지 얼마 안됐을 때 or 잘못된 room을 넘겼을 때 + } + if (privateIps.size() != ssidConfig.getSsids(room).size()){ + throw new IllegalStateException(room + "의 내부 아이피가 올바르지 않은 상태"); //해당 방의 와이파이가 잘 연결됐는지 확인해봐야 함 + } + return privateIps; + } +} From cd2e72c040c6c126af47919cf8cc098861b8f6ea Mon Sep 17 00:00:00 2001 From: coco3x Date: Tue, 14 Jan 2025 05:34:57 +0900 Subject: [PATCH 114/138] =?UTF-8?q?feat(network-api):=20=EC=9E=90=EC=8B=A0?= =?UTF-8?q?=EC=9D=98=20=EB=82=B4=EB=B6=80=20=EC=95=84=EC=9D=B4=ED=94=BC?= =?UTF-8?q?=EB=A5=BC=20=EC=A3=BC=EA=B8=B0=EC=A0=81=EC=9C=BC=EB=A1=9C=20mai?= =?UTF-8?q?n-api=EC=97=90=20=EC=A0=80=EC=9E=A5=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/RestTemplateConfig.java | 14 ++++ .../private_ip/HttpPrivateIpWriter.java | 72 +++++++++++++++++++ .../private_ip/PrivateIpUpdater.java | 43 +++++++++++ .../private_ip/PrivateIpWriter.java | 9 +++ .../private_ip/SystemPrivateIpResolver.java | 25 +++++++ .../resources/application-network-api.yml | 4 ++ 6 files changed, 167 insertions(+) create mode 100644 modules/network-api/src/main/java/com/whoz_in/network_api/config/RestTemplateConfig.java create mode 100644 modules/network-api/src/main/java/com/whoz_in/network_api/private_ip/HttpPrivateIpWriter.java create mode 100644 modules/network-api/src/main/java/com/whoz_in/network_api/private_ip/PrivateIpUpdater.java create mode 100644 modules/network-api/src/main/java/com/whoz_in/network_api/private_ip/PrivateIpWriter.java create mode 100644 modules/network-api/src/main/java/com/whoz_in/network_api/private_ip/SystemPrivateIpResolver.java diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/config/RestTemplateConfig.java b/modules/network-api/src/main/java/com/whoz_in/network_api/config/RestTemplateConfig.java new file mode 100644 index 00000000..e999cd28 --- /dev/null +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/config/RestTemplateConfig.java @@ -0,0 +1,14 @@ +package com.whoz_in.network_api.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class RestTemplateConfig { + + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } +} \ No newline at end of file diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/private_ip/HttpPrivateIpWriter.java b/modules/network-api/src/main/java/com/whoz_in/network_api/private_ip/HttpPrivateIpWriter.java new file mode 100644 index 00000000..9a82c0fa --- /dev/null +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/private_ip/HttpPrivateIpWriter.java @@ -0,0 +1,72 @@ +package com.whoz_in.network_api.private_ip; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.stereotype.Component; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.ResourceAccessException; +import org.springframework.web.client.RestTemplate; + +//http로 알리도록 구현 +@Slf4j +@Component +public final class HttpPrivateIpWriter implements PrivateIpWriter { + private final RestTemplate restTemplate; + private final ObjectMapper objectMapper; + private final String mainApiBaseUrl; + private final String mainApiKey; + + public HttpPrivateIpWriter(RestTemplate restTemplate, ObjectMapper objectMapper, + @Value("${main-api.base-url}") String mainApiBaseUrl, + @Value("${main-api.api-key}") String mainApiKey) { + this.restTemplate = restTemplate; + this.objectMapper = objectMapper; + this.mainApiBaseUrl = mainApiBaseUrl; + this.mainApiKey = mainApiKey; + } + + //TODO: 다른 요청도 하게 되면 공통 로직 묶기 + @Override + public boolean write(String room, Map privateIps) { + + HttpHeaders headers = new HttpHeaders(); + headers.set("Authorization", mainApiKey); + headers.set("Content-Type", "application/json"); + + HttpEntity requestEntity = new HttpEntity<>(createRequestBody(room, privateIps), headers); + + try { + restTemplate.exchange( + mainApiBaseUrl + "/api/v1/private-ip", + HttpMethod.PUT, + requestEntity, + Void.class + ); + return true; + } catch (ResourceAccessException e){ + log.error("main api에 접근할 수 없음 : {}", e.getMessage()); //서버가 꺼져있는지 확인 + } catch (HttpClientErrorException.Forbidden e) { + log.error("Api key 인증 실패 : {}", e.getMessage()); + } catch (Exception e) { + log.error("알 수 없는 예외 : {}", e.getMessage()); + } + return false; + } + + private String createRequestBody(String room, Map privateIps) { + try { + return objectMapper.writeValueAsString(Map.of( + "room", room, + "private_ip_list", privateIps + )); + } catch (JsonProcessingException e) { + throw new RuntimeException("Failed to serialize request body", e); + } + } +} diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/private_ip/PrivateIpUpdater.java b/modules/network-api/src/main/java/com/whoz_in/network_api/private_ip/PrivateIpUpdater.java new file mode 100644 index 00000000..fa376a93 --- /dev/null +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/private_ip/PrivateIpUpdater.java @@ -0,0 +1,43 @@ +package com.whoz_in.network_api.private_ip; + +import com.whoz_in.network_api.common.NetworkInterface; +import com.whoz_in.network_api.config.NetworkConfig; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +//주기적으로 자신의 내부 아이피를 알아내고 PrivateIpWriter를 이용하여 main-api에 저장 +@Slf4j +@Component +@RequiredArgsConstructor +public class PrivateIpUpdater { + private Map sent = Map.of(); + private final NetworkConfig networkConfig; + private final PrivateIpWriter writer; + + @Scheduled(fixedRate = 30000) + private void update() { + Map privateIp = getPrivateIpPerSsid(); + if (sent.equals(privateIp)) + return; + if (writer.write(networkConfig.getRoom(), privateIp)) { + sent = privateIp; + log.info("[private ip] updated"); + } + } + + private Map getPrivateIpPerSsid(){ + List networkInterfaces = networkConfig.getManagedNIs(); + //아이피를 얻지 못했을 경우 담지 않는다. + Map privateIps = new HashMap<>(); + for (NetworkInterface ni : networkInterfaces) { + SystemPrivateIpResolver.getIPv4(ni.getInterfaceName()) + .ifPresent(ip->privateIps.put(ni.getAltSsid(), ip)); + } + return privateIps; + } +} diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/private_ip/PrivateIpWriter.java b/modules/network-api/src/main/java/com/whoz_in/network_api/private_ip/PrivateIpWriter.java new file mode 100644 index 00000000..85de5144 --- /dev/null +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/private_ip/PrivateIpWriter.java @@ -0,0 +1,9 @@ +package com.whoz_in.network_api.private_ip; + +import java.util.Map; + +//main-api에게 자신(network-api)이 가진 내부 아이피를 알리는 기능 +public interface PrivateIpWriter { + //반환 값은 성공 여부를 나타낸다. + boolean write(String room, Map privateIps); //Map<방, Optional<아이피>> +} diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/private_ip/SystemPrivateIpResolver.java b/modules/network-api/src/main/java/com/whoz_in/network_api/private_ip/SystemPrivateIpResolver.java new file mode 100644 index 00000000..f9ab1072 --- /dev/null +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/private_ip/SystemPrivateIpResolver.java @@ -0,0 +1,25 @@ +package com.whoz_in.network_api.private_ip; + +import java.net.InetAddress; +import java.net.SocketException; +import java.util.Collections; +import java.util.Optional; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +//내부 아이피를 알아내는 클래스 +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class SystemPrivateIpResolver { + public static Optional getIPv4(String interfaceName) { + try { + return Collections.list(java.net.NetworkInterface.getNetworkInterfaces()).stream() + .filter(networkInterface -> networkInterface.getName().equals(interfaceName)) + .flatMap(networkInterface -> Collections.list(networkInterface.getInetAddresses()).stream()) + .filter(address -> !address.isLoopbackAddress() && address instanceof java.net.Inet4Address) + .map(InetAddress::getHostAddress) + .findAny(); + } catch (SocketException e) { + throw new IllegalStateException("시스템에 네트워크 인터페이스가 아예 존재하지 않음"); + } + } +} diff --git a/modules/network-api/src/main/resources/application-network-api.yml b/modules/network-api/src/main/resources/application-network-api.yml index 0d3496f7..d561be38 100644 --- a/modules/network-api/src/main/resources/application-network-api.yml +++ b/modules/network-api/src/main/resources/application-network-api.yml @@ -18,5 +18,9 @@ command: sudo_password: ${SUDO_PASSWORD} +main-api: + base-url: ${MAIN_API_BASE_URL} + api-key: ${MAIN_API_API_KEY} + logging: config: "classpath:logback-common.xml" \ No newline at end of file From 90f5382180aff9e39b2b36671d9ea1dff7dd4a65 Mon Sep 17 00:00:00 2001 From: coco3x Date: Tue, 14 Jan 2025 05:35:50 +0900 Subject: [PATCH 115/138] =?UTF-8?q?feat(master-api):=20=EB=82=B4=EB=B6=80?= =?UTF-8?q?=20=EC=95=84=EC=9D=B4=ED=94=BC=EB=A5=BC=20main-api=EC=9D=98=20?= =?UTF-8?q?=ED=95=B8=EB=93=A4=EB=9F=AC=EB=A5=BC=20=ED=86=B5=ED=95=B4=20?= =?UTF-8?q?=EC=A7=81=EC=A0=91=20=EC=A0=80=EC=9E=A5=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=EC=B2=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MainApiHandlerPrivateIpWriter.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 modules/master-api/src/main/java/com/whoz_in/master_api/private_ip/MainApiHandlerPrivateIpWriter.java diff --git a/modules/master-api/src/main/java/com/whoz_in/master_api/private_ip/MainApiHandlerPrivateIpWriter.java b/modules/master-api/src/main/java/com/whoz_in/master_api/private_ip/MainApiHandlerPrivateIpWriter.java new file mode 100644 index 00000000..75d3ac1b --- /dev/null +++ b/modules/master-api/src/main/java/com/whoz_in/master_api/private_ip/MainApiHandlerPrivateIpWriter.java @@ -0,0 +1,22 @@ +package com.whoz_in.master_api.private_ip; + +import com.whoz_in.main_api.command.private_ip.PrivateIpUpdate; +import com.whoz_in.main_api.command.private_ip.PrivateIpUpdateHandler; +import com.whoz_in.network_api.private_ip.PrivateIpWriter; +import java.util.Map; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Component; + +//main-api의 핸들러를 직접 호출하여 내부 아이피를 최신화함 +@Primary +@Component +@RequiredArgsConstructor +public class MainApiHandlerPrivateIpWriter implements PrivateIpWriter { + private final PrivateIpUpdateHandler privateIpUpdateHandler; + @Override + public boolean write(String room, Map privateIps) { + privateIpUpdateHandler.handle(new PrivateIpUpdate(room, privateIps)); + return true; + } +} From c1c35d0b9c238519644d22c6132bf2a9efdbd05a Mon Sep 17 00:00:00 2001 From: coco3x Date: Tue, 14 Jan 2025 05:37:57 +0900 Subject: [PATCH 116/138] =?UTF-8?q?feat(main-api):=20=EB=B0=A9=EC=9D=B4=20?= =?UTF-8?q?=EA=B0=80=EC=A7=80=EA=B3=A0=20=EC=9E=88=EB=8A=94=20=EB=82=B4?= =?UTF-8?q?=EB=B6=80=20=EC=95=84=EC=9D=B4=ED=94=BC=EB=A5=BC=20=EB=B0=98?= =?UTF-8?q?=ED=99=98=ED=95=98=EB=8A=94=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../query/private_ip/PrivateIpList.java | 8 ++++++ .../query/private_ip/PrivateIpListGet.java | 7 ++++++ .../private_ip/PrivateIpListGetHandler.java | 17 +++++++++++++ .../private_ip/PrivateIpQueryController.java | 25 +++++++++++++++++++ 4 files changed, 57 insertions(+) create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpList.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpListGet.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpListGetHandler.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpQueryController.java diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpList.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpList.java new file mode 100644 index 00000000..3ecf46db --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpList.java @@ -0,0 +1,8 @@ +package com.whoz_in.main_api.query.private_ip; + +import com.whoz_in.main_api.query.shared.application.Response; +import java.util.List; + +public record PrivateIpList( + List ipList +) implements Response {} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpListGet.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpListGet.java new file mode 100644 index 00000000..44e441d3 --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpListGet.java @@ -0,0 +1,7 @@ +package com.whoz_in.main_api.query.private_ip; + +import com.whoz_in.main_api.query.shared.application.Query; + +public record PrivateIpListGet( + String room +) implements Query {} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpListGetHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpListGetHandler.java new file mode 100644 index 00000000..f80f1094 --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpListGetHandler.java @@ -0,0 +1,17 @@ +package com.whoz_in.main_api.query.private_ip; + +import com.whoz_in.main_api.query.shared.application.QueryHandler; +import com.whoz_in.main_api.shared.application.Handler; +import com.whoz_in.main_api.shared.caching.private_ip.PrivateIpStore; +import lombok.RequiredArgsConstructor; + +@Handler +@RequiredArgsConstructor +public class PrivateIpListGetHandler implements QueryHandler { + private final PrivateIpStore privateIpStore; + @Override + public PrivateIpList handle(PrivateIpListGet query) { + return new PrivateIpList(privateIpStore.get(query.room()).values().stream() + .toList()); + } +} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpQueryController.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpQueryController.java new file mode 100644 index 00000000..164a5404 --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpQueryController.java @@ -0,0 +1,25 @@ +package com.whoz_in.main_api.query.private_ip; + +import com.whoz_in.main_api.query.shared.application.QueryBus; +import com.whoz_in.main_api.query.shared.presentation.QueryController; +import com.whoz_in.main_api.shared.presentation.CrudResponseCode; +import com.whoz_in.main_api.shared.presentation.ResponseEntityGenerator; +import com.whoz_in.main_api.shared.presentation.SuccessBody; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/v1") +public class PrivateIpQueryController extends QueryController { + public PrivateIpQueryController(QueryBus queryBus) { + super(queryBus); + } + + @GetMapping("/private-ip/{room}") + public ResponseEntity> getPrivateIps(@PathVariable String room){ + return ResponseEntityGenerator.success(ask(new PrivateIpListGet(room)), CrudResponseCode.READ); + } +} From 94600eeee07601ed2cc71072d391b28cbbdd9028 Mon Sep 17 00:00:00 2001 From: coco3x Date: Tue, 14 Jan 2025 06:10:35 +0900 Subject: [PATCH 117/138] =?UTF-8?q?style(main-api):=20=EB=B3=80=EC=88=98?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../command/device/application/DeviceRegisterHandler.java | 2 +- .../query/device/application/TempDeviceInfosStatus.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceRegisterHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceRegisterHandler.java index 61faa5d8..8843af23 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceRegisterHandler.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceRegisterHandler.java @@ -34,7 +34,7 @@ public Void handle(DeviceRegister cmd) { List deviceInfos = tempDeviceInfoStore.takeout(requesterId.id()) .stream() - .map(cdi-> DeviceInfo.create(cdi.getRoom(), cdi.getSsid(), MacAddress.create(cdi.getMac()))) + .map(tempDI-> DeviceInfo.create(tempDI.getRoom(), tempDI.getSsid(), MacAddress.create(tempDI.getMac()))) .toList(); Device device = Device.create(requesterId, deviceInfos, cmd.deviceName()); diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/TempDeviceInfosStatus.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/TempDeviceInfosStatus.java index e4533cc9..1b21dcd1 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/TempDeviceInfosStatus.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/TempDeviceInfosStatus.java @@ -9,12 +9,12 @@ /** * 이 클래스는 사용자가 등록해야 할 DeviceInfo들의 상태를 가지고 있다.
* - * {@code isAddedPerSsid} 맵은 각 SSID의 임시 등록 여부를 나타낸다.
+ * {@code status} 맵은 각 SSID의 임시 등록 여부를 나타낸다.
* - Key는 사용자가 아직 등록하지 않은 SSID를 의미한다. (db에 없다는 말이다.)
- * - Value가 {@code true}인 경우, 해당 SSID는 + * - Value가 true인 경우, 해당 SSID는 * {@link TempDeviceInfoStore}에 이미 등록된 것이다.
* 모두 true라면 기기 등록을 완료할 수 있다.
*/ public record TempDeviceInfosStatus( - @JsonProperty("status") Map isAddedPerSsid + Map status ) implements Response {} From 488d9649e13a53af8869c5ec83aa96b231f784a7 Mon Sep 17 00:00:00 2001 From: coco3x Date: Wed, 15 Jan 2025 13:11:56 +0900 Subject: [PATCH 118/138] =?UTF-8?q?chore(main-api):=20=EC=84=9C=EB=B2=84?= =?UTF-8?q?=20=EA=B0=84=20=ED=86=B5=EC=8B=A0=20=EC=97=94=EB=93=9C=ED=8F=AC?= =?UTF-8?q?=EC=9D=B8=ED=8A=B8=20prefix=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main_api/command/private_ip/PrivateIpController.java | 3 ++- .../main_api/config/security/SecurityFilterChainConfig.java | 2 +- .../whoz_in/network_api/private_ip/HttpPrivateIpWriter.java | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/command/private_ip/PrivateIpController.java b/modules/main-api/src/main/java/com/whoz_in/main_api/command/private_ip/PrivateIpController.java index d8153af7..765eef1d 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/command/private_ip/PrivateIpController.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/command/private_ip/PrivateIpController.java @@ -7,8 +7,9 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +//server to server @RestController -@RequestMapping("/api/v1") +@RequestMapping("/internal/api/v1") public class PrivateIpController extends CommandController { public PrivateIpController(CommandBus commandBus) { diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java b/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java index 9c4aa98b..9c454eb4 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java @@ -31,7 +31,7 @@ public class SecurityFilterChainConfig { @Order(0) public SecurityFilterChain serverToServerFilterChain(HttpSecurity httpSecurity) throws Exception { httpSecurity.securityMatcher( - "/api/v1/private-ip" + "/internal/**" ); commonConfigurations(httpSecurity); diff --git a/modules/network-api/src/main/java/com/whoz_in/network_api/private_ip/HttpPrivateIpWriter.java b/modules/network-api/src/main/java/com/whoz_in/network_api/private_ip/HttpPrivateIpWriter.java index 9a82c0fa..c5de809a 100644 --- a/modules/network-api/src/main/java/com/whoz_in/network_api/private_ip/HttpPrivateIpWriter.java +++ b/modules/network-api/src/main/java/com/whoz_in/network_api/private_ip/HttpPrivateIpWriter.java @@ -43,7 +43,7 @@ public boolean write(String room, Map privateIps) { try { restTemplate.exchange( - mainApiBaseUrl + "/api/v1/private-ip", + mainApiBaseUrl + "/internal/api/v1/private-ip", HttpMethod.PUT, requestEntity, Void.class From fd522be236c24c65555c6c51344cf8dbf2282110 Mon Sep 17 00:00:00 2001 From: coco3x Date: Wed, 15 Jan 2025 14:05:18 +0900 Subject: [PATCH 119/138] =?UTF-8?q?update(main-api):=20=EB=82=B4=EB=B6=80?= =?UTF-8?q?=20=EC=95=84=EC=9D=B4=ED=94=BC=20=EC=A1=B0=ED=9A=8C=20api=20-?= =?UTF-8?q?=20=EC=A0=84=EC=B2=B4=EB=A5=BC=20=EB=B0=98=ED=99=98=ED=95=A0=20?= =?UTF-8?q?=EC=88=98=20=EC=9E=88=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main_api/config/RoomSsidConfig.java | 4 +++- .../security/SecurityFilterChainConfig.java | 2 +- .../query/private_ip/PrivateIpListGet.java | 3 ++- .../private_ip/PrivateIpListGetHandler.java | 7 +++++-- .../private_ip/PrivateIpQueryController.java | 5 +++-- .../caching/private_ip/PrivateIpStore.java | 20 ++++++++++++++++--- 6 files changed, 31 insertions(+), 10 deletions(-) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/config/RoomSsidConfig.java b/modules/main-api/src/main/java/com/whoz_in/main_api/config/RoomSsidConfig.java index 712dd1c2..b6978130 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/config/RoomSsidConfig.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/config/RoomSsidConfig.java @@ -12,7 +12,9 @@ public class RoomSsidConfig { private final Map> rooms; - + public List getRooms(){ + return rooms.keySet().stream().toList(); + } public List getSsids(String room){ List ssids = this.rooms.get(room); if (ssids == null) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java b/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java index 9c454eb4..653be0f9 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java @@ -95,7 +95,7 @@ public SecurityFilterChain authenticationFilterChain(HttpSecurity httpSecurity) //인증 필요 auth.requestMatchers(HttpMethod.GET, "/api/v1/device/info-status", - "/api/v1/private-ip/*" + "/api/v1/private-ip" ).authenticated(); auth.requestMatchers(HttpMethod.POST, "/api/v1/device", diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpListGet.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpListGet.java index 44e441d3..81eb2798 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpListGet.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpListGet.java @@ -1,7 +1,8 @@ package com.whoz_in.main_api.query.private_ip; +import com.whoz_in.domain.shared.Nullable; import com.whoz_in.main_api.query.shared.application.Query; public record PrivateIpListGet( - String room + @Nullable String room ) implements Query {} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpListGetHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpListGetHandler.java index f80f1094..815f4484 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpListGetHandler.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpListGetHandler.java @@ -3,6 +3,7 @@ import com.whoz_in.main_api.query.shared.application.QueryHandler; import com.whoz_in.main_api.shared.application.Handler; import com.whoz_in.main_api.shared.caching.private_ip.PrivateIpStore; +import java.util.List; import lombok.RequiredArgsConstructor; @Handler @@ -11,7 +12,9 @@ public class PrivateIpListGetHandler implements QueryHandler ipList = (query.room() != null) ? + privateIpStore.getIpList(query.room()) : + privateIpStore.getIpList(); + return new PrivateIpList(ipList); } } diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpQueryController.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpQueryController.java index 164a5404..acc9643e 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpQueryController.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/private_ip/PrivateIpQueryController.java @@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @@ -18,8 +19,8 @@ public PrivateIpQueryController(QueryBus queryBus) { super(queryBus); } - @GetMapping("/private-ip/{room}") - public ResponseEntity> getPrivateIps(@PathVariable String room){ + @GetMapping("/private-ip") + public ResponseEntity> getPrivateIps(@RequestParam(required = false) String room){ return ResponseEntityGenerator.success(ask(new PrivateIpListGet(room)), CrudResponseCode.READ); } } diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/caching/private_ip/PrivateIpStore.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/caching/private_ip/PrivateIpStore.java index 6c424e72..db671775 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/caching/private_ip/PrivateIpStore.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/caching/private_ip/PrivateIpStore.java @@ -3,6 +3,8 @@ import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.whoz_in.main_api.config.RoomSsidConfig; +import java.util.Collection; +import java.util.List; import java.util.Map; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; @@ -10,15 +12,15 @@ @Component @RequiredArgsConstructor public final class PrivateIpStore { - //Cache<방, Map> - private static final Cache> store = CacheBuilder.newBuilder().build(); + //룸보단 SSID로 저장해야 할 수도 있음 (ESSID가 같다면 맥이 같을 것으로 보이기 때문) + private static final Cache> store = CacheBuilder.newBuilder().build(); //Cache<방, Map> private final RoomSsidConfig ssidConfig; public void put(String room, Map privateIps){ store.put(room, privateIps); } - public Map get(String room){ + public Map get(String room){ Map privateIps = store.getIfPresent(room); if (privateIps == null){ throw new IllegalStateException("방에 대한 내부 아이피 정보가 없음"); //main-api 서버 시작된지 얼마 안됐을 때 or 잘못된 room을 넘겼을 때 @@ -28,4 +30,16 @@ public Map get(String room){ } return privateIps; } + + public List getIpList(String room) { + return get(room).values().stream().toList(); + } + + //캐싱 + public List getIpList() { + return ssidConfig.getRooms().stream() + .map(this::getIpList) + .flatMap(Collection::stream) + .toList(); + } } From dc00d847b56388619a2bcb45a45d09bd7db41aa0 Mon Sep 17 00:00:00 2001 From: bellmin Date: Wed, 15 Jan 2025 14:46:34 +0900 Subject: [PATCH 120/138] =?UTF-8?q?refactor(api-query-jpa):=20ddlAuto=20,?= =?UTF-8?q?=20namingStrategy=20=EC=86=8D=EC=84=B1=20=EA=B0=92=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/whoz_in/api_query_jpa/config/ApiQueryJpaConfig.java | 6 +++++- .../src/main/resources/application-api-query-jpa.yml | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/config/ApiQueryJpaConfig.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/config/ApiQueryJpaConfig.java index d7163f0f..f7ae8248 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/config/ApiQueryJpaConfig.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/config/ApiQueryJpaConfig.java @@ -38,6 +38,8 @@ public static class DataSourceProperties { @Getter @Setter public static class HibernateProperties { + private String ddlAuto; + private String physicalNamingStrategy; private boolean formatSql; private boolean showSql; } @@ -80,7 +82,9 @@ public LocalContainerEntityManagerFactoryBean apiQueryJpaEntityManagerFactory( .properties( Map.of( "hibernate.show_sql", hibernateProperties.showSql, - "hibernate.format_sql", hibernateProperties.formatSql + "hibernate.format_sql", hibernateProperties.formatSql, + "hibernate.ddl.auto", hibernateProperties.ddlAuto, + "hibernate.physical_naming_strategy", hibernateProperties.physicalNamingStrategy ) ) .build(); diff --git a/modules/infrastructure/api-query-jpa/src/main/resources/application-api-query-jpa.yml b/modules/infrastructure/api-query-jpa/src/main/resources/application-api-query-jpa.yml index 9c3c98f5..f1aaeb41 100644 --- a/modules/infrastructure/api-query-jpa/src/main/resources/application-api-query-jpa.yml +++ b/modules/infrastructure/api-query-jpa/src/main/resources/application-api-query-jpa.yml @@ -11,6 +11,8 @@ api-query-jpa: hibernate: show_sql: true format_sql: true + ddl-auto: validate + physical-naming-strategy: org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy logging: level: From df0cbcb9ac1eb4f2b0df3c879ed31c942e5212fc Mon Sep 17 00:00:00 2001 From: bellmin Date: Wed, 15 Jan 2025 14:49:11 +0900 Subject: [PATCH 121/138] =?UTF-8?q?refactor(api-query-jpa):=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - activeTime -> connectedTime - inActiveTime -> disConnectedTime --- .../device/ActiveDeviceEntity.java | 27 ++++++++++--------- .../device/ActiveDeviceJpaViewer.java | 6 ++--- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java index c6240995..5613a032 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceEntity.java @@ -1,6 +1,7 @@ package com.whoz_in.api_query_jpa.device; import jakarta.persistence.Column; +import jakarta.persistence.Entity; import jakarta.persistence.Id; import java.time.Duration; import java.time.LocalDateTime; @@ -10,7 +11,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; -// TODO: JPA 적용 +@Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class ActiveDeviceEntity { @@ -19,39 +20,39 @@ public class ActiveDeviceEntity { private UUID deviceId; @Column(nullable = false) - private LocalDateTime activeTime; + private LocalDateTime connectedTime; - private LocalDateTime inactiveTime; + private LocalDateTime disConnectedTime; private Duration totalActiveTime; private boolean isActive; - private ActiveDeviceEntity(UUID deviceId, LocalDateTime activeTime) { + private ActiveDeviceEntity(UUID deviceId, LocalDateTime connectedTime) { this.deviceId = deviceId; - this.activeTime = activeTime; + this.connectedTime = connectedTime; this.isActive = true; } - public void activeOn(LocalDateTime activeTime){ + public void activeOn(LocalDateTime connectedTime){ this.isActive = true; - this.activeTime = activeTime; - this.inactiveTime = null; + this.connectedTime = connectedTime; + this.disConnectedTime = null; } - public void inActiveOn(LocalDateTime inactiveTime){ + public void inActiveOn(LocalDateTime disConnectedTime){ this.isActive = false; - this.inactiveTime = inactiveTime; + this.disConnectedTime = disConnectedTime; addTotalActiveTime(); } private void addTotalActiveTime(){ - Duration add = Duration.between(activeTime, inactiveTime).abs(); + Duration add = Duration.between(connectedTime, disConnectedTime).abs(); this.totalActiveTime = Objects.nonNull(totalActiveTime) ? totalActiveTime.plus(add) : add; } - public static ActiveDeviceEntity create(UUID deviceId, LocalDateTime activeTime){ - return new ActiveDeviceEntity(deviceId, activeTime); + public static ActiveDeviceEntity create(UUID deviceId, LocalDateTime connectedTime){ + return new ActiveDeviceEntity(deviceId, connectedTime); } } diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java index 1c446b50..4ddd72a1 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java @@ -3,9 +3,7 @@ import com.whoz_in.api_query_jpa.member.Member; import com.whoz_in.api_query_jpa.member.MemberRepository; import com.whoz_in.main_api.query.device.application.active.ActiveDevice; -import com.whoz_in.main_api.query.device.application.active.ActiveDeviceResponse; import com.whoz_in.main_api.query.device.application.active.ActiveDeviceViewer; -import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -55,8 +53,8 @@ private Optional createOptionalActiveDevice(ActiveDeviceEntity ent return Optional.of(new ActiveDevice( entity.getDeviceId(), member.getId(), - entity.getActiveTime(), - entity.getInactiveTime(), + entity.getConnectedTime(), + entity.getDisConnectedTime(), entity.getTotalActiveTime(), entity.isActive())); } From d1cf59c9cf09c007e04904b9439fe832685a049f Mon Sep 17 00:00:00 2001 From: coco3x Date: Wed, 15 Jan 2025 15:06:32 +0900 Subject: [PATCH 122/138] =?UTF-8?q?feat(main-api):=20=EC=99=80=EC=9D=B4?= =?UTF-8?q?=ED=8C=8C=EC=9D=B4=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main_api/config/RoomSsidConfig.java | 4 ++++ .../security/SecurityFilterChainConfig.java | 3 ++- .../query/ssid/SsidQueryController.java | 23 +++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/ssid/SsidQueryController.java diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/config/RoomSsidConfig.java b/modules/main-api/src/main/java/com/whoz_in/main_api/config/RoomSsidConfig.java index b6978130..96bf554d 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/config/RoomSsidConfig.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/config/RoomSsidConfig.java @@ -1,5 +1,6 @@ package com.whoz_in.main_api.config; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -15,6 +16,9 @@ public class RoomSsidConfig { public List getRooms(){ return rooms.keySet().stream().toList(); } + public List getSsids(){ + return getRooms().stream().map(this::getSsids).flatMap(Collection::stream).toList(); + } public List getSsids(String room){ List ssids = this.rooms.get(room); if (ssids == null) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java b/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java index 653be0f9..18313034 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java @@ -95,7 +95,8 @@ public SecurityFilterChain authenticationFilterChain(HttpSecurity httpSecurity) //인증 필요 auth.requestMatchers(HttpMethod.GET, "/api/v1/device/info-status", - "/api/v1/private-ip" + "/api/v1/private-ip", + "/api/v1/ssid" ).authenticated(); auth.requestMatchers(HttpMethod.POST, "/api/v1/device", diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/ssid/SsidQueryController.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/ssid/SsidQueryController.java new file mode 100644 index 00000000..ee36df63 --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/ssid/SsidQueryController.java @@ -0,0 +1,23 @@ +package com.whoz_in.main_api.query.ssid; + +import com.whoz_in.main_api.config.RoomSsidConfig; +import com.whoz_in.main_api.shared.presentation.CrudResponseCode; +import com.whoz_in.main_api.shared.presentation.ResponseEntityGenerator; +import com.whoz_in.main_api.shared.presentation.SuccessBody; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/v1") +@RequiredArgsConstructor +public class SsidQueryController{ + private final RoomSsidConfig ssidConfig; + @GetMapping("/ssid") + public ResponseEntity>> getSsidList(){ + return ResponseEntityGenerator.success(ssidConfig.getSsids(), CrudResponseCode.READ); + } +} From 3208c543e6d11a76229f8f4143be30267a133819 Mon Sep 17 00:00:00 2001 From: bellmin Date: Wed, 15 Jan 2025 15:16:12 +0900 Subject: [PATCH 123/138] =?UTF-8?q?refactor(api-query-jpa):=20ActiveDevice?= =?UTF-8?q?=20JPA=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ActiveDeviceRepository 생성 - ActiveDeviceJpaViewer JPA 적용 --- .../api_query_jpa/device/ActiveDeviceJpaViewer.java | 3 +-- .../device/ActiveDeviceRepository.java | 13 +++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceRepository.java diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java index 4ddd72a1..16ea391a 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceJpaViewer.java @@ -11,12 +11,11 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -// TODO : JPA 적용 @Component @RequiredArgsConstructor public class ActiveDeviceJpaViewer implements ActiveDeviceViewer { - private final InMemoryActiveDeviceRepository activeDeviceRepository; + private final ActiveDeviceRepository activeDeviceRepository; private final DeviceRepository deviceRepository; private final MemberRepository memberRepository; diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceRepository.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceRepository.java new file mode 100644 index 00000000..38a61c13 --- /dev/null +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/ActiveDeviceRepository.java @@ -0,0 +1,13 @@ +package com.whoz_in.api_query_jpa.device; + +import java.util.Optional; +import java.util.UUID; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ActiveDeviceRepository extends JpaRepository { + + Optional findByDeviceId(UUID deviceId); + + void deleteByDeviceId(UUID deviceId); + +} From fd6409b251b386d80bdbf9e8955743cbc75474ca Mon Sep 17 00:00:00 2001 From: bellmin Date: Wed, 15 Jan 2025 15:30:38 +0900 Subject: [PATCH 124/138] =?UTF-8?q?fix(api-query-jpa):=20api=20query=20jpa?= =?UTF-8?q?=20config=20hibernate=20=EC=98=A4=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/whoz_in/api_query_jpa/config/ApiQueryJpaConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/config/ApiQueryJpaConfig.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/config/ApiQueryJpaConfig.java index f7ae8248..20bf4955 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/config/ApiQueryJpaConfig.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/config/ApiQueryJpaConfig.java @@ -83,7 +83,7 @@ public LocalContainerEntityManagerFactoryBean apiQueryJpaEntityManagerFactory( Map.of( "hibernate.show_sql", hibernateProperties.showSql, "hibernate.format_sql", hibernateProperties.formatSql, - "hibernate.ddl.auto", hibernateProperties.ddlAuto, + "hibernate.hbm2ddl.auto", hibernateProperties.ddlAuto, "hibernate.physical_naming_strategy", hibernateProperties.physicalNamingStrategy ) ) From dbe38e163164cb44e5fbf5c5fe5c8e1b3bd45836 Mon Sep 17 00:00:00 2001 From: bellmin Date: Wed, 15 Jan 2025 15:32:53 +0900 Subject: [PATCH 125/138] =?UTF-8?q?refactor(api-query-jpa):=20JPA=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api_query_jpa/device/event/ActiveDeviceEventHandler.java | 5 ++--- .../device/event/InActiveDeviceEventHandler.java | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java index 1551b1a5..d7307a09 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/ActiveDeviceEventHandler.java @@ -1,6 +1,7 @@ package com.whoz_in.api_query_jpa.device.event; import com.whoz_in.api_query_jpa.device.ActiveDeviceEntity; +import com.whoz_in.api_query_jpa.device.ActiveDeviceRepository; import com.whoz_in.api_query_jpa.device.InMemoryActiveDeviceRepository; import com.whoz_in.main_api.query.device.application.active.event.ActiveDeviceFinded; import java.time.LocalDateTime; @@ -19,9 +20,7 @@ @Slf4j public class ActiveDeviceEventHandler { -// private final ActiveDeviceRepository activeDeviceRepository; - // TODO: JPA 적용 - private final InMemoryActiveDeviceRepository activeDeviceRepository; + private final ActiveDeviceRepository activeDeviceRepository; @Transactional(isolation = Isolation.SERIALIZABLE) @EventListener(ActiveDeviceFinded.class) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/InActiveDeviceEventHandler.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/InActiveDeviceEventHandler.java index 7e5b7f04..bde1c8ec 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/InActiveDeviceEventHandler.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/event/InActiveDeviceEventHandler.java @@ -1,6 +1,7 @@ package com.whoz_in.api_query_jpa.device.event; import com.whoz_in.api_query_jpa.device.ActiveDeviceEntity; +import com.whoz_in.api_query_jpa.device.ActiveDeviceRepository; import com.whoz_in.api_query_jpa.device.InMemoryActiveDeviceRepository; import com.whoz_in.main_api.query.device.application.active.event.InActiveDeviceFinded; import java.time.LocalDateTime; @@ -16,7 +17,7 @@ @RequiredArgsConstructor public class InActiveDeviceEventHandler { - private final InMemoryActiveDeviceRepository activeDeviceRepository; + private final ActiveDeviceRepository activeDeviceRepository; // ActiveDeviceEvent 핸들러에서 데이터를 수정할 수 있으므로 격리 수준을 serializable 로 설정 @Transactional(isolation = Isolation.SERIALIZABLE) From 9f4898c2f74967fd5c62c6243070d2685a883f72 Mon Sep 17 00:00:00 2001 From: coco3x Date: Wed, 15 Jan 2025 18:21:45 +0900 Subject: [PATCH 126/138] =?UTF-8?q?update(main-api):=20=EA=B8=B0=EA=B8=B0?= =?UTF-8?q?=20=EB=93=B1=EB=A1=9D=20api=20-=20=EB=93=B1=EB=A1=9D=20?= =?UTF-8?q?=EC=95=88=EB=90=9C=20=EC=99=80=EC=9D=B4=ED=8C=8C=EC=9D=B4?= =?UTF-8?q?=EB=A7=8C=20=EC=9A=94=EA=B5=AC=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/device/DeviceRepository.java | 5 ++ .../device/event/DeviceInfoRegistered.java | 7 ++ .../whoz_in/domain/device/model/Device.java | 21 ++++-- .../domain/device/model/DeviceInfo.java | 3 + .../device/DeviceEntityConverter.java | 3 +- .../device/DeviceEntityRepository.java | 3 + .../device/DeviceJpaRepository.java | 6 ++ .../device/application/DeviceRegister.java | 17 +++-- .../application/DeviceRegisterHandler.java | 67 +++++++++++++++++-- 9 files changed, 116 insertions(+), 16 deletions(-) create mode 100644 modules/domain/src/main/java/com/whoz_in/domain/device/event/DeviceInfoRegistered.java diff --git a/modules/domain/src/main/java/com/whoz_in/domain/device/DeviceRepository.java b/modules/domain/src/main/java/com/whoz_in/domain/device/DeviceRepository.java index 69b5f2ea..97061c09 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/device/DeviceRepository.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/device/DeviceRepository.java @@ -1,6 +1,7 @@ package com.whoz_in.domain.device; import com.whoz_in.domain.device.model.Device; +import com.whoz_in.domain.device.model.DeviceId; import java.util.Optional; public interface DeviceRepository { @@ -8,4 +9,8 @@ public interface DeviceRepository { //해당 mac을 포함하는 device를 찾는 메서드 Optional findByMac(String mac); + Optional findByDeviceId(DeviceId deviceId); + default Device getByDeviceId(DeviceId deviceId){ + return findByDeviceId(deviceId).orElseThrow(()->new IllegalArgumentException("device가 없음")); + } } diff --git a/modules/domain/src/main/java/com/whoz_in/domain/device/event/DeviceInfoRegistered.java b/modules/domain/src/main/java/com/whoz_in/domain/device/event/DeviceInfoRegistered.java new file mode 100644 index 00000000..ef53c7fb --- /dev/null +++ b/modules/domain/src/main/java/com/whoz_in/domain/device/event/DeviceInfoRegistered.java @@ -0,0 +1,7 @@ +package com.whoz_in.domain.device.event; + +import com.whoz_in.domain.shared.event.DomainEvent; + +public final class DeviceInfoRegistered extends DomainEvent { + +} diff --git a/modules/domain/src/main/java/com/whoz_in/domain/device/model/Device.java b/modules/domain/src/main/java/com/whoz_in/domain/device/model/Device.java index e350f70a..d08798e5 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/device/model/Device.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/device/model/Device.java @@ -1,9 +1,11 @@ package com.whoz_in.domain.device.model; import com.whoz_in.domain.device.event.DeviceCreated; +import com.whoz_in.domain.device.event.DeviceInfoRegistered; import com.whoz_in.domain.member.model.MemberId; import com.whoz_in.domain.shared.AggregateRoot; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import java.util.UUID; import lombok.AccessLevel; import lombok.AllArgsConstructor; @@ -17,13 +19,22 @@ public final class Device extends AggregateRoot { private final DeviceId id; private final MemberId memberId; //양도 기능 생기면 final 제거 private String deviceName; - private final List deviceInfos; + private final Set deviceInfos; public boolean isOwnedBy(MemberId memberId){ return this.getMemberId().equals(memberId); } - public static Device create(MemberId memberId, List deviceInfos, String deviceName){ + public void registerDeviceInfo(DeviceInfo deviceInfo){ + this.deviceInfos.add(deviceInfo); + this.register(new DeviceInfoRegistered()); + } + + public void registerDeviceInfo(Set deviceInfos){ + deviceInfos.forEach(this::registerDeviceInfo); + } + + public static Device create(MemberId memberId, Set deviceInfos, String deviceName){ Device device = Device.builder() .id(new DeviceId(UUID.randomUUID())) .memberId(memberId) @@ -34,11 +45,11 @@ public static Device create(MemberId memberId, List deviceInfos, Str return device; } - public static Device load(DeviceId id, MemberId memberId, List deviceInfos, String deviceName){ + public static Device load(DeviceId id, MemberId memberId, Set deviceInfos, String deviceName){ return Device.builder() .id(id) .memberId(memberId) - .deviceInfos(deviceInfos) + .deviceInfos(new HashSet<>(deviceInfos)) .deviceName(deviceName) .build(); } diff --git a/modules/domain/src/main/java/com/whoz_in/domain/device/model/DeviceInfo.java b/modules/domain/src/main/java/com/whoz_in/domain/device/model/DeviceInfo.java index 89fe379a..91777054 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/device/model/DeviceInfo.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/device/model/DeviceInfo.java @@ -2,14 +2,17 @@ import lombok.AccessLevel; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.RequiredArgsConstructor; @Getter +@EqualsAndHashCode @RequiredArgsConstructor(access = AccessLevel.PRIVATE) public final class DeviceInfo { private final String room; private final String ssid; + @EqualsAndHashCode.Exclude private final MacAddress mac; public static DeviceInfo create(String room, String ssid, MacAddress mac){ diff --git a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceEntityConverter.java b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceEntityConverter.java index 75417433..beecf835 100644 --- a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceEntityConverter.java +++ b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceEntityConverter.java @@ -6,6 +6,7 @@ import com.whoz_in.domain.member.model.MemberId; import com.whoz_in.domain_jpa.shared.BaseConverter; import java.util.List; +import java.util.stream.Collectors; import org.springframework.stereotype.Component; @Component @@ -32,7 +33,7 @@ public Device to(DeviceEntity entity) { deviceInfoEntity.getRoom(), deviceInfoEntity.getSsid(), deviceInfoEntity.getMac())) - .toList(), + .collect(Collectors.toSet()), entity.getName() ); } diff --git a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceEntityRepository.java b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceEntityRepository.java index 04fff59a..8af73852 100644 --- a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceEntityRepository.java +++ b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceEntityRepository.java @@ -1,6 +1,7 @@ package com.whoz_in.domain_jpa.device; import java.util.Optional; +import java.util.UUID; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -10,4 +11,6 @@ public interface DeviceEntityRepository extends JpaRepository { @Query("SELECT d FROM DeviceEntity d JOIN d.deviceInfoEntity di WHERE di.mac = :mac") Optional findByMac(@Param("mac") String mac); + + Optional findById(UUID memberId); } \ No newline at end of file diff --git a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceJpaRepository.java b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceJpaRepository.java index e94e2d04..f7026447 100644 --- a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceJpaRepository.java +++ b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceJpaRepository.java @@ -2,6 +2,7 @@ import com.whoz_in.domain.device.DeviceRepository; import com.whoz_in.domain.device.model.Device; +import com.whoz_in.domain.device.model.DeviceId; import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; @@ -20,4 +21,9 @@ public void save(Device device) { public Optional findByMac(String mac) { return repository.findByMac(mac).map(converter::to); } + + @Override + public Optional findByDeviceId(DeviceId deviceId) { + return repository.findById(deviceId.id()).map(converter::to); + } } diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceRegister.java b/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceRegister.java index 065d5d16..627efd90 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceRegister.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceRegister.java @@ -1,14 +1,23 @@ package com.whoz_in.main_api.command.device.application; +import com.whoz_in.domain.device.model.DeviceId; +import com.whoz_in.domain.shared.Nullable; import com.whoz_in.main_api.command.shared.application.Command; +import java.util.Optional; +import java.util.UUID; +//사용자가 와이파이마다 맥을 모두 추가했을 경우 그 맥들을 저장한다. (DeviceInfo) public record DeviceRegister( - String room, - String deviceName + @Nullable UUID deviceId, //이전에 등록된 기기인 경우 - Device를 불러옴 + @Nullable String deviceName //새로 등록하는 경우 - 기기 이름이 필요함 ) implements Command { public DeviceRegister { - if (deviceName == null || deviceName.isBlank()) - throw new IllegalArgumentException("기기 이름이 비어있음"); + if ((deviceId == null) == (deviceName == null)) + throw new IllegalArgumentException("device id, device name 중 하나를 보내야 함"); + } + + public Optional getDeviceId(){ + return Optional.ofNullable(deviceId).map(DeviceId::new); } } diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceRegisterHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceRegisterHandler.java index 8843af23..11be398c 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceRegisterHandler.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceRegisterHandler.java @@ -8,17 +8,24 @@ import com.whoz_in.domain.member.service.MemberFinderService; import com.whoz_in.domain.shared.event.EventBus; import com.whoz_in.main_api.command.shared.application.CommandHandler; +import com.whoz_in.main_api.config.RoomSsidConfig; import com.whoz_in.main_api.shared.application.Handler; +import com.whoz_in.main_api.shared.caching.device.TempDeviceInfo; import com.whoz_in.main_api.shared.caching.device.TempDeviceInfoStore; import com.whoz_in.main_api.shared.utils.RequesterInfo; import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.springframework.transaction.annotation.Transactional; + @Handler @RequiredArgsConstructor public class DeviceRegisterHandler implements CommandHandler { private final RequesterInfo requesterInfo; + private final RoomSsidConfig ssidConfig; private final TempDeviceInfoStore tempDeviceInfoStore; private final MemberFinderService memberFinderService; private final DeviceRepository deviceRepository; @@ -28,19 +35,67 @@ public class DeviceRegisterHandler implements CommandHandler optionalDevice = cmd.getDeviceId().map(deviceRepository::getByDeviceId); - List deviceInfos = tempDeviceInfoStore.takeout(requesterId.id()) - .stream() - .map(tempDI-> DeviceInfo.create(tempDI.getRoom(), tempDI.getSsid(), MacAddress.create(tempDI.getMac()))) - .toList(); + // 등록된 Device가 있으면 등록된 SSID를 가져오고 없으면 빈 리스트 반환 + List registeredSsids = optionalDevice.map(this::getRegisteredSsids).orElseGet(List::of); + // 모든 와이파이에 대해 이미 등록되어있으면 리턴 + if (registeredSsids.equals(ssidConfig.getSsids())) return null; + // TempDeviceInfo에 등록된 SSID 가져오기 + List addedSsids = getTempDeviceInfoSsids(requesterId); + // 추가되지 않은 SSID는 없어야 함 + validateAllSsidsAdded(registeredSsids, addedSsids); + + // TempDeviceInfo로부터 DeviceInfo 생성 + Set deviceInfos = createDeviceInfos(requesterId); + + // Device를 생성 후 저장 (기존 Device가 없을 때만) + Device device = optionalDevice + .map(d->{ + d.registerDeviceInfo(deviceInfos);return d; + }) + .orElseGet(() -> Device.create(requesterId, deviceInfos, cmd.deviceName())); - Device device = Device.create(requesterId, deviceInfos, cmd.deviceName()); deviceRepository.save(device); eventBus.publish(device.pullDomainEvents()); return null; } + + private List getRegisteredSsids(Device device){ + return device.getDeviceInfos() + .stream() + .map(DeviceInfo::getSsid) + .toList(); + } + + private List getTempDeviceInfoSsids(MemberId requesterId) { + return tempDeviceInfoStore.get(requesterId.id()) + .stream() + .map(TempDeviceInfo::getSsid) + .toList(); + } + + private void validateAllSsidsAdded(List registeredSsids, List addedSsids) { + List notAddedSsids = ssidConfig.getSsids().stream() + .filter(ssid -> !registeredSsids.contains(ssid)) + .filter(ssid -> !addedSsids.contains(ssid)) + .toList(); + + if (!notAddedSsids.isEmpty()) { + throw new IllegalArgumentException("등록하지 않은 SSID: " + notAddedSsids); + } + } + + private Set createDeviceInfos(MemberId requesterId) { + return tempDeviceInfoStore.takeout(requesterId.id()) + .stream() + .map(tempDI -> DeviceInfo.create(tempDI.getRoom(), tempDI.getSsid(), MacAddress.create(tempDI.getMac()))) + .collect(Collectors.toSet()); + } } From 724ddd4d74703507da7ebf3f97e071c7f9f9e074 Mon Sep 17 00:00:00 2001 From: bellmin Date: Wed, 15 Jan 2025 23:01:52 +0900 Subject: [PATCH 127/138] =?UTF-8?q?feat(github):=20chat=20gpt=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=EB=A6=AC=EB=B7=B0=20=EC=8A=A4=ED=81=AC=EB=A6=BD?= =?UTF-8?q?=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/chat-gpt-code-review.yml | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/workflows/chat-gpt-code-review.yml diff --git a/.github/workflows/chat-gpt-code-review.yml b/.github/workflows/chat-gpt-code-review.yml new file mode 100644 index 00000000..073ac867 --- /dev/null +++ b/.github/workflows/chat-gpt-code-review.yml @@ -0,0 +1,24 @@ +name: Code Review + +permissions: + content: read + pull-requests: write + +# Pull Request ? ?? ? ?? +# Pull Request ? ??? ??? ???? ??? ? ? +on: + pull_request: + types: + - opened + - synchronize + +jobs: + code-review: + runs-on: ubuntu-latest + steps: + - uses: anc95/Chat-GPT-CodeReview@main + env: + GITHUB_TOKEN : ${{secrets.GITHUB_TOKEN}} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + LANGUAGE: Korean + MODEL: gpt-4 From 4cd1f409845fccf52630836e983df28e5394db67 Mon Sep 17 00:00:00 2001 From: bellmin Date: Wed, 15 Jan 2025 23:06:14 +0900 Subject: [PATCH 128/138] =?UTF-8?q?refactor(github):=20secrets=20=ED=86=A0?= =?UTF-8?q?=ED=81=B0=20=EC=9D=B4=EB=A6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/chat-gpt-code-review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/chat-gpt-code-review.yml b/.github/workflows/chat-gpt-code-review.yml index 073ac867..8b8fcc32 100644 --- a/.github/workflows/chat-gpt-code-review.yml +++ b/.github/workflows/chat-gpt-code-review.yml @@ -18,7 +18,7 @@ jobs: steps: - uses: anc95/Chat-GPT-CodeReview@main env: - GITHUB_TOKEN : ${{secrets.GITHUB_TOKEN}} + GITHUB_TOKEN : ${{secrets.BELLMIN_GITHUB_TOKEN}} OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} LANGUAGE: Korean MODEL: gpt-4 From 08f9b4008566be7f5ac00c6861ed67c825da6332 Mon Sep 17 00:00:00 2001 From: bellmin Date: Wed, 15 Jan 2025 23:09:05 +0900 Subject: [PATCH 129/138] =?UTF-8?q?refactor(github):=20=EC=98=A4=ED=83=80?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/chat-gpt-code-review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/chat-gpt-code-review.yml b/.github/workflows/chat-gpt-code-review.yml index 8b8fcc32..946da6c0 100644 --- a/.github/workflows/chat-gpt-code-review.yml +++ b/.github/workflows/chat-gpt-code-review.yml @@ -1,7 +1,7 @@ name: Code Review permissions: - content: read + contents: read pull-requests: write # Pull Request ? ?? ? ?? From 07d2b72c6e8fee4028d2af6b7c38cccf31757e68 Mon Sep 17 00:00:00 2001 From: bellmin Date: Wed, 15 Jan 2025 23:11:28 +0900 Subject: [PATCH 130/138] =?UTF-8?q?refactor(github):=20github=20repository?= =?UTF-8?q?=20=EC=98=A4=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/chat-gpt-code-review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/chat-gpt-code-review.yml b/.github/workflows/chat-gpt-code-review.yml index 946da6c0..518b7959 100644 --- a/.github/workflows/chat-gpt-code-review.yml +++ b/.github/workflows/chat-gpt-code-review.yml @@ -16,7 +16,7 @@ jobs: code-review: runs-on: ubuntu-latest steps: - - uses: anc95/Chat-GPT-CodeReview@main + - uses: anc95/ChatGPT-CodeReview@main env: GITHUB_TOKEN : ${{secrets.BELLMIN_GITHUB_TOKEN}} OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} From 4d151a7b32f9dec4b52ae479b812c1157ce8d13b Mon Sep 17 00:00:00 2001 From: bellmin Date: Wed, 15 Jan 2025 23:20:09 +0900 Subject: [PATCH 131/138] =?UTF-8?q?chore(github):=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=EC=9A=A9=20=EC=BB=A4=EB=B0=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From dccef6f5db704d18deaea11bdefde435512c6cd2 Mon Sep 17 00:00:00 2001 From: bellmin Date: Wed, 15 Jan 2025 23:30:17 +0900 Subject: [PATCH 132/138] =?UTF-8?q?fix(api-query-jpa):=20=EC=84=B8?= =?UTF-8?q?=EB=AF=B8=EC=BD=9C=EB=A1=A0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/whoz_in/api_query_jpa/device/Device.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/Device.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/Device.java index 5631e843..850afa2f 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/Device.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/Device.java @@ -4,7 +4,7 @@ import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.FetchType; -import jakarta.persistence.JoinColumn +import jakarta.persistence.JoinColumn; import jakarta.persistence.OneToMany; import java.util.List; import java.util.UUID; From 58110b24c9cfc8a77c4dcdf2112d20cc80942892 Mon Sep 17 00:00:00 2001 From: bellmin Date: Thu, 16 Jan 2025 11:37:04 +0900 Subject: [PATCH 133/138] =?UTF-8?q?refactor(github):=20=EB=AA=A8=EB=8D=B8?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20max=20=ED=86=A0?= =?UTF-8?q?=ED=81=B0=20=EA=B0=92=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/chat-gpt-code-review.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/chat-gpt-code-review.yml b/.github/workflows/chat-gpt-code-review.yml index 518b7959..7b84866c 100644 --- a/.github/workflows/chat-gpt-code-review.yml +++ b/.github/workflows/chat-gpt-code-review.yml @@ -21,4 +21,5 @@ jobs: GITHUB_TOKEN : ${{secrets.BELLMIN_GITHUB_TOKEN}} OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} LANGUAGE: Korean - MODEL: gpt-4 + MODEL: gpt-3.5-turbo + max_tokens: 10000 From f459e7bd55f6b0b6c82e7c94bbcb47d75d9bfda6 Mon Sep 17 00:00:00 2001 From: bellmin Date: Thu, 16 Jan 2025 18:32:50 +0900 Subject: [PATCH 134/138] =?UTF-8?q?refactor(github):=20token=20=EA=B0=92?= =?UTF-8?q?=20=EC=84=A4=EC=A0=95=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/chat-gpt-code-review.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/chat-gpt-code-review.yml b/.github/workflows/chat-gpt-code-review.yml index 7b84866c..85d79417 100644 --- a/.github/workflows/chat-gpt-code-review.yml +++ b/.github/workflows/chat-gpt-code-review.yml @@ -22,4 +22,3 @@ jobs: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} LANGUAGE: Korean MODEL: gpt-3.5-turbo - max_tokens: 10000 From 4269f9c580c2abc32882cb1a3b4d82c95e9fe72d Mon Sep 17 00:00:00 2001 From: coco3x Date: Fri, 17 Jan 2025 03:31:12 +0900 Subject: [PATCH 135/138] =?UTF-8?q?feat(main-api):=20application=20?= =?UTF-8?q?=EA=B3=84=EC=B8=B5=20=EC=98=88=EC=99=B8=20=EC=A0=95=EC=9D=98=20?= =?UTF-8?q?=EB=B0=8F=20=EA=B8=B0=EC=A1=B4=20=EC=98=88=EC=99=B8=20=ED=95=B8?= =?UTF-8?q?=EB=93=A4=EB=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/ApplicationException.java | 13 +++++++++ .../MainApiGlobalExceptionHandler.java | 29 ++++++++++++------- 2 files changed, 31 insertions(+), 11 deletions(-) create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/shared/application/ApplicationException.java diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/application/ApplicationException.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/application/ApplicationException.java new file mode 100644 index 00000000..ece14e01 --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/application/ApplicationException.java @@ -0,0 +1,13 @@ +package com.whoz_in.main_api.shared.application; + +import lombok.Getter; + +@Getter +public abstract class ApplicationException extends RuntimeException{ + private final String errorCode; + + protected ApplicationException(String errorCode, String errorMessage) { + super(errorMessage); + this.errorCode = errorCode; + } +} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/presentation/MainApiGlobalExceptionHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/presentation/MainApiGlobalExceptionHandler.java index 7cf73455..94ca3ef9 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/presentation/MainApiGlobalExceptionHandler.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/presentation/MainApiGlobalExceptionHandler.java @@ -1,22 +1,30 @@ package com.whoz_in.main_api.shared.presentation; +import com.whoz_in.domain.shared.BusinessException; +import com.whoz_in.main_api.shared.application.ApplicationException; +import jakarta.servlet.http.HttpServletRequest; +import java.util.Objects; +import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; -@ControllerAdvice +@RestControllerAdvice +@RequiredArgsConstructor public class MainApiGlobalExceptionHandler { - // 사용자 예외 - @ExceptionHandler(IllegalArgumentException.class) - public ResponseEntity handleIllegalArgumentException(IllegalArgumentException e) { - return ResponseEntityGenerator.fail("USER_ERROR", e.getMessage(), HttpStatus.BAD_REQUEST); + //TODO: mapper + @ExceptionHandler(ApplicationException.class) + public ResponseEntity handle(ApplicationException e, HttpServletRequest request) { + return ResponseEntityGenerator.fail(e.getErrorCode(), e.getMessage(), HttpStatus.BAD_REQUEST); } - // 개발자 예외 - @ExceptionHandler(IllegalStateException.class) - public ResponseEntity handleIllegalStateException(IllegalStateException e) { - return ResponseEntityGenerator.fail("SYSTEM_ERROR", e.getMessage(), HttpStatus.BAD_REQUEST); + //TODO: ApplicationException과 합쳐야 할듯 + @ExceptionHandler(BusinessException.class) + public ResponseEntity handle(BusinessException e) { + return ResponseEntityGenerator.fail(e.getErrorCode(), e.getMessage(), HttpStatus.BAD_REQUEST); } // 나머지 예외 @@ -24,5 +32,4 @@ public ResponseEntity handleIllegalStateException(IllegalStateExcep public ResponseEntity handleException(Exception e) { return ResponseEntityGenerator.fail("UNEXPECTED_ERROR", e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); } - } From 7f6aeab592ab74bfcc41458930bb15f3993a8f46 Mon Sep 17 00:00:00 2001 From: coco3x Date: Fri, 17 Jan 2025 03:39:37 +0900 Subject: [PATCH 136/138] =?UTF-8?q?update:=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20/=20=EA=B8=B0=EA=B8=B0=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=20api=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/device/DeviceRepository.java | 3 -- .../DeviceAlreadyRegisteredException.java | 10 ++++++ .../InvalidDeviceOwnerException.java | 13 ++++++++ .../InvalidIPv4AddressException.java | 3 +- .../exception/InvalidMacAddressException.java | 3 +- .../device/exception/NoDeviceException.java | 10 ++++++ .../domain/device/model/IpAddress.java | 2 +- .../domain/device/model/MacAddress.java | 2 +- .../device/service/DeviceFinderService.java | 30 +++++++++++++++++ .../service/DeviceOwnershipService.java | 12 ++++--- .../domain/member/MemberRepository.java | 13 +------- .../InvalidAuthCredentialsException.java | 4 +-- .../LoginIdPolicyViolationException.java | 4 +-- .../member/exception/NoMemberException.java | 4 +-- .../exception/NotAuthMemberException.java | 3 +- .../exception/NotOAuthMemberException.java | 4 +-- .../PasswordPolicyViolationException.java | 4 +-- .../exception/WrongPasswordException.java | 4 +-- .../domain/member/model/AuthCredentials.java | 8 ++--- .../whoz_in/domain/member/model/Member.java | 2 +- .../member/service/MemberFinderService.java | 8 ++++- .../application/DeviceInfoAddHandler.java | 32 +++++++------------ .../application/DeviceRegisterHandler.java | 23 +++++++------ .../device/presentation/DeviceController.java | 5 ++- .../caching/device/TempDeviceInfoStore.java | 20 ++---------- 25 files changed, 133 insertions(+), 93 deletions(-) create mode 100644 modules/domain/src/main/java/com/whoz_in/domain/device/exception/DeviceAlreadyRegisteredException.java create mode 100644 modules/domain/src/main/java/com/whoz_in/domain/device/exception/InvalidDeviceOwnerException.java create mode 100644 modules/domain/src/main/java/com/whoz_in/domain/device/exception/NoDeviceException.java create mode 100644 modules/domain/src/main/java/com/whoz_in/domain/device/service/DeviceFinderService.java diff --git a/modules/domain/src/main/java/com/whoz_in/domain/device/DeviceRepository.java b/modules/domain/src/main/java/com/whoz_in/domain/device/DeviceRepository.java index 97061c09..a867c760 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/device/DeviceRepository.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/device/DeviceRepository.java @@ -10,7 +10,4 @@ public interface DeviceRepository { //해당 mac을 포함하는 device를 찾는 메서드 Optional findByMac(String mac); Optional findByDeviceId(DeviceId deviceId); - default Device getByDeviceId(DeviceId deviceId){ - return findByDeviceId(deviceId).orElseThrow(()->new IllegalArgumentException("device가 없음")); - } } diff --git a/modules/domain/src/main/java/com/whoz_in/domain/device/exception/DeviceAlreadyRegisteredException.java b/modules/domain/src/main/java/com/whoz_in/domain/device/exception/DeviceAlreadyRegisteredException.java new file mode 100644 index 00000000..923ac57c --- /dev/null +++ b/modules/domain/src/main/java/com/whoz_in/domain/device/exception/DeviceAlreadyRegisteredException.java @@ -0,0 +1,10 @@ +package com.whoz_in.domain.device.exception; + +import com.whoz_in.domain.shared.BusinessException; + +public class DeviceAlreadyRegisteredException extends BusinessException { + public static final DeviceAlreadyRegisteredException EXCEPTION = new DeviceAlreadyRegisteredException(); + private DeviceAlreadyRegisteredException() { + super("3030", "이미 등록된 기기입니다."); + } +} diff --git a/modules/domain/src/main/java/com/whoz_in/domain/device/exception/InvalidDeviceOwnerException.java b/modules/domain/src/main/java/com/whoz_in/domain/device/exception/InvalidDeviceOwnerException.java new file mode 100644 index 00000000..42fefb44 --- /dev/null +++ b/modules/domain/src/main/java/com/whoz_in/domain/device/exception/InvalidDeviceOwnerException.java @@ -0,0 +1,13 @@ +package com.whoz_in.domain.device.exception; + +import com.whoz_in.domain.shared.BusinessException; + +public class InvalidDeviceOwnerException extends BusinessException { + private InvalidDeviceOwnerException(String errorMessage) { + super("3020", errorMessage); + } + + public static InvalidDeviceOwnerException of(String ownerName){ + return new InvalidDeviceOwnerException(String.format("이 기기는 %s 회원의 기기입니다. 해당 회원에게 기기 삭제를 부탁하세요.", ownerName)); + } +} diff --git a/modules/domain/src/main/java/com/whoz_in/domain/device/exception/InvalidIPv4AddressException.java b/modules/domain/src/main/java/com/whoz_in/domain/device/exception/InvalidIPv4AddressException.java index b9af4b51..0ff12454 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/device/exception/InvalidIPv4AddressException.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/device/exception/InvalidIPv4AddressException.java @@ -3,7 +3,8 @@ import com.whoz_in.domain.shared.BusinessException; public class InvalidIPv4AddressException extends BusinessException { - public InvalidIPv4AddressException() { + public static final InvalidIPv4AddressException EXCEPTION = new InvalidIPv4AddressException(); + private InvalidIPv4AddressException() { super("3006", "유효하지 않은 IPv4 주소입니다."); } } diff --git a/modules/domain/src/main/java/com/whoz_in/domain/device/exception/InvalidMacAddressException.java b/modules/domain/src/main/java/com/whoz_in/domain/device/exception/InvalidMacAddressException.java index 1d9c92ca..c8aa8539 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/device/exception/InvalidMacAddressException.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/device/exception/InvalidMacAddressException.java @@ -3,7 +3,8 @@ import com.whoz_in.domain.shared.BusinessException; public class InvalidMacAddressException extends BusinessException { - public InvalidMacAddressException() { + public static final InvalidMacAddressException EXCEPTION = new InvalidMacAddressException(); + private InvalidMacAddressException() { super("3005", "유효하지 않은 Mac 주소입니다."); } } diff --git a/modules/domain/src/main/java/com/whoz_in/domain/device/exception/NoDeviceException.java b/modules/domain/src/main/java/com/whoz_in/domain/device/exception/NoDeviceException.java new file mode 100644 index 00000000..3cff5b30 --- /dev/null +++ b/modules/domain/src/main/java/com/whoz_in/domain/device/exception/NoDeviceException.java @@ -0,0 +1,10 @@ +package com.whoz_in.domain.device.exception; + +import com.whoz_in.domain.shared.BusinessException; + +public class NoDeviceException extends BusinessException { + public static final NoDeviceException EXCEPTION = new NoDeviceException(); + private NoDeviceException() { + super("3001", "등록된 기기가 없습니다."); + } +} diff --git a/modules/domain/src/main/java/com/whoz_in/domain/device/model/IpAddress.java b/modules/domain/src/main/java/com/whoz_in/domain/device/model/IpAddress.java index cb8a90c9..851a4926 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/device/model/IpAddress.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/device/model/IpAddress.java @@ -20,7 +20,7 @@ public final class IpAddress { public static IpAddress create(String address){ if (!isValid(address)) { - throw new InvalidIPv4AddressException(); + throw InvalidIPv4AddressException.EXCEPTION; } return new IpAddress(address); } diff --git a/modules/domain/src/main/java/com/whoz_in/domain/device/model/MacAddress.java b/modules/domain/src/main/java/com/whoz_in/domain/device/model/MacAddress.java index c4b0787e..6d0d4baf 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/device/model/MacAddress.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/device/model/MacAddress.java @@ -18,7 +18,7 @@ public final class MacAddress { public static MacAddress create(String address){ if (!isValid(address)) { - throw new InvalidMacAddressException(); + throw InvalidMacAddressException.EXCEPTION; } return new MacAddress(normalize(address)); } diff --git a/modules/domain/src/main/java/com/whoz_in/domain/device/service/DeviceFinderService.java b/modules/domain/src/main/java/com/whoz_in/domain/device/service/DeviceFinderService.java new file mode 100644 index 00000000..a12dbcc9 --- /dev/null +++ b/modules/domain/src/main/java/com/whoz_in/domain/device/service/DeviceFinderService.java @@ -0,0 +1,30 @@ +package com.whoz_in.domain.device.service; + +import com.whoz_in.domain.device.DeviceRepository; +import com.whoz_in.domain.device.exception.DeviceAlreadyRegisteredException; +import com.whoz_in.domain.device.exception.NoDeviceException; +import com.whoz_in.domain.device.model.Device; +import com.whoz_in.domain.device.model.DeviceId; +import com.whoz_in.domain.shared.DomainService; +import lombok.RequiredArgsConstructor; + +@DomainService +@RequiredArgsConstructor +public class DeviceFinderService { + private final DeviceRepository deviceRepository; + + public Device find(DeviceId deviceId){ + return deviceRepository.findByDeviceId(deviceId).orElseThrow(()-> NoDeviceException.EXCEPTION); + } + + public void mustNotExist(DeviceId deviceId){ + if (deviceRepository.findByDeviceId(deviceId).isPresent()) + throw DeviceAlreadyRegisteredException.EXCEPTION; + } + + public void mustNotExistByMac(String mac){ + if (deviceRepository.findByMac(mac).isPresent()) + throw DeviceAlreadyRegisteredException.EXCEPTION; + } + +} diff --git a/modules/domain/src/main/java/com/whoz_in/domain/device/service/DeviceOwnershipService.java b/modules/domain/src/main/java/com/whoz_in/domain/device/service/DeviceOwnershipService.java index 691f7298..6909837a 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/device/service/DeviceOwnershipService.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/device/service/DeviceOwnershipService.java @@ -1,20 +1,22 @@ package com.whoz_in.domain.device.service; +import com.whoz_in.domain.device.exception.InvalidDeviceOwnerException; import com.whoz_in.domain.device.model.Device; -import com.whoz_in.domain.member.MemberRepository; import com.whoz_in.domain.member.model.Member; import com.whoz_in.domain.member.model.MemberId; +import com.whoz_in.domain.member.service.MemberFinderService; import com.whoz_in.domain.shared.DomainService; import lombok.RequiredArgsConstructor; @DomainService @RequiredArgsConstructor public class DeviceOwnershipService { - private final MemberRepository memberRepository; + private final MemberFinderService memberFinderService; - public void validateOwnership(Device device, MemberId memberId){ + //기기가 자신의 것이 맞는지 확인합니다. + public void validateIsMine(Device device, MemberId memberId){ if (device.isOwnedBy(memberId)) return; - Member deviceOwner = memberRepository.getByMemberId(device.getMemberId()); - throw new IllegalArgumentException("이 기기는 " + deviceOwner.getName() + " 회원의 기기입니다."); + Member deviceOwner = memberFinderService.find(device.getMemberId()); + throw InvalidDeviceOwnerException.of(deviceOwner.getName()); } } diff --git a/modules/domain/src/main/java/com/whoz_in/domain/member/MemberRepository.java b/modules/domain/src/main/java/com/whoz_in/domain/member/MemberRepository.java index a026d232..01930e57 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/member/MemberRepository.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/member/MemberRepository.java @@ -14,18 +14,7 @@ public interface MemberRepository { Optional findByMemberId(MemberId id); List findByName(String name); Optional findBySocialId(String socialId); - default Member getByLoginId(String loginId){ - return findByLoginId(loginId).orElseThrow(NoMemberException::new); - } - default List getByName(String name){ - List members = findByName(name); - if(members.isEmpty()) throw new NoMemberException(); - return members; - } - default Member getByMemberId(MemberId id){ - return findByMemberId(id).orElseThrow(NoMemberException::new); - } default Member getBySocialId(String socialId){ - return findBySocialId(socialId).orElseThrow(NoMemberException::new); + return findBySocialId(socialId).orElseThrow(()->NoMemberException.EXCEPTION); } } diff --git a/modules/domain/src/main/java/com/whoz_in/domain/member/exception/InvalidAuthCredentialsException.java b/modules/domain/src/main/java/com/whoz_in/domain/member/exception/InvalidAuthCredentialsException.java index 8b3f1f53..793b4508 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/member/exception/InvalidAuthCredentialsException.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/member/exception/InvalidAuthCredentialsException.java @@ -3,8 +3,8 @@ import com.whoz_in.domain.shared.BusinessException; public class InvalidAuthCredentialsException extends BusinessException { - - public InvalidAuthCredentialsException() { + public static final InvalidAuthCredentialsException EXCEPTION = new InvalidAuthCredentialsException(); + private InvalidAuthCredentialsException() { super("2003", "아이디 혹은 비밀번호가 틀렸습니다."); } } diff --git a/modules/domain/src/main/java/com/whoz_in/domain/member/exception/LoginIdPolicyViolationException.java b/modules/domain/src/main/java/com/whoz_in/domain/member/exception/LoginIdPolicyViolationException.java index a74f7a93..a2cf0f0b 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/member/exception/LoginIdPolicyViolationException.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/member/exception/LoginIdPolicyViolationException.java @@ -3,8 +3,8 @@ import com.whoz_in.domain.shared.BusinessException; public class LoginIdPolicyViolationException extends BusinessException { - - public LoginIdPolicyViolationException() { + public static final LoginIdPolicyViolationException EXCEPTION = new LoginIdPolicyViolationException(); + private LoginIdPolicyViolationException() { super("2001", "아이디는 알파벳 소문자, 숫자로 6자리 이상 16자리 이하여야 합니다."); } } diff --git a/modules/domain/src/main/java/com/whoz_in/domain/member/exception/NoMemberException.java b/modules/domain/src/main/java/com/whoz_in/domain/member/exception/NoMemberException.java index 087e9e86..032b9af0 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/member/exception/NoMemberException.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/member/exception/NoMemberException.java @@ -3,8 +3,8 @@ import com.whoz_in.domain.shared.BusinessException; public class NoMemberException extends BusinessException { - - public NoMemberException() { + public static final NoMemberException EXCEPTION = new NoMemberException(); + private NoMemberException() { super("2008", "존재하지 않는 멤버입니다."); } } diff --git a/modules/domain/src/main/java/com/whoz_in/domain/member/exception/NotAuthMemberException.java b/modules/domain/src/main/java/com/whoz_in/domain/member/exception/NotAuthMemberException.java index b68d7749..95818a36 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/member/exception/NotAuthMemberException.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/member/exception/NotAuthMemberException.java @@ -3,7 +3,8 @@ import com.whoz_in.domain.shared.BusinessException; public class NotAuthMemberException extends BusinessException { - public NotAuthMemberException() { + public static final NotAuthMemberException EXCEPTION = new NotAuthMemberException(); + private NotAuthMemberException() { super("2006", "일반 로그인 정보가 없는 회원입니다."); } } diff --git a/modules/domain/src/main/java/com/whoz_in/domain/member/exception/NotOAuthMemberException.java b/modules/domain/src/main/java/com/whoz_in/domain/member/exception/NotOAuthMemberException.java index 7ae1af21..bd43d706 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/member/exception/NotOAuthMemberException.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/member/exception/NotOAuthMemberException.java @@ -3,8 +3,8 @@ import com.whoz_in.domain.shared.BusinessException; public class NotOAuthMemberException extends BusinessException { - - public NotOAuthMemberException() { + public static final NotOAuthMemberException EXCEPTION = new NotOAuthMemberException(); + private NotOAuthMemberException() { super("2007", "소셜 로그인 정보가 없는 회원입니다."); } } diff --git a/modules/domain/src/main/java/com/whoz_in/domain/member/exception/PasswordPolicyViolationException.java b/modules/domain/src/main/java/com/whoz_in/domain/member/exception/PasswordPolicyViolationException.java index 60253229..c403a16f 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/member/exception/PasswordPolicyViolationException.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/member/exception/PasswordPolicyViolationException.java @@ -3,8 +3,8 @@ import com.whoz_in.domain.shared.BusinessException; public class PasswordPolicyViolationException extends BusinessException { - - public PasswordPolicyViolationException() { + public static final PasswordPolicyViolationException EXCEPTION = new PasswordPolicyViolationException(); + private PasswordPolicyViolationException() { super("2002", "비밀번호는 알파벳 소문자, 숫자로 6자리 이상 16자리 이하여야 합니다."); } } diff --git a/modules/domain/src/main/java/com/whoz_in/domain/member/exception/WrongPasswordException.java b/modules/domain/src/main/java/com/whoz_in/domain/member/exception/WrongPasswordException.java index 48cc17eb..975a92d6 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/member/exception/WrongPasswordException.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/member/exception/WrongPasswordException.java @@ -3,8 +3,8 @@ import com.whoz_in.domain.shared.BusinessException; public class WrongPasswordException extends BusinessException { - - public WrongPasswordException() { + public static final WrongPasswordException EXCEPTION = new WrongPasswordException(); + private WrongPasswordException() { super("2005", "틀린 비밀번호입니다."); } } diff --git a/modules/domain/src/main/java/com/whoz_in/domain/member/model/AuthCredentials.java b/modules/domain/src/main/java/com/whoz_in/domain/member/model/AuthCredentials.java index 34ea11ec..4768a3ef 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/member/model/AuthCredentials.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/member/model/AuthCredentials.java @@ -24,10 +24,10 @@ public final class AuthCredentials { public static AuthCredentials create(String loginId, String rawPassword, PasswordEncoder passwordEncoder){ //아이디가 정책에 맞는지 확인 if (!Pattern.matches(LOGIN_ID_REGEX, loginId)) - throw new LoginIdPolicyViolationException(); + throw LoginIdPolicyViolationException.EXCEPTION; //비밀번호가 정책에 맞는지 확인 if (!Pattern.matches(PASSWORD_REGEX, rawPassword)) - throw new PasswordPolicyViolationException(); + throw PasswordPolicyViolationException.EXCEPTION; return new AuthCredentials(loginId, passwordEncoder.encode(rawPassword)); } @@ -41,10 +41,10 @@ AuthCredentials changePassword(String rawOldPassword, String rawNewPassword, Pas String encodedOldPassword = passwordEncoder.encode(rawOldPassword); //기존 비밀번호가 같은지 확인 if (!encodedPassword.equals(encodedOldPassword)) - throw new WrongPasswordException(); + throw WrongPasswordException.EXCEPTION; //새로운 비밀번호가 정책에 맞는지 확인 if (!Pattern.matches(PASSWORD_REGEX, rawNewPassword)) - throw new PasswordPolicyViolationException(); + throw PasswordPolicyViolationException.EXCEPTION; return new AuthCredentials(this.loginId, passwordEncoder.encode(rawNewPassword)); } } diff --git a/modules/domain/src/main/java/com/whoz_in/domain/member/model/Member.java b/modules/domain/src/main/java/com/whoz_in/domain/member/model/Member.java index f74e433d..3e0ab938 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/member/model/Member.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/member/model/Member.java @@ -74,7 +74,7 @@ public static Member load(MemberId id, String name, Position mainPosition, int g public void changePassword(String rawOldPassword, String rawNewPassword, PasswordEncoder passwordEncoder){ if (authCredentials == null) - throw new NotAuthMemberException(); + throw NotAuthMemberException.EXCEPTION; this.authCredentials = this.authCredentials.changePassword(rawOldPassword, rawNewPassword, passwordEncoder); this.register(new MemberPasswordChanged(this.getId(), this.authCredentials.getEncodedPassword())); } diff --git a/modules/domain/src/main/java/com/whoz_in/domain/member/service/MemberFinderService.java b/modules/domain/src/main/java/com/whoz_in/domain/member/service/MemberFinderService.java index 430e79a6..02c757d8 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/member/service/MemberFinderService.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/member/service/MemberFinderService.java @@ -2,6 +2,7 @@ import com.whoz_in.domain.member.MemberRepository; import com.whoz_in.domain.member.exception.NoMemberException; +import com.whoz_in.domain.member.model.Member; import com.whoz_in.domain.member.model.MemberId; import com.whoz_in.domain.shared.DomainService; import lombok.RequiredArgsConstructor; @@ -10,8 +11,13 @@ @RequiredArgsConstructor public class MemberFinderService { private final MemberRepository memberRepository; + + public Member find(MemberId memberId){ + return memberRepository.findByMemberId(memberId).orElseThrow(()->NoMemberException.EXCEPTION); + } + public void mustExist(MemberId memberId) { if (!memberRepository.existsByMemberId(memberId)) - throw new NoMemberException(); + throw NoMemberException.EXCEPTION; } } diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceInfoAddHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceInfoAddHandler.java index e96bcd60..3b8b9ab1 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceInfoAddHandler.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceInfoAddHandler.java @@ -1,6 +1,8 @@ package com.whoz_in.main_api.command.device.application; import com.whoz_in.domain.device.DeviceRepository; +import com.whoz_in.domain.device.exception.DeviceAlreadyRegisteredException; +import com.whoz_in.domain.device.service.DeviceFinderService; import com.whoz_in.domain.device.service.DeviceOwnershipService; import com.whoz_in.domain.member.model.MemberId; import com.whoz_in.domain.member.service.MemberFinderService; @@ -18,12 +20,11 @@ @Handler @RequiredArgsConstructor -public class DeviceInfoAddHandler implements CommandHandler { +public class DeviceInfoAddHandler implements CommandHandler { private final RequesterInfo requesterInfo; private final TempDeviceInfoStore tempDeviceInfoStore; private final MemberFinderService memberFinderService; - private final DeviceOwnershipService deviceOwnershipService; - private final DeviceRepository deviceRepository; + private final DeviceFinderService deviceFinderService; //얘네 도메인에서의 입지가 애매해서 일단 Repository로 다뤘습니다. private final ManagedLogRepository managedLogRepository; private final MonitorLogRepository monitorLogRepository; @@ -31,33 +32,24 @@ public class DeviceInfoAddHandler implements CommandHandler //연결 시마다 맥이 바뀌는 기기가 다시 똑같은 와이파이에 등록하려고 하는 경우는 막지 못함 @Transactional @Override - public Void handle(DeviceInfoAdd req) { + public String handle(DeviceInfoAdd req) { MemberId requesterId = requesterInfo.getMemberId(); memberFinderService.mustExist(requesterId); //해당 룸에서 발생한 아이피로 ManagedLog를 찾으며, 오래된 맥일 경우 신뢰할 수 없으므로 무시한다. ManagedLog managedLog = managedLogRepository.getLatestByRoomAndIpAfter(req.room(), req.ip().toString(), LocalDateTime.now().minusDays(1)); - String mac = managedLog.getMac(); - - //등록할 DeviceInfo 생성 + //등록할 TempDeviceInfo 생성 TempDeviceInfo deviceInfo = new TempDeviceInfo(req.room(), managedLog.getSsid(), mac); - //이미 등록된 DeviceInfo가 아닌지 미리 확인 - tempDeviceInfoStore.mustNotExist(requesterId.id(), deviceInfo); - - //모니터 로그에서 현재 접속 중인 맥이 있는지 확인 (넉넉하게 15분) + //이미 등록된 TempDeviceInfo면 완료로 취급한다. (예외를 띄워야 할수도) + if (tempDeviceInfoStore.exists(requesterId.id(), deviceInfo)) return managedLog.getSsid(); + //모니터 로그에서 현재 접속 중인 맥이 있어야 한다. (넉넉하게 15분) monitorLogRepository.mustExistAfter(mac, LocalDateTime.now().minusMinutes(15)); - - //해당 맥으로 이미 등록된 기기가 있을경우 - deviceRepository.findByMac(mac).ifPresent(device -> { - deviceOwnershipService.validateOwnership(device, requesterId); // 회원에게 기기 삭제를 부탁하세요.라는 말을 해야 되는데.. - //자신의 것이면 - throw new IllegalArgumentException("이미 등록된 기기입니다."); - }); - + //해당 맥으로 이미 등록된 기기가 없어야 한다. + deviceFinderService.mustNotExistByMac(mac); //마침내! DeviceInfo를 추가한다. tempDeviceInfoStore.add(requesterId.id(), deviceInfo); - return null; + return managedLog.getSsid(); } } diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceRegisterHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceRegisterHandler.java index 11be398c..f9a49e2a 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceRegisterHandler.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/application/DeviceRegisterHandler.java @@ -4,6 +4,8 @@ import com.whoz_in.domain.device.model.Device; import com.whoz_in.domain.device.model.DeviceInfo; import com.whoz_in.domain.device.model.MacAddress; +import com.whoz_in.domain.device.service.DeviceFinderService; +import com.whoz_in.domain.device.service.DeviceOwnershipService; import com.whoz_in.domain.member.model.MemberId; import com.whoz_in.domain.member.service.MemberFinderService; import com.whoz_in.domain.shared.event.EventBus; @@ -28,6 +30,8 @@ public class DeviceRegisterHandler implements CommandHandler optionalDevice = cmd.getDeviceId().map(deviceRepository::getByDeviceId); + Optional optionalDevice = cmd.getDeviceId().map(deviceFinderService::find); + // 내꺼인지 검증 + optionalDevice.ifPresent(device -> deviceOwnershipService.validateIsMine(device, requesterId)); - // 등록된 Device가 있으면 등록된 SSID를 가져오고 없으면 빈 리스트 반환 + // 등록된 Device가 있으면 기존에 등록한 와이파이들을 가져옴. 없으면 빈 리스트 반환 List registeredSsids = optionalDevice.map(this::getRegisteredSsids).orElseGet(List::of); // 모든 와이파이에 대해 이미 등록되어있으면 리턴 if (registeredSsids.equals(ssidConfig.getSsids())) return null; - // TempDeviceInfo에 등록된 SSID 가져오기 + // TempDeviceInfo에 추가된 와이파이 가져오기 List addedSsids = getTempDeviceInfoSsids(requesterId); - // 추가되지 않은 SSID는 없어야 함 + // 추가되지 않은 와이파이가 있으면 예외 validateAllSsidsAdded(registeredSsids, addedSsids); // TempDeviceInfo로부터 DeviceInfo 생성 Set deviceInfos = createDeviceInfos(requesterId); - // Device를 생성 후 저장 (기존 Device가 없을 때만) + // 기존 Device 사용함. 없으면 생성함 Device device = optionalDevice .map(d->{ - d.registerDeviceInfo(deviceInfos);return d; + //기존 Device에 DeviceInfo 추가 + d.registerDeviceInfo(deviceInfos); + return d; }) .orElseGet(() -> Device.create(requesterId, deviceInfos, cmd.deviceName())); - deviceRepository.save(device); eventBus.publish(device.pullDomainEvents()); diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/presentation/DeviceController.java b/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/presentation/DeviceController.java index 97cdd6ac..6c071295 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/presentation/DeviceController.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/command/device/presentation/DeviceController.java @@ -22,9 +22,8 @@ public DeviceController(CommandBus commandBus) { } @PostMapping("/device/info") - public ResponseEntity> addDeviceInfo(@RequestBody DeviceInfoAdd request) { - dispatch(request); - return ResponseEntityGenerator.success("기기 정보 등록 완료", HttpStatus.CREATED); + public ResponseEntity> addDeviceInfo(@RequestBody DeviceInfoAdd request) { + return ResponseEntityGenerator.success(dispatch(request), "기기 정보 등록 완료", HttpStatus.CREATED); } @PostMapping("/device") diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/caching/device/TempDeviceInfoStore.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/caching/device/TempDeviceInfoStore.java index 8f054fe5..a757193a 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/caching/device/TempDeviceInfoStore.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/caching/device/TempDeviceInfoStore.java @@ -2,7 +2,6 @@ import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; -import com.whoz_in.main_api.config.RoomSsidConfig; import java.util.List; import java.util.UUID; import java.util.concurrent.CopyOnWriteArrayList; @@ -25,26 +24,11 @@ public final class TempDeviceInfoStore { .expireAfterAccess(5, TimeUnit.MINUTES) // 5분 동안 접근이 없으면 만료 .build(); - private final RoomSsidConfig ssidConfig; - //이전에 등록되지 않은 TempDeviceInfo인지 검증 - public void mustNotExist(UUID ownerId, TempDeviceInfo deviceInfo){ + public boolean exists(UUID ownerId, TempDeviceInfo deviceInfo){ List deviceInfos = store.getIfPresent(ownerId); - if (deviceInfos != null && deviceInfos.stream().anyMatch(di->di.equals(deviceInfo))) - throw new IllegalArgumentException("이미 등록됨"); - } - - //TODO: deviceInfo들에 room이 있는데 room을 굳이 받아야 하나 - //room의 모든 와이파이에 대해 CachedDevice가 추가되었는지 검증 - public void verifyAllAdded(UUID ownerId, String room){ - List deviceInfos = get(ownerId); - List unregisteredSsids = ssidConfig.getSsids(room).stream() - .filter(ssid -> deviceInfos.stream().noneMatch(di -> di.getSsid().equals(ssid))) - .toList(); - if (!unregisteredSsids.isEmpty()) { - throw new IllegalArgumentException("다음 wifi에 대해 맥을 등록하지 않았습니다. " + String.join(", ", unregisteredSsids)); - } + return (deviceInfos != null) && deviceInfos.stream().anyMatch(di->di.equals(deviceInfo)); } //DeviceInfo 추가 From f647469c78a5e70e9199f5ff8a10a7e97f95cc31 Mon Sep 17 00:00:00 2001 From: coco3x Date: Fri, 17 Jan 2025 21:00:40 +0900 Subject: [PATCH 137/138] =?UTF-8?q?feat(main-api):=20=EB=82=98=EC=9D=98=20?= =?UTF-8?q?=EA=B8=B0=EA=B8=B0=20=ED=98=84=ED=99=A9=20=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/whoz_in/domain/shared/Nullable.java | 1 + .../api_query_jpa/device/DeviceInfo.java | 2 + .../device/DeviceInfoJpaViewer.java | 21 ---------- .../api_query_jpa/device/DeviceJpaViewer.java | 40 +++++++++++++++++++ .../device/DeviceRepository.java | 9 +++++ .../device/DeviceEntityRepository.java | 2 +- .../security/SecurityFilterChainConfig.java | 1 + .../device/application/DevicesStatus.java | 19 +++++++++ .../device/application/DevicesStatusGet.java | 6 +++ .../application/DevicesStatusHandler.java | 23 +++++++++++ .../TempDeviceInfosStatusHandler.java | 6 +-- .../presentation/DeviceQueryController.java | 7 ++++ .../query/device/view/DeviceInfoViewer.java | 8 ---- .../query/device/view/DeviceViewer.java | 12 ++++++ 14 files changed, 124 insertions(+), 33 deletions(-) delete mode 100644 modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceInfoJpaViewer.java create mode 100644 modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceJpaViewer.java create mode 100644 modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceRepository.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/DevicesStatus.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/DevicesStatusGet.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/DevicesStatusHandler.java delete mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/view/DeviceInfoViewer.java create mode 100644 modules/main-api/src/main/java/com/whoz_in/main_api/query/device/view/DeviceViewer.java diff --git a/modules/domain/src/main/java/com/whoz_in/domain/shared/Nullable.java b/modules/domain/src/main/java/com/whoz_in/domain/shared/Nullable.java index f990e67a..15819630 100644 --- a/modules/domain/src/main/java/com/whoz_in/domain/shared/Nullable.java +++ b/modules/domain/src/main/java/com/whoz_in/domain/shared/Nullable.java @@ -1,4 +1,5 @@ package com.whoz_in.domain.shared; //null일 수 있는 값을 나타내는 마커 어노테이션 +//common으로 빼야 할듯 public @interface Nullable {} diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceInfo.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceInfo.java index 67583b8a..418ee361 100644 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceInfo.java +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceInfo.java @@ -1,5 +1,6 @@ package com.whoz_in.api_query_jpa.device; +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Id; import java.util.UUID; @@ -20,6 +21,7 @@ public class DeviceInfo { @Id private Long id; + @Column(name ="device_id", nullable = false) //TODO: 자동 스네이크 케이스 적용 private UUID deviceId; private String mac; diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceInfoJpaViewer.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceInfoJpaViewer.java deleted file mode 100644 index bc593da1..00000000 --- a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceInfoJpaViewer.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.whoz_in.api_query_jpa.device; - -import com.whoz_in.main_api.query.device.view.DeviceInfoViewer; -import com.whoz_in.main_api.query.device.view.RegisteredSsids; -import java.util.UUID; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; - - -@Component -@RequiredArgsConstructor -public class DeviceInfoJpaViewer implements DeviceInfoViewer { - private final DeviceInfoRepository deviceInfoRepository; - @Override - public RegisteredSsids findRegisteredSsids(UUID ownerId, String room, String mac) { - return new RegisteredSsids( - deviceInfoRepository.findAllByMac(ownerId, room, mac).stream() - .map(DeviceInfo::getSsid) - .toList()); - } -} diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceJpaViewer.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceJpaViewer.java new file mode 100644 index 00000000..21ab0bf0 --- /dev/null +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceJpaViewer.java @@ -0,0 +1,40 @@ +package com.whoz_in.api_query_jpa.device; + +import com.whoz_in.main_api.query.device.application.DevicesStatus; +import com.whoz_in.main_api.query.device.application.DevicesStatus.DeviceStatus; +import com.whoz_in.main_api.query.device.view.DeviceViewer; +import com.whoz_in.main_api.query.device.view.RegisteredSsids; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + + +@Component +@RequiredArgsConstructor +public class DeviceJpaViewer implements DeviceViewer { + private final DeviceRepository deviceRepository; + private final DeviceInfoRepository deviceInfoRepository; + @Override + public RegisteredSsids findRegisteredSsids(UUID ownerId, String room, String mac) { + return new RegisteredSsids( + deviceInfoRepository.findAllByMac(ownerId, room, mac).stream() + .map(DeviceInfo::getSsid) + .toList()); + } + + @Override + public DevicesStatus findDevicesStatus(UUID ownerId) { + List devicesStatus = deviceRepository.findAllByMemberId(ownerId) + .stream() + .map(device -> new DeviceStatus(device.getId(), device.getDeviceInfos() + .stream() + .collect(Collectors.toMap( + DeviceInfo::getSsid, + DeviceInfo::getMac)), + null))//TODO: connected된 ssid는 기기 현황 구현 후 리팩토링하면서 구현하기 + .toList(); + return new DevicesStatus(devicesStatus); + } +} diff --git a/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceRepository.java b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceRepository.java new file mode 100644 index 00000000..775bbbae --- /dev/null +++ b/modules/infrastructure/api-query-jpa/src/main/java/com/whoz_in/api_query_jpa/device/DeviceRepository.java @@ -0,0 +1,9 @@ +package com.whoz_in.api_query_jpa.device; + +import java.util.List; +import java.util.UUID; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface DeviceRepository extends JpaRepository { + List findAllByMemberId(UUID ownerId); +} diff --git a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceEntityRepository.java b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceEntityRepository.java index 8af73852..947da879 100644 --- a/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceEntityRepository.java +++ b/modules/infrastructure/domain-jpa/src/main/java/com/whoz_in/domain_jpa/device/DeviceEntityRepository.java @@ -12,5 +12,5 @@ public interface DeviceEntityRepository extends JpaRepository findByMac(@Param("mac") String mac); - Optional findById(UUID memberId); + Optional findById(UUID deviceId); } \ No newline at end of file diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java b/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java index 18313034..dd7c4e8d 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/config/security/SecurityFilterChainConfig.java @@ -95,6 +95,7 @@ public SecurityFilterChain authenticationFilterChain(HttpSecurity httpSecurity) //인증 필요 auth.requestMatchers(HttpMethod.GET, "/api/v1/device/info-status", + "/api/v1/devices", "/api/v1/private-ip", "/api/v1/ssid" ).authenticated(); diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/DevicesStatus.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/DevicesStatus.java new file mode 100644 index 00000000..15c1b4ac --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/DevicesStatus.java @@ -0,0 +1,19 @@ +package com.whoz_in.main_api.query.device.application; + +import com.whoz_in.domain.shared.Nullable; +import com.whoz_in.main_api.query.shared.application.Response; +import com.whoz_in.main_api.query.shared.application.View; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +public record DevicesStatus( + List devices +) implements Response, View { + public record DeviceStatus( + UUID deviceId, + Map macPerSsid, //Map + @Nullable String connectedSsid + ) {} +} + diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/DevicesStatusGet.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/DevicesStatusGet.java new file mode 100644 index 00000000..f539c7ef --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/DevicesStatusGet.java @@ -0,0 +1,6 @@ +package com.whoz_in.main_api.query.device.application; + +import com.whoz_in.main_api.query.shared.application.Query; + +public record DevicesStatusGet( +) implements Query {} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/DevicesStatusHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/DevicesStatusHandler.java new file mode 100644 index 00000000..4ce8fecf --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/DevicesStatusHandler.java @@ -0,0 +1,23 @@ +package com.whoz_in.main_api.query.device.application; + +import com.whoz_in.main_api.query.device.view.DeviceViewer; +import com.whoz_in.main_api.query.shared.application.QueryHandler; +import com.whoz_in.main_api.shared.application.Handler; +import com.whoz_in.main_api.shared.utils.RequesterInfo; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import org.springframework.transaction.annotation.Transactional; + +@Handler +@RequiredArgsConstructor +public class DevicesStatusHandler implements QueryHandler { + private final RequesterInfo requesterInfo; + private final DeviceViewer deviceViewer; + + @Transactional(readOnly = true) + @Override + public DevicesStatus handle(DevicesStatusGet query) { + UUID memberId = requesterInfo.getMemberId().id(); + return deviceViewer.findDevicesStatus(memberId); + } +} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/TempDeviceInfosStatusHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/TempDeviceInfosStatusHandler.java index 9047b59a..27db67f0 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/TempDeviceInfosStatusHandler.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/application/TempDeviceInfosStatusHandler.java @@ -3,7 +3,7 @@ import com.whoz_in.domain.network_log.ManagedLog; import com.whoz_in.domain.network_log.ManagedLogRepository; import com.whoz_in.main_api.config.RoomSsidConfig; -import com.whoz_in.main_api.query.device.view.DeviceInfoViewer; +import com.whoz_in.main_api.query.device.view.DeviceViewer; import com.whoz_in.main_api.query.shared.application.QueryHandler; import com.whoz_in.main_api.shared.application.Handler; import com.whoz_in.main_api.shared.caching.device.TempDeviceInfo; @@ -21,7 +21,7 @@ public class TempDeviceInfosStatusHandler implements QueryHandler { private final RoomSsidConfig ssidConfig; private final RequesterInfo requesterInfo; - private final DeviceInfoViewer deviceInfoViewer; + private final DeviceViewer deviceViewer; private final TempDeviceInfoStore tempDeviceInfoStore; private final ManagedLogRepository managedLogRepository; @@ -35,7 +35,7 @@ public TempDeviceInfosStatus handle(TempDeviceInfosStatusGet query) { // 방에 존재하는 와이파이들 List roomSsids = ssidConfig.getSsids(query.room()); // 사용자가 이전에 등록한 기기 정보를 가져옴 - List registeredSsids = deviceInfoViewer + List registeredSsids = deviceViewer .findRegisteredSsids(requesterId, query.room(), log.getMac()) .ssids(); // 임시로 등록한 기기 정보를 가져옴 diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/presentation/DeviceQueryController.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/presentation/DeviceQueryController.java index 927fa0f3..69565d06 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/presentation/DeviceQueryController.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/presentation/DeviceQueryController.java @@ -1,5 +1,7 @@ package com.whoz_in.main_api.query.device.presentation; +import com.whoz_in.main_api.query.device.application.DevicesStatus; +import com.whoz_in.main_api.query.device.application.DevicesStatusGet; import com.whoz_in.main_api.query.device.application.TempDeviceInfosStatus; import com.whoz_in.main_api.query.device.application.TempDeviceInfosStatusGet; import com.whoz_in.main_api.query.shared.application.QueryBus; @@ -21,6 +23,11 @@ public DeviceQueryController(QueryBus queryBus) { super(queryBus); } + @GetMapping("/devices") + public ResponseEntity> getDeviceStatus(){ + return ResponseEntityGenerator.success(ask(new DevicesStatusGet()), CrudResponseCode.READ); + } + @GetMapping("/device/info-status") public ResponseEntity> getTempDeviceInfosStatus(@RequestParam String room, @RequestParam String ip){ return ResponseEntityGenerator.success( diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/view/DeviceInfoViewer.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/view/DeviceInfoViewer.java deleted file mode 100644 index e3fc4eae..00000000 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/view/DeviceInfoViewer.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.whoz_in.main_api.query.device.view; - -import com.whoz_in.main_api.query.shared.application.Viewer; -import java.util.UUID; - -public interface DeviceInfoViewer extends Viewer { - RegisteredSsids findRegisteredSsids(UUID ownerId, String room, String mac); -} diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/view/DeviceViewer.java b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/view/DeviceViewer.java new file mode 100644 index 00000000..eee9284f --- /dev/null +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/query/device/view/DeviceViewer.java @@ -0,0 +1,12 @@ +package com.whoz_in.main_api.query.device.view; + +import com.whoz_in.main_api.query.device.application.DevicesStatus; +import com.whoz_in.main_api.query.shared.application.Viewer; +import java.util.UUID; + +public interface DeviceViewer extends Viewer { + //room과 mac을 기반으로 기기를 찾고 기기가 등록한 와이파이들을 반환 + RegisteredSsids findRegisteredSsids(UUID ownerId, String room, String mac); + //device들의 요약 정보를 반환 + DevicesStatus findDevicesStatus(UUID ownerId); +} From 7c77d1762740bfe3d5f925e3f89d31bdb5d07dca Mon Sep 17 00:00:00 2001 From: bellmin Date: Fri, 17 Jan 2025 22:10:36 +0900 Subject: [PATCH 138/138] =?UTF-8?q?fix(main-api):=20MainApiGlobalException?= =?UTF-8?q?Handler=EC=97=90=20@Slf4j=20=EC=96=B4=EB=85=B8=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shared/presentation/MainApiGlobalExceptionHandler.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/presentation/MainApiGlobalExceptionHandler.java b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/presentation/MainApiGlobalExceptionHandler.java index c1f01732..13dbb6cf 100644 --- a/modules/main-api/src/main/java/com/whoz_in/main_api/shared/presentation/MainApiGlobalExceptionHandler.java +++ b/modules/main-api/src/main/java/com/whoz_in/main_api/shared/presentation/MainApiGlobalExceptionHandler.java @@ -5,6 +5,7 @@ import jakarta.servlet.http.HttpServletRequest; import java.util.Objects; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; @@ -14,6 +15,7 @@ @RestControllerAdvice @RequiredArgsConstructor +@Slf4j public class MainApiGlobalExceptionHandler { //TODO: mapper @ExceptionHandler(ApplicationException.class)