Skip to content

Commit

Permalink
Merge pull request #94 from IoTeaTime/refactor/93-kan-152-domain-diff
Browse files Browse the repository at this point in the history
refactor: 도메인 변경으로 인한 CCTV 퇴출 코드 수정
  • Loading branch information
ywonchae1 authored Nov 6, 2024
2 parents 5e760a5 + ee0170d commit def5010
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@

@Tag(name = "CCTV Api", description = "CCTV 관련 API 목록입니다.")
public interface CctvApi {
@Operation(summary = "CCTV 삭제(퇴출)", description = "담당자: 양원채")
Api<?> delete(@LoginMember Long userId, @PathVariable Long cctvId);
@Operation(summary = "MASTER 회원이 CCTV 퇴출", description = "담당자: 양원채")
Api<?> out(@LoginMember Long userId, @PathVariable Long cctvId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
public class CctvController implements CctvApi {
private final CctvService cctvService;

@DeleteMapping("/{cctvId}")
public Api<?> delete(@LoginMember Long userId, @PathVariable("cctvId") Long cctvId) {
cctvService.deleteById(userId, cctvId);
@DeleteMapping("/{cctvId}/out")
public Api<?> out(@LoginMember Long userId, @PathVariable("cctvId") Long cctvId) {
cctvService.outById(userId, cctvId);
return Api.success(CctvSuccessType.DELETE_CCTV);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@

import java.util.Optional;
import org.ioteatime.meonghanyangserver.cctv.domain.CctvEntity;
import org.ioteatime.meonghanyangserver.cctv.dto.db.CctvWithDeviceId;

public interface CctvRepository {
boolean existsByKvsChannelName(String kvsChannelName);

void deleteById(Long cctvId);

Optional<CctvWithDeviceId> findByIdWithDeviceId(Long cctvId);

CctvEntity save(CctvEntity cctv);

Optional<CctvEntity> findById(Long cctvId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.ioteatime.meonghanyangserver.cctv.domain.CctvEntity;
import org.ioteatime.meonghanyangserver.cctv.dto.db.CctvWithDeviceId;
import org.springframework.stereotype.Repository;

@Repository
Expand All @@ -23,24 +22,12 @@ public void deleteById(Long cctvId) {
}

@Override
public Optional<CctvWithDeviceId> findByIdWithDeviceId(Long cctvId) {
// return Optional.ofNullable(
// jpaQueryFactory
// .select(
// Projections.constructor(
// CctvWithDeviceId.class,
// cctvEntity.id.as("cctvId"),
// cctvEntity.kvsChannelName.as("kvsChannelName"),
// cctvEntity.device.id.as("deviceId")))
// .from(cctvEntity)
// .join(cctvEntity.device, deviceEntity)
// .where(cctvEntity.id.eq(cctvId))
// .fetchOne());
return null;
public CctvEntity save(CctvEntity cctv) {
return jpaCctvRepository.save(cctv);
}

@Override
public CctvEntity save(CctvEntity cctv) {
return jpaCctvRepository.save(cctv);
public Optional<CctvEntity> findById(Long cctvId) {
return jpaCctvRepository.findById(cctvId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.ioteatime.meonghanyangserver.cctv.dto.db.CctvWithDeviceId;
import org.ioteatime.meonghanyangserver.cctv.domain.CctvEntity;
import org.ioteatime.meonghanyangserver.cctv.repository.CctvRepository;
import org.ioteatime.meonghanyangserver.clients.kvs.KvsClient;
import org.ioteatime.meonghanyangserver.common.exception.BadRequestException;
Expand All @@ -16,25 +16,21 @@
public class CctvService {
private final KvsClient kvsClient;
private final CctvRepository cctvRepository;
private final GroupMemberRepository deviceRepository;
private final GroupMemberRepository groupMemberRepository;

@Transactional
public void deleteById(Long userId, Long cctvId) {
// Device 테이블에서 userId를 조회하여 role 을 확인
if (deviceRepository.isParcitipantUserId(userId)) {
// PARTICIPANT 이면 CCTV 삭제 실패
public void outById(Long memberId, Long cctvId) {
// Master 권한을 가진 회원만 cctv 퇴출 가능
if (!groupMemberRepository.isMasterMember(memberId)) {
throw new BadRequestException(CctvErrorType.ONLY_MASTER_CAN_DELETE);
}
// MASTER 이거나, CCTV(자기자신)이면 CCTV 퇴출(나가기) 가능
CctvWithDeviceId cctv =
CctvEntity cctv =
cctvRepository
.findByIdWithDeviceId(cctvId)
.findById(cctvId)
.orElseThrow(() -> new NotFoundException(CctvErrorType.NOT_FOUND));
// 1. KVS 시그널링 채널 삭제
kvsClient.deleteSignalingChannel(cctv.kvsChannelName());
kvsClient.deleteSignalingChannel(cctv.getKvsChannelName());
// 2. CCTV 테이블에서 삭제
cctvRepository.deleteById(cctvId);
// 3. Device 테이블에서 삭제
deviceRepository.deleteById(cctv.deviceId());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ public class RedisConfig {
@Value("${spring.data.redis.password}")
private String password;

@Value("${spring.data.redis.port}")
private String port;

@Bean
public RedisConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration redisConfiguration = new RedisStandaloneConfiguration();
redisConfiguration.setHostName(host);
redisConfiguration.setPort(6379);
redisConfiguration.setPort(Integer.parseInt(port));
redisConfiguration.setPassword(password);
return new LettuceConnectionFactory(redisConfiguration);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,15 @@
import org.ioteatime.meonghanyangserver.groupmember.doamin.GroupMemberEntity;

public interface GroupMemberRepository {
GroupMemberEntity createGroupMember(GroupMemberEntity groupMemberEntity);
GroupMemberEntity save(GroupMemberEntity groupMemberEntity);

boolean existsGroupMember(Long memberId);

Optional<GroupMemberEntity> findByMemberId(Long memberId);

GroupEntity findGroupMember(Long memberId);

boolean isParcitipantUserId(Long userId);

void deleteById(Long id);

GroupMemberEntity save(GroupMemberEntity device);
boolean isMasterMember(Long memberId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import lombok.RequiredArgsConstructor;
import org.ioteatime.meonghanyangserver.group.domain.GroupEntity;
import org.ioteatime.meonghanyangserver.groupmember.doamin.GroupMemberEntity;
import org.ioteatime.meonghanyangserver.groupmember.doamin.enums.GroupMemberRole;
import org.springframework.stereotype.Repository;

@Repository
Expand All @@ -17,7 +18,7 @@ public class GroupMemberRepositoryImpl implements GroupMemberRepository {
private final JPAQueryFactory jpaQueryFactory;

@Override
public GroupMemberEntity createGroupMember(GroupMemberEntity groupMemberEntity) {
public GroupMemberEntity save(GroupMemberEntity groupMemberEntity) {
return jpaGroupMemberRepository.save(groupMemberEntity);
}

Expand All @@ -40,29 +41,23 @@ public GroupEntity findGroupMember(Long memberId) {
.fetchOne();
}

@Override
public boolean isParcitipantUserId(Long userId) {
// return !jpaQueryFactory
// .select(deviceEntity.role)
// .from(deviceEntity)
// .where(
// deviceEntity
// .member
// .id
// .eq(userId)
// .and(deviceEntity.role.eq(DeviceRole.ROLE_PARTICIPANT)))
// .fetch()
// .isEmpty();
return true;
}

@Override
public void deleteById(Long id) {
jpaGroupMemberRepository.deleteById(id);
}

@Override
public GroupMemberEntity save(GroupMemberEntity device) {
return jpaGroupMemberRepository.save(device);
public boolean isMasterMember(Long memberId) {
return !jpaQueryFactory
.select(groupMemberEntity.role)
.from(groupMemberEntity)
.where(
groupMemberEntity
.member
.id
.eq(memberId)
.and(groupMemberEntity.role.eq(GroupMemberRole.ROLE_MASTER)))
.fetch()
.isEmpty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public void createGroupMember(
String thingId) {
GroupMemberEntity groupMember =
GroupMemberEntityMapper.from(groupEntity, memberEntity, groupMemberRole, thingId);
groupMemberRepository.createGroupMember(groupMember);
groupMemberRepository.save(groupMember);
}

public boolean existsGroupMember(Long memberId) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,39 @@
package org.ioteatime.meonghanyangserver.cctv.controller;

import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.assertj.core.api.Assertions;
import org.ioteatime.meonghanyangserver.cctv.domain.CctvEntity;
import org.ioteatime.meonghanyangserver.cctv.repository.CctvRepository;
import org.ioteatime.meonghanyangserver.common.utils.JwtUtils;
import org.ioteatime.meonghanyangserver.config.ControllerTestConfig;
import org.ioteatime.meonghanyangserver.group.domain.GroupEntity;
import org.ioteatime.meonghanyangserver.group.repository.GroupRepository;
import org.ioteatime.meonghanyangserver.group.service.GroupService;
import org.ioteatime.meonghanyangserver.groupmember.doamin.GroupMemberEntity;
import org.ioteatime.meonghanyangserver.groupmember.doamin.enums.GroupMemberRole;
import org.ioteatime.meonghanyangserver.groupmember.repository.GroupMemberRepository;
import org.ioteatime.meonghanyangserver.member.domain.MemberEntity;
import org.ioteatime.meonghanyangserver.member.repository.MemberRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;

@SpringBootTest
class CctvControllerTest extends ControllerTestConfig {
@Autowired private JwtUtils jwtUtils;
@Autowired private MemberRepository memberRepository;
@Autowired private CctvRepository cctvRepository;
@Autowired private GroupRepository groupRepository;
@Autowired private GroupMemberRepository deviceRepository;
@Autowired private GroupMemberRepository groupMemberRepository;

@Autowired private GroupService groupService;

private String accessToken;
private MemberEntity member;
Expand All @@ -39,39 +52,41 @@ public void beforeEach() {

@Test
void CCTV를_삭제합니다() throws Exception {
// GroupEntity group = GroupEntity.builder().groupName("testgroup").build();
// groupRepository.save(group);
//
// DeviceEntity device2 =
// DeviceEntity.builder()
// .member(member)
// .group(group)
// .deviceUuid("test2")
// .role(DeviceRole.ROLE_CCTV)
// .build();
// device2 = deviceRepository.save(device2);
//
// String kvsChannelName = "delete-test-channel"; // KVS에 채널이 존재해야 함
// CctvEntity cctv =
// CctvEntity.builder()
// .cctvNickname("delcctv")
// .device(device2)
// .kvsChannelName(kvsChannelName)
// .build();
// cctvRepository.save(cctv);
//
// mockMvc.perform(
// delete("/api/cctv/{cctvId}", cctv.getId())
// .header(HttpHeaders.AUTHORIZATION, accessToken)
// .contentType(MediaType.APPLICATION_JSON))
// .andExpect(status().isOk())
// .andExpect(jsonPath("$.result.message").value("OK"))
// .andExpect(jsonPath("$.result.description").value("CCTV 삭제(퇴출)에
// 성공하였습니다."))
// .andDo(print());
//
// Assertions.assertThat(cctvRepository.existsByKvsChannelName(kvsChannelName))
// .isEqualTo(false);
// Assertions.assertThat(deviceRepository.findByDeviceId(device2.getId())).isEmpty();
GroupEntity group = GroupEntity.builder().groupName("testgroup").build();
groupRepository.save(group);

GroupMemberEntity groupMember =
GroupMemberEntity.builder()
.group(group)
.member(member)
.thingId("master-thing-id")
.role(GroupMemberRole.ROLE_MASTER)
.build();
groupMemberRepository.save(groupMember);

CctvEntity cctv =
CctvEntity.builder()
.group(group)
.cctvNickname("test")
.kvsChannelName("test-delete-channel") // KVS에 채널이 존재해야 함
.thingId("test-thing-id")
.build();

cctvRepository.save(cctv);

String kvsChannelName = cctv.getKvsChannelName(); // KVS에 채널이 존재해야 함

mockMvc.perform(
delete("/api/cctv/{cctvId}/out", cctv.getId())
.header(HttpHeaders.AUTHORIZATION, accessToken)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.result.message").value("OK"))
.andExpect(jsonPath("$.result.description").value("CCTV 삭제(퇴출)에 성공하였습니다."))
.andDo(print());

Assertions.assertThat(cctvRepository.existsByKvsChannelName(kvsChannelName))
.isEqualTo(false);
Assertions.assertThat(cctvRepository.findById(cctv.getId())).isEmpty();
}
}

0 comments on commit def5010

Please sign in to comment.