Skip to content

Commit

Permalink
Merge branch 'develop' into badge
Browse files Browse the repository at this point in the history
  • Loading branch information
westzeroright authored Jan 11, 2025
2 parents d237c3a + 6970765 commit d1fa838
Show file tree
Hide file tree
Showing 85 changed files with 1,081 additions and 603 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package com.whoz_in.domain.device;

import com.whoz_in.domain.device.model.Device;
import java.util.Optional;

public interface DeviceRepository {
void save(Device device);

//해당 mac을 포함하는 device를 찾는 메서드
Optional<Device> findByMac(String mac);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,30 @@
public final class Device extends AggregateRoot {
private final DeviceId id;
private final MemberId memberId; //양도 기능 생기면 final 제거
private String name;
private String deviceName;
private final List<DeviceInfo> deviceInfos;

public static Device create(MemberId memberId, List<DeviceInfo> deviceInfos, String name){
public boolean isOwnedBy(MemberId memberId){
return this.getMemberId().equals(memberId);
}

public static Device create(MemberId memberId, List<DeviceInfo> deviceInfos, String deviceName){
Device device = Device.builder()
.id(new DeviceId(UUID.randomUUID()))
.memberId(memberId)
.deviceInfos(deviceInfos)
.name(name)
.deviceName(deviceName)
.build();
device.register(new DeviceCreated());
return device;
}

public static Device load(DeviceId id, MemberId memberId, List<DeviceInfo> deviceInfos, String name){
public static Device load(DeviceId id, MemberId memberId, List<DeviceInfo> deviceInfos, String deviceName){
return Device.builder()
.id(id)
.memberId(memberId)
.deviceInfos(deviceInfos)
.name(name)
.deviceName(deviceName)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.whoz_in.domain.device.service;

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.shared.DomainService;
import lombok.RequiredArgsConstructor;

@DomainService
@RequiredArgsConstructor
public class DeviceOwnershipService {
private final MemberRepository memberRepository;

public void validateOwnership(Device device, MemberId memberId){
if (device.isOwnedBy(memberId)) return;
Member deviceOwner = memberRepository.getByMemberId(device.getMemberId());
throw new IllegalArgumentException("이 기기는 " + deviceOwner.getName() + " 회원의 기기입니다.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
public interface MemberRepository {
void save(Member member);
Optional<Member> findByLoginId(String loginId);
boolean existsBySocialProviderAndSocialId(SocialProvider socialProvider, String socialId);
boolean existsBySocialId(String socialId);
boolean existsByMemberId(MemberId memberId);
Optional<Member> findByMemberId(MemberId id);
List<Member> findByName(String name);
Optional<Member> findBySocialProviderAndSocialId(SocialProvider socialProvider, String socialId);
Optional<Member> findBySocialId(String socialId);
default Member getByLoginId(String loginId){
return findByLoginId(loginId).orElseThrow(NoMemberException::new);
}
Expand All @@ -26,8 +27,8 @@ default List<Member> getByName(String name){
default Member getByMemberId(MemberId id){
return findByMemberId(id).orElseThrow(NoMemberException::new);
}
default Member getBySocialProviderAndSocialId(SocialProvider socialProvider, String socialId){
return findBySocialProviderAndSocialId(socialProvider, socialId).orElseThrow(NoMemberException::new);
default Member getBySocialId(String socialId){
return findBySocialId(socialId).orElseThrow(NoMemberException::new);
}
void addBadge(MemberId memberId, BadgeId badgeId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public final class OAuthCredentials {
private final SocialProvider socialProvider;
private final String socialId;

public static OAuthCredentials load(SocialProvider socialProvider, String socialId){
public static OAuthCredentials create(SocialProvider socialProvider, String socialId){
if (socialProvider == null || socialId == null)
throw new IllegalStateException("no social provider or social id");
return new OAuthCredentials(socialProvider, socialId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,24 @@
@Getter
public enum Position {
AI("ai"),
AOS("aos"),
BE("be"),
DE("de"),
DE("de"), //디자이너
FE("fe"),
IOS("ios"),
PM("pm"),
GAME("game");

private String position;
private final String position;

Position(String position) {
this.position = position;
}

public static Position findPosition(String position){
public static Position findByName(String position){
return Arrays.stream(Position.values())
.filter(pos -> pos.getPosition().equals(position))
.findFirst()
.filter(pos -> pos.getPosition().equalsIgnoreCase(position))
.findAny()
.orElseThrow(() -> new IllegalArgumentException("no position"));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.whoz_in.domain.member.service;

import com.whoz_in.domain.member.MemberRepository;
import com.whoz_in.domain.member.exception.NoMemberException;
import com.whoz_in.domain.member.model.MemberId;
import com.whoz_in.domain.shared.DomainService;
import lombok.RequiredArgsConstructor;

@DomainService
@RequiredArgsConstructor
public class MemberFinderService {
private final MemberRepository memberRepository;
public void mustExist(MemberId memberId) {
if (!memberRepository.existsByMemberId(memberId))
throw new NoMemberException();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ public final class ManagedLog {
private final String ssid;
private final String room;
private final LocalDateTime createdAt;
private final LocalDateTime updatedAt;
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package com.whoz_in.domain.network_log;

import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Optional;

public interface ManagedLogRepository {
void save(ManagedLog log);
void saveAll(Collection<ManagedLog> logs);
Optional<ManagedLog> findLatestByIp(String ip);
Optional<ManagedLog> findLatestByRoomAndIpAfter(String room, String ip, LocalDateTime time);
default ManagedLog getLatestByRoomAndIpAfter(String room, String ip, LocalDateTime time){
return findLatestByRoomAndIpAfter(room, ip, time).orElseThrow(() -> new IllegalArgumentException("로그가 없습니다"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public MonitorLog(String mac, String room) {
this.updatedAt = null; //Repository 구현체에서 처리
}

//MonitorLog의 updateAt은 정확하지 않아도 되기 때문에 구현체에서 일괄로 처리합니다.
//따라서 이 생성자는 읽을 때만 쓰도록 합시다.
public MonitorLog(String mac, String room, LocalDateTime updatedAt) {
this.mac = mac;
this.room = room;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package com.whoz_in.domain.network_log;

import java.time.LocalDateTime;
import java.util.Collection;

public interface MonitorLogRepository {
void save(MonitorLog log);
void saveAll(Collection<MonitorLog> logs);
boolean existsAfter(String mac, LocalDateTime time);
default void mustExistAfter(String mac, LocalDateTime time){
if (!existsAfter(mac, time))
throw new IllegalArgumentException("monitor log가 없습니다");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Service
public @interface DomainService {
@AliasFor(annotation = Component.class)
@AliasFor(annotation = Service.class)
String value() default "";
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public DeviceEntity from(Device device) {
.mac(deviceInfo.getMac().toString())
.build())
.toList();
return new DeviceEntity(device.getId().id(), device.getMemberId().id(), device.getName(), deviceInfoEntities);
return new DeviceEntity(device.getId().id(), device.getMemberId().id(), device.getDeviceName(), deviceInfoEntities);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package com.whoz_in.domain_jpa.device;

import java.util.Optional;
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 DeviceEntityRepository extends JpaRepository<DeviceEntity, Long> {

@Query("SELECT d FROM DeviceEntity d JOIN d.deviceInfoEntity di WHERE di.mac = :mac")
Optional<DeviceEntity> findByMac(@Param("mac") String mac);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

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;

Expand All @@ -14,4 +16,9 @@ public class DeviceJpaRepository implements DeviceRepository {
public void save(Device device) {
repository.save(converter.from(device));
}

@Override
public Optional<Device> findByMac(String mac) {
return repository.findByMac(mac).map(converter::to);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public ManagedLogEntity from(ManagedLog log) {
public ManagedLog to(ManagedLogEntity entity) {
return new ManagedLog(
entity.getLogId().getMac(), entity.getLogId().getIp(),
entity.getSsid(), entity.getRoom(),
entity.getDeviceName(), entity.getCreatedAt());
entity.getDeviceName(), entity.getSsid(), entity.getRoom(),
entity.getCreatedAt(), entity.getUpdatedAt());
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.whoz_in.domain_jpa.managed;

import java.util.List;
import java.time.LocalDateTime;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
Expand All @@ -10,7 +10,8 @@
@Repository
public interface ManagedLogEntityRepository extends JpaRepository<ManagedLogEntity, String> {

@Query("SELECT m FROM ManagedLogEntity m WHERE m.logId.ip = :ip ORDER BY m.updatedAt DESC LIMIT 1")
Optional<ManagedLogEntity> findTopByIpOrderByUpdatedAtDesc(@Param("ip") String ip);
@Query("SELECT m FROM ManagedLogEntity m WHERE m.room = :room AND m.logId.ip = :ip AND m.updatedAt > :time ORDER BY m.updatedAt DESC")
Optional<ManagedLogEntity> findTopByRoomAndIpOrderByUpdatedAtDescAfter(
@Param("room") String room, @Param("ip") String ip, @Param("time") LocalDateTime time);

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.whoz_in.domain.network_log.ManagedLog;
import com.whoz_in.domain.network_log.ManagedLogRepository;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
Expand All @@ -24,34 +25,36 @@ public void save(ManagedLog log) {
repository.save(managedLogConverter.from(log));
}

@Override
public Optional<ManagedLog> findLatestByIp(String ip) {
return repository.findTopByIpOrderByUpdatedAtDesc(ip).map(managedLogConverter::to);
}

public void saveAll(Collection<ManagedLog> logs) {
if (logs.isEmpty()) return;

String sql = "INSERT INTO managed_log_entity " +
"(mac, created_at, updated_at, device_name, ip, ssid) " +
"VALUES (?, ?, ?, ?, ?, ?) " +
"(mac, created_at, updated_at, device_name, ip, ssid, room) " +
"VALUES (?, ?, ?, ?, ?, ?, ?) " +
"ON DUPLICATE KEY UPDATE updated_at = ?";

try {
jdbcTemplate.batchUpdate(sql, logs, logs.size(), (ps, log) -> {
Timestamp logTime = Timestamp.valueOf(log.getCreatedAt());
Timestamp createdAt = Timestamp.valueOf(log.getCreatedAt());
Timestamp updatedAt = Timestamp.valueOf(log.getUpdatedAt());
ps.setString(1, log.getMac());
ps.setTimestamp(2, logTime);
ps.setTimestamp(3, logTime);
ps.setTimestamp(2, createdAt);
ps.setTimestamp(3, updatedAt);
ps.setString(4, log.getDeviceName());
ps.setString(5, log.getIp());
ps.setString(6, log.getSsid());
ps.setTimestamp(7, logTime);
ps.setString(7, log.getRoom());
ps.setTimestamp(8, updatedAt);
});
} catch (DuplicateKeyException e) {
log.error("Duplicate key: " + e.getMessage());
} catch (Exception e) {
log.error("Unexpected error: " + e.getMessage());
}
}

@Override
public Optional<ManagedLog> findLatestByRoomAndIpAfter(String room, String ip, LocalDateTime time) {
return repository.findTopByRoomAndIpOrderByUpdatedAtDescAfter(room, ip, time).map(managedLogConverter::to);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.whoz_in.domain_jpa.member;

import com.whoz_in.domain.member.model.SocialProvider;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
Expand All @@ -10,6 +9,7 @@ public interface MemberEntityJpaRepository extends JpaRepository<MemberEntity, U
Optional<MemberEntity> findByLoginId(String loginId);
List<MemberEntity> findByName(String name);
Optional<MemberEntity> findById(UUID id);
boolean existsBySocialProviderAndSocialId(SocialProvider socialProvider, String socialId);
Optional<MemberEntity> findBySocialProviderAndSocialId(SocialProvider socialProvider, String socialId);
boolean existsBySocialId(String socialId);
boolean existsById(UUID id);
Optional<MemberEntity> findBySocialId(String socialId);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.whoz_in.domain_jpa.monitor;

import java.time.LocalDateTime;
import org.springframework.data.jpa.repository.JpaRepository;

public interface MonitorLogEntityRepository extends JpaRepository<MonitorLogEntity, String> {
boolean existsByMacAndUpdatedAtAfter(String mac, LocalDateTime time);
}
Loading

0 comments on commit d1fa838

Please sign in to comment.